2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 1999 - 2005, Digium, Inc.
6 * Mark Spencer <markster@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.
22 * \brief Old-style G.723.1 frame/timestamp format.
24 * \arg Extensions: g723, g723sf
30 ASTERISK_FILE_VERSION(__FILE__
, "$Revision$")
32 #include "asterisk/mod_format.h"
33 #include "asterisk/module.h"
35 #define G723_MAX_SIZE 1024
37 static struct ast_frame
*g723_read(struct ast_filestream
*s
, int *whennext
)
42 /* Read the delay for the next packet, and schedule again if necessary */
43 /* XXX is this ignored ? */
44 if (fread(&delay
, 1, 4, s
->f
) == 4)
48 if (fread(&size
, 1, 2, s
->f
) != 2) {
49 /* Out of data, or the file is no longer valid. In any case
50 go ahead and stop the stream */
53 /* Looks like we have a frame to read from here */
55 if (size
> G723_MAX_SIZE
) {
56 ast_log(LOG_WARNING
, "Size %d is invalid\n", size
);
57 /* The file is apparently no longer any good, as we
58 shouldn't ever get frames even close to this
62 /* Read the data into the buffer */
63 s
->fr
.frametype
= AST_FRAME_VOICE
;
64 s
->fr
.subclass
= AST_FORMAT_G723_1
;
66 AST_FRAME_SET_BUFFER(&s
->fr
, s
->buf
, AST_FRIENDLY_OFFSET
, size
);
67 if ((res
= fread(s
->fr
.data
.ptr
, 1, s
->fr
.datalen
, s
->f
)) != size
) {
68 ast_log(LOG_WARNING
, "Short read (%d of %d bytes) (%s)!\n", res
, size
, strerror(errno
));
71 *whennext
= s
->fr
.samples
= 240;
75 static int g723_write(struct ast_filestream
*s
, struct ast_frame
*f
)
80 /* XXX there used to be a check s->fr means a read stream */
81 if (f
->frametype
!= AST_FRAME_VOICE
) {
82 ast_log(LOG_WARNING
, "Asked to write non-voice frame!\n");
85 if (f
->subclass
!= AST_FORMAT_G723_1
) {
86 ast_log(LOG_WARNING
, "Asked to write non-g723 frame!\n");
90 if (f
->datalen
<= 0) {
91 ast_log(LOG_WARNING
, "Short frame ignored (%d bytes long?)\n", f
->datalen
);
94 if ((res
= fwrite(&delay
, 1, 4, s
->f
)) != 4) {
95 ast_log(LOG_WARNING
, "Unable to write delay: res=%d (%s)\n", res
, strerror(errno
));
98 size
= htons(f
->datalen
);
99 if ((res
= fwrite(&size
, 1, 2, s
->f
)) != 2) {
100 ast_log(LOG_WARNING
, "Unable to write size: res=%d (%s)\n", res
, strerror(errno
));
103 if ((res
= fwrite(f
->data
.ptr
, 1, f
->datalen
, s
->f
)) != f
->datalen
) {
104 ast_log(LOG_WARNING
, "Unable to write frame: res=%d (%s)\n", res
, strerror(errno
));
110 static int g723_seek(struct ast_filestream
*fs
, off_t sample_offset
, int whence
)
115 static int g723_trunc(struct ast_filestream
*fs
)
117 /* Truncate file to current length */
118 if (ftruncate(fileno(fs
->f
), ftello(fs
->f
)) < 0)
123 static off_t
g723_tell(struct ast_filestream
*fs
)
128 static const struct ast_format g723_1_f
= {
130 .exts
= "g723|g723sf",
131 .format
= AST_FORMAT_G723_1
,
137 .buf_size
= G723_MAX_SIZE
+ AST_FRIENDLY_OFFSET
,
140 static int load_module(void)
142 if (ast_format_register(&g723_1_f
))
143 return AST_MODULE_LOAD_FAILURE
;
144 return AST_MODULE_LOAD_SUCCESS
;
147 static int unload_module(void)
149 return ast_format_unregister(g723_1_f
.name
);
152 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY
, "G.723.1 Simple Timestamp File Format");