2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 1999 - 2005, Anthony Minessale
5 * Anthony Minessale (anthmct@yahoo.com)
7 * See http://www.asterisk.org for more information about
8 * the Asterisk project. Please do not directly contact
9 * any of the maintainers of this project for assistance;
10 * the project provides a web site, mailing lists and IRC
11 * channels for your use.
13 * This program is free software, distributed under the terms of
14 * the GNU General Public License Version 2. See the LICENSE file
15 * at the top of the source tree.
20 * \brief RAW SLINEAR Format
21 * \arg File name extensions: sln, raw
27 ASTERISK_FILE_VERSION(__FILE__
, "$Revision$")
29 #include "asterisk/mod_format.h"
30 #include "asterisk/module.h"
31 #include "asterisk/endian.h"
33 #define BUF_SIZE 320 /* 320 bytes, 160 samples */
34 #define SLIN_SAMPLES 160
36 static struct ast_frame
*slinear_read(struct ast_filestream
*s
, int *whennext
)
39 /* Send a frame from the file to the appropriate channel */
41 s
->fr
.frametype
= AST_FRAME_VOICE
;
42 s
->fr
.subclass
= AST_FORMAT_SLINEAR
;
44 AST_FRAME_SET_BUFFER(&s
->fr
, s
->buf
, AST_FRIENDLY_OFFSET
, BUF_SIZE
);
45 if ((res
= fread(s
->fr
.data
.ptr
, 1, s
->fr
.datalen
, s
->f
)) < 1) {
47 ast_log(LOG_WARNING
, "Short read (%d) (%s)!\n", res
, strerror(errno
));
50 *whennext
= s
->fr
.samples
= res
/2;
55 static int slinear_write(struct ast_filestream
*fs
, struct ast_frame
*f
)
58 if (f
->frametype
!= AST_FRAME_VOICE
) {
59 ast_log(LOG_WARNING
, "Asked to write non-voice frame!\n");
62 if (f
->subclass
!= AST_FORMAT_SLINEAR
) {
63 ast_log(LOG_WARNING
, "Asked to write non-slinear frame (%d)!\n", f
->subclass
);
66 if ((res
= fwrite(f
->data
.ptr
, 1, f
->datalen
, fs
->f
)) != f
->datalen
) {
67 ast_log(LOG_WARNING
, "Bad write (%d/%d): %s\n", res
, f
->datalen
, strerror(errno
));
73 static int slinear_seek(struct ast_filestream
*fs
, off_t sample_offset
, int whence
)
75 off_t offset
=0,min
,cur
,max
;
80 fseeko(fs
->f
, 0, SEEK_END
);
82 if (whence
== SEEK_SET
)
83 offset
= sample_offset
;
84 else if (whence
== SEEK_CUR
|| whence
== SEEK_FORCECUR
)
85 offset
= sample_offset
+ cur
;
86 else if (whence
== SEEK_END
)
87 offset
= max
- sample_offset
;
88 if (whence
!= SEEK_FORCECUR
) {
89 offset
= (offset
> max
)?max
:offset
;
91 /* always protect against seeking past begining. */
92 offset
= (offset
< min
)?min
:offset
;
93 return fseeko(fs
->f
, offset
, SEEK_SET
);
96 static int slinear_trunc(struct ast_filestream
*fs
)
98 return ftruncate(fileno(fs
->f
), ftello(fs
->f
));
101 static off_t
slinear_tell(struct ast_filestream
*fs
)
103 return ftello(fs
->f
) / 2;
106 static const struct ast_format slin_f
= {
109 .format
= AST_FORMAT_SLINEAR
,
110 .write
= slinear_write
,
111 .seek
= slinear_seek
,
112 .trunc
= slinear_trunc
,
113 .tell
= slinear_tell
,
114 .read
= slinear_read
,
115 .buf_size
= BUF_SIZE
+ AST_FRIENDLY_OFFSET
,
118 static int load_module(void)
120 if (ast_format_register(&slin_f
))
121 return AST_MODULE_LOAD_FAILURE
;
122 return AST_MODULE_LOAD_SUCCESS
;
125 static int unload_module(void)
127 return ast_format_unregister(slin_f
.name
);
130 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY
, "Raw Signed Linear Audio support (SLN)");