2 * Headerless G.726 (16/24/32/40kbps) data format for Asterisk.
4 * Copyright (c) 2004, inAccess Networks
6 * Michael Manousos <manousos@inaccessnetworks.com>
8 * This program is free software, distributed under the terms of
9 * the GNU General Public License
12 #include <asterisk/lock.h>
13 #include <asterisk/options.h>
14 #include <asterisk/channel.h>
15 #include <asterisk/file.h>
16 #include <asterisk/logger.h>
17 #include <asterisk/sched.h>
18 #include <asterisk/module.h>
19 #include <netinet/in.h>
20 #include <arpa/inet.h>
31 #include <machine/endian.h>
39 /* We can only read/write chunks of FRAME_TIME ms G.726 data */
40 #define FRAME_TIME 10 /* 10 ms size */
42 /* Frame sizes in bytes */
43 static int frame_size[4] = {
50 struct ast_filestream {
51 /* Do not place anything before "reserved" */
52 void *reserved[AST_RESERVED_POINTERS];
53 /* This is what a filestream means to us */
54 int fd; /* Open file descriptor */
55 int rate; /* RATE_* defines */
56 struct ast_frame fr; /* Frame information */
57 char waste[AST_FRIENDLY_OFFSET]; /* Buffer for sending frames, etc */
58 char empty; /* Empty character */
59 unsigned char g726[FRAME_TIME * 5]; /* G.726 encoded voice */
62 AST_MUTEX_DEFINE_STATIC(g726_lock);
63 static int glistcnt = 0;
65 static char *desc = "Raw G.726 (16/24/32/40kbps) data";
66 static char *name40 = "g726-40";
67 static char *name32 = "g726-32";
68 static char *name24 = "g726-24";
69 static char *name16 = "g726-16";
70 static char *exts40 = "g726-40";
71 static char *exts32 = "g726-32";
72 static char *exts24 = "g726-24";
73 static char *exts16 = "g726-16";
76 * Rate dependant format functions (open, rewrite)
78 static struct ast_filestream *g726_40_open(int fd)
80 /* We don't have any header to read or anything really, but
81 if we did, it would go here. We also might want to check
82 and be sure it's a valid file. */
83 struct ast_filestream *tmp;
84 if ((tmp = malloc(sizeof(struct ast_filestream)))) {
85 memset(tmp, 0, sizeof(struct ast_filestream));
86 if (ast_mutex_lock(&g726_lock)) {
87 ast_log(LOG_WARNING, "Unable to lock g726 list.\n");
93 tmp->fr.data = tmp->g726;
94 tmp->fr.frametype = AST_FRAME_VOICE;
95 tmp->fr.subclass = AST_FORMAT_G726;
96 /* datalen will vary for each frame */
101 ast_log(LOG_DEBUG, "Created filestream G.726-%dk.\n",
103 ast_mutex_unlock(&g726_lock);
104 ast_update_use_count();
109 static struct ast_filestream *g726_32_open(int fd)
111 /* We don't have any header to read or anything really, but
112 if we did, it would go here. We also might want to check
113 and be sure it's a valid file. */
114 struct ast_filestream *tmp;
115 if ((tmp = malloc(sizeof(struct ast_filestream)))) {
116 memset(tmp, 0, sizeof(struct ast_filestream));
117 if (ast_mutex_lock(&g726_lock)) {
118 ast_log(LOG_WARNING, "Unable to lock g726 list.\n");
124 tmp->fr.data = tmp->g726;
125 tmp->fr.frametype = AST_FRAME_VOICE;
126 tmp->fr.subclass = AST_FORMAT_G726;
127 /* datalen will vary for each frame */
128 tmp->fr.src = name32;
132 ast_log(LOG_DEBUG, "Created filestream G.726-%dk.\n",
134 ast_mutex_unlock(&g726_lock);
135 ast_update_use_count();
140 static struct ast_filestream *g726_24_open(int fd)
142 /* We don't have any header to read or anything really, but
143 if we did, it would go here. We also might want to check
144 and be sure it's a valid file. */
145 struct ast_filestream *tmp;
146 if ((tmp = malloc(sizeof(struct ast_filestream)))) {
147 memset(tmp, 0, sizeof(struct ast_filestream));
148 if (ast_mutex_lock(&g726_lock)) {
149 ast_log(LOG_WARNING, "Unable to lock g726 list.\n");
155 tmp->fr.data = tmp->g726;
156 tmp->fr.frametype = AST_FRAME_VOICE;
157 tmp->fr.subclass = AST_FORMAT_G726;
158 /* datalen will vary for each frame */
159 tmp->fr.src = name24;
163 ast_log(LOG_DEBUG, "Created filestream G.726-%dk.\n",
165 ast_mutex_unlock(&g726_lock);
166 ast_update_use_count();
171 static struct ast_filestream *g726_16_open(int fd)
173 /* We don't have any header to read or anything really, but
174 if we did, it would go here. We also might want to check
175 and be sure it's a valid file. */
176 struct ast_filestream *tmp;
177 if ((tmp = malloc(sizeof(struct ast_filestream)))) {
178 memset(tmp, 0, sizeof(struct ast_filestream));
179 if (ast_mutex_lock(&g726_lock)) {
180 ast_log(LOG_WARNING, "Unable to lock g726 list.\n");
186 tmp->fr.data = tmp->g726;
187 tmp->fr.frametype = AST_FRAME_VOICE;
188 tmp->fr.subclass = AST_FORMAT_G726;
189 /* datalen will vary for each frame */
190 tmp->fr.src = name16;
194 ast_log(LOG_DEBUG, "Created filestream G.726-%dk.\n",
196 ast_mutex_unlock(&g726_lock);
197 ast_update_use_count();
202 static struct ast_filestream *g726_40_rewrite(int fd, char *comment)
204 /* We don't have any header to read or anything really, but
205 if we did, it would go here. We also might want to check
206 and be sure it's a valid file. */
207 struct ast_filestream *tmp;
208 if ((tmp = malloc(sizeof(struct ast_filestream)))) {
209 memset(tmp, 0, sizeof(struct ast_filestream));
210 if (ast_mutex_lock(&g726_lock)) {
211 ast_log(LOG_WARNING, "Unable to lock g726 list.\n");
219 ast_log(LOG_DEBUG, "Created filestream G.726-%dk.\n",
221 ast_mutex_unlock(&g726_lock);
222 ast_update_use_count();
224 ast_log(LOG_WARNING, "Out of memory\n");
228 static struct ast_filestream *g726_32_rewrite(int fd, char *comment)
230 /* We don't have any header to read or anything really, but
231 if we did, it would go here. We also might want to check
232 and be sure it's a valid file. */
233 struct ast_filestream *tmp;
234 if ((tmp = malloc(sizeof(struct ast_filestream)))) {
235 memset(tmp, 0, sizeof(struct ast_filestream));
236 if (ast_mutex_lock(&g726_lock)) {
237 ast_log(LOG_WARNING, "Unable to lock g726 list.\n");
245 ast_log(LOG_DEBUG, "Created filestream G.726-%dk.\n",
247 ast_mutex_unlock(&g726_lock);
248 ast_update_use_count();
250 ast_log(LOG_WARNING, "Out of memory\n");
254 static struct ast_filestream *g726_24_rewrite(int fd, char *comment)
256 /* We don't have any header to read or anything really, but
257 if we did, it would go here. We also might want to check
258 and be sure it's a valid file. */
259 struct ast_filestream *tmp;
260 if ((tmp = malloc(sizeof(struct ast_filestream)))) {
261 memset(tmp, 0, sizeof(struct ast_filestream));
262 if (ast_mutex_lock(&g726_lock)) {
263 ast_log(LOG_WARNING, "Unable to lock g726 list.\n");
271 ast_log(LOG_DEBUG, "Created filestream G.726-%dk.\n",
273 ast_mutex_unlock(&g726_lock);
274 ast_update_use_count();
276 ast_log(LOG_WARNING, "Out of memory\n");
280 static struct ast_filestream *g726_16_rewrite(int fd, char *comment)
282 /* We don't have any header to read or anything really, but
283 if we did, it would go here. We also might want to check
284 and be sure it's a valid file. */
285 struct ast_filestream *tmp;
286 if ((tmp = malloc(sizeof(struct ast_filestream)))) {
287 memset(tmp, 0, sizeof(struct ast_filestream));
288 if (ast_mutex_lock(&g726_lock)) {
289 ast_log(LOG_WARNING, "Unable to lock g726 list.\n");
297 ast_log(LOG_DEBUG, "Created filestream G.726-%dk.\n",
299 ast_mutex_unlock(&g726_lock);
300 ast_update_use_count();
302 ast_log(LOG_WARNING, "Out of memory\n");
307 * Rate independent format functions (close, read, write)
309 static void g726_close(struct ast_filestream *s)
311 if (ast_mutex_lock(&g726_lock)) {
312 ast_log(LOG_WARNING, "Unable to lock g726 list.\n");
317 ast_log(LOG_DEBUG, "Closed filestream G.726-%dk.\n", 40 - s->rate * 8);
318 ast_mutex_unlock(&g726_lock);
319 ast_update_use_count();
325 static struct ast_frame *g726_read(struct ast_filestream *s, int *whennext)
328 /* Send a frame from the file to the appropriate channel */
329 s->fr.frametype = AST_FRAME_VOICE;
330 s->fr.subclass = AST_FORMAT_G726;
331 s->fr.offset = AST_FRIENDLY_OFFSET;
332 s->fr.samples = 8 * FRAME_TIME;
333 s->fr.datalen = frame_size[s->rate];
335 s->fr.data = s->g726;
336 if ((res = read(s->fd, s->g726, s->fr.datalen)) != s->fr.datalen) {
338 ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
341 *whennext = s->fr.samples;
345 static int g726_write(struct ast_filestream *fs, struct ast_frame *f)
348 if (f->frametype != AST_FRAME_VOICE) {
349 ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
352 if (f->subclass != AST_FORMAT_G726) {
353 ast_log(LOG_WARNING, "Asked to write non-G726 frame (%d)!\n",
357 if (f->datalen % frame_size[fs->rate]) {
358 ast_log(LOG_WARNING, "Invalid data length %d, should be multiple of %d\n",
359 f->datalen, frame_size[fs->rate]);
362 if ((res = write(fs->fd, f->data, f->datalen)) != f->datalen) {
363 ast_log(LOG_WARNING, "Bad write (%d/%d): %s\n",
364 res, frame_size[fs->rate], strerror(errno));
370 static char *g726_getcomment(struct ast_filestream *s)
375 static int g726_seek(struct ast_filestream *fs, long sample_offset, int whence)
380 static int g726_trunc(struct ast_filestream *fs)
385 static long g726_tell(struct ast_filestream *fs)
391 * Module interface (load_module, unload_module, usecount, description, key)
397 res = ast_format_register(name40, exts40, AST_FORMAT_G726,
408 ast_log(LOG_WARNING, "Failed to register format %s.\n", name40);
411 res = ast_format_register(name32, exts32, AST_FORMAT_G726,
422 ast_log(LOG_WARNING, "Failed to register format %s.\n", name32);
425 res = ast_format_register(name24, exts24, AST_FORMAT_G726,
436 ast_log(LOG_WARNING, "Failed to register format %s.\n", name24);
439 res = ast_format_register(name16, exts16, AST_FORMAT_G726,
450 ast_log(LOG_WARNING, "Failed to register format %s.\n", name16);
460 res = ast_format_unregister(name16);
462 ast_log(LOG_WARNING, "Failed to unregister format %s.\n", name16);
465 res = ast_format_unregister(name24);
467 ast_log(LOG_WARNING, "Failed to unregister format %s.\n", name24);
470 res = ast_format_unregister(name32);
472 ast_log(LOG_WARNING, "Failed to unregister format %s.\n", name32);
475 res = ast_format_unregister(name40);
477 ast_log(LOG_WARNING, "Failed to unregister format %s.\n", name40);
486 if (ast_mutex_lock(&g726_lock)) {
487 ast_log(LOG_WARNING, "Unable to lock g726 list.\n");
491 ast_mutex_unlock(&g726_lock);
502 return ASTERISK_GPL_KEY;