2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 1999 - 2008, Anthony Minessale and Digium, Inc.
5 * Anthony Minessale (anthmct@yahoo.com)
6 * Kevin P. Fleming <kpfleming@digium.com>
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
21 * \brief RAW SLINEAR 16 Format
22 * \arg File name extensions: sln16
28 ASTERISK_FILE_VERSION(__FILE__
, "$Revision$")
30 #include "asterisk/mod_format.h"
31 #include "asterisk/module.h"
32 #include "asterisk/endian.h"
34 #define BUF_SIZE 640 /* 640 bytes, 320 samples */
35 #define SLIN_SAMPLES 320
37 static struct ast_frame
*slinear_read(struct ast_filestream
*s
, int *whennext
)
40 /* Send a frame from the file to the appropriate channel */
42 s
->fr
.frametype
= AST_FRAME_VOICE
;
43 s
->fr
.subclass
= AST_FORMAT_SLINEAR16
;
45 AST_FRAME_SET_BUFFER(&s
->fr
, s
->buf
, AST_FRIENDLY_OFFSET
, BUF_SIZE
);
46 if ((res
= fread(s
->fr
.data
.ptr
, 1, s
->fr
.datalen
, s
->f
)) < 1) {
48 ast_log(LOG_WARNING
, "Short read (%d) (%s)!\n", res
, strerror(errno
));
51 *whennext
= s
->fr
.samples
= res
/2;
56 static int slinear_write(struct ast_filestream
*fs
, struct ast_frame
*f
)
60 if (f
->frametype
!= AST_FRAME_VOICE
) {
61 ast_log(LOG_WARNING
, "Asked to write non-voice frame!\n");
64 if (f
->subclass
!= AST_FORMAT_SLINEAR16
) {
65 ast_log(LOG_WARNING
, "Asked to write non-slinear16 frame (%d)!\n", f
->subclass
);
68 if ((res
= fwrite(f
->data
.ptr
, 1, f
->datalen
, fs
->f
)) != f
->datalen
) {
69 ast_log(LOG_WARNING
, "Bad write (%d/%d): %s\n", res
, f
->datalen
, strerror(errno
));
75 static int slinear_seek(struct ast_filestream
*fs
, off_t sample_offset
, int whence
)
77 off_t offset
= 0, min
= 0, cur
, max
;
83 fseeko(fs
->f
, 0, SEEK_END
);
87 if (whence
== SEEK_SET
)
88 offset
= sample_offset
;
89 else if (whence
== SEEK_CUR
|| whence
== SEEK_FORCECUR
)
90 offset
= sample_offset
+ cur
;
91 else if (whence
== SEEK_END
)
92 offset
= max
- sample_offset
;
94 if (whence
!= SEEK_FORCECUR
)
95 offset
= (offset
> max
) ? max
: offset
;
97 /* always protect against seeking past begining. */
98 offset
= (offset
< min
) ? min
: offset
;
100 return fseeko(fs
->f
, offset
, SEEK_SET
);
103 static int slinear_trunc(struct ast_filestream
*fs
)
105 return ftruncate(fileno(fs
->f
), ftello(fs
->f
));
108 static off_t
slinear_tell(struct ast_filestream
*fs
)
110 return ftello(fs
->f
) / 2;
113 static const struct ast_format slin_f
= {
116 .format
= AST_FORMAT_SLINEAR16
,
117 .write
= slinear_write
,
118 .seek
= slinear_seek
,
119 .trunc
= slinear_trunc
,
120 .tell
= slinear_tell
,
121 .read
= slinear_read
,
122 .buf_size
= BUF_SIZE
+ AST_FRIENDLY_OFFSET
,
125 static int load_module(void)
127 if (ast_format_register(&slin_f
))
128 return AST_MODULE_LOAD_FAILURE
;
130 return AST_MODULE_LOAD_SUCCESS
;
133 static int unload_module(void)
135 return ast_format_unregister(slin_f
.name
);
138 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY
, "Raw Signed Linear 16KHz Audio support (SLN16)");