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$")
30 #include <netinet/in.h>
31 #include <arpa/inet.h>
38 #include "asterisk/lock.h"
39 #include "asterisk/channel.h"
40 #include "asterisk/file.h"
41 #include "asterisk/logger.h"
42 #include "asterisk/sched.h"
43 #include "asterisk/module.h"
44 #include "asterisk/endian.h"
46 #define BUF_SIZE 320 /* 320 bytes, 160 samples */
47 #define SLIN_SAMPLES 160
49 static struct ast_frame
*slinear_read(struct ast_filestream
*s
, int *whennext
)
52 /* Send a frame from the file to the appropriate channel */
54 s
->fr
.frametype
= AST_FRAME_VOICE
;
55 s
->fr
.subclass
= AST_FORMAT_SLINEAR
;
57 AST_FRAME_SET_BUFFER(&s
->fr
, s
->buf
, AST_FRIENDLY_OFFSET
, BUF_SIZE
);
58 if ((res
= fread(s
->fr
.data
, 1, s
->fr
.datalen
, s
->f
)) < 1) {
60 ast_log(LOG_WARNING
, "Short read (%d) (%s)!\n", res
, strerror(errno
));
63 *whennext
= s
->fr
.samples
= res
/2;
68 static int slinear_write(struct ast_filestream
*fs
, struct ast_frame
*f
)
71 if (f
->frametype
!= AST_FRAME_VOICE
) {
72 ast_log(LOG_WARNING
, "Asked to write non-voice frame!\n");
75 if (f
->subclass
!= AST_FORMAT_SLINEAR
) {
76 ast_log(LOG_WARNING
, "Asked to write non-slinear frame (%d)!\n", f
->subclass
);
79 if ((res
= fwrite(f
->data
, 1, f
->datalen
, fs
->f
)) != f
->datalen
) {
80 ast_log(LOG_WARNING
, "Bad write (%d/%d): %s\n", res
, f
->datalen
, strerror(errno
));
86 static int slinear_seek(struct ast_filestream
*fs
, off_t sample_offset
, int whence
)
88 off_t offset
=0,min
,cur
,max
;
93 fseeko(fs
->f
, 0, SEEK_END
);
95 if (whence
== SEEK_SET
)
96 offset
= sample_offset
;
97 else if (whence
== SEEK_CUR
|| whence
== SEEK_FORCECUR
)
98 offset
= sample_offset
+ cur
;
99 else if (whence
== SEEK_END
)
100 offset
= max
- sample_offset
;
101 if (whence
!= SEEK_FORCECUR
) {
102 offset
= (offset
> max
)?max
:offset
;
104 /* always protect against seeking past begining. */
105 offset
= (offset
< min
)?min
:offset
;
106 return fseeko(fs
->f
, offset
, SEEK_SET
);
109 static int slinear_trunc(struct ast_filestream
*fs
)
111 return ftruncate(fileno(fs
->f
), ftello(fs
->f
));
114 static off_t
slinear_tell(struct ast_filestream
*fs
)
116 return ftello(fs
->f
) / 2;
119 static const struct ast_format slin_f
= {
122 .format
= AST_FORMAT_SLINEAR
,
123 .write
= slinear_write
,
124 .seek
= slinear_seek
,
125 .trunc
= slinear_trunc
,
126 .tell
= slinear_tell
,
127 .read
= slinear_read
,
128 .buf_size
= BUF_SIZE
+ AST_FRIENDLY_OFFSET
,
131 static int load_module(void)
133 return ast_format_register(&slin_f
);
136 static int unload_module(void)
138 return ast_format_unregister(slin_f
.name
);
141 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY
, "Raw Signed Linear Audio support (SLN)");