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$")
33 #include <netinet/in.h>
34 #include <arpa/inet.h>
41 #include "asterisk/lock.h"
42 #include "asterisk/channel.h"
43 #include "asterisk/file.h"
44 #include "asterisk/logger.h"
45 #include "asterisk/sched.h"
46 #include "asterisk/module.h"
48 #define G723_MAX_SIZE 1024
50 static struct ast_frame
*g723_read(struct ast_filestream
*s
, int *whennext
)
55 /* Read the delay for the next packet, and schedule again if necessary */
56 /* XXX is this ignored ? */
57 if (fread(&delay
, 1, 4, s
->f
) == 4)
61 if (fread(&size
, 1, 2, s
->f
) != 2) {
62 /* Out of data, or the file is no longer valid. In any case
63 go ahead and stop the stream */
66 /* Looks like we have a frame to read from here */
68 if (size
> G723_MAX_SIZE
) {
69 ast_log(LOG_WARNING
, "Size %d is invalid\n", size
);
70 /* The file is apparently no longer any good, as we
71 shouldn't ever get frames even close to this
75 /* Read the data into the buffer */
76 s
->fr
.frametype
= AST_FRAME_VOICE
;
77 s
->fr
.subclass
= AST_FORMAT_G723_1
;
79 AST_FRAME_SET_BUFFER(&s
->fr
, s
->buf
, AST_FRIENDLY_OFFSET
, size
);
80 if ((res
= fread(s
->fr
.data
, 1, s
->fr
.datalen
, s
->f
)) != size
) {
81 ast_log(LOG_WARNING
, "Short read (%d of %d bytes) (%s)!\n", res
, size
, strerror(errno
));
84 *whennext
= s
->fr
.samples
= 240;
88 static int g723_write(struct ast_filestream
*s
, struct ast_frame
*f
)
93 /* XXX there used to be a check s->fr means a read stream */
94 if (f
->frametype
!= AST_FRAME_VOICE
) {
95 ast_log(LOG_WARNING
, "Asked to write non-voice frame!\n");
98 if (f
->subclass
!= AST_FORMAT_G723_1
) {
99 ast_log(LOG_WARNING
, "Asked to write non-g723 frame!\n");
103 if (f
->datalen
<= 0) {
104 ast_log(LOG_WARNING
, "Short frame ignored (%d bytes long?)\n", f
->datalen
);
107 if ((res
= fwrite(&delay
, 1, 4, s
->f
)) != 4) {
108 ast_log(LOG_WARNING
, "Unable to write delay: res=%d (%s)\n", res
, strerror(errno
));
111 size
= htons(f
->datalen
);
112 if ((res
= fwrite(&size
, 1, 2, s
->f
)) != 2) {
113 ast_log(LOG_WARNING
, "Unable to write size: res=%d (%s)\n", res
, strerror(errno
));
116 if ((res
= fwrite(f
->data
, 1, f
->datalen
, s
->f
)) != f
->datalen
) {
117 ast_log(LOG_WARNING
, "Unable to write frame: res=%d (%s)\n", res
, strerror(errno
));
123 static int g723_seek(struct ast_filestream
*fs
, off_t sample_offset
, int whence
)
128 static int g723_trunc(struct ast_filestream
*fs
)
130 /* Truncate file to current length */
131 if (ftruncate(fileno(fs
->f
), ftello(fs
->f
)) < 0)
136 static off_t
g723_tell(struct ast_filestream
*fs
)
141 static const struct ast_format g723_1_f
= {
143 .exts
= "g723|g723sf",
144 .format
= AST_FORMAT_G723_1
,
150 .buf_size
= G723_MAX_SIZE
+ AST_FRIENDLY_OFFSET
,
153 static int load_module(void)
155 return ast_format_register(&g723_1_f
);
158 static int unload_module(void)
160 return ast_format_unregister(g723_1_f
.name
);
163 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY
, "G.723.1 Simple Timestamp File Format");