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>
30 #include <machine/endian.h>
38 /* We can only read/write chunks of FRAME_TIME ms G.726 data */
39 #define FRAME_TIME 10 /* 10 ms size */
41 /* Frame sizes in bytes */
42 static int frame_size[4] = {
49 struct ast_filestream {
50 /* Do not place anything before "reserved" */
51 void *reserved[AST_RESERVED_POINTERS];
52 /* This is what a filestream means to us */
53 int fd; /* Open file descriptor */
54 int rate; /* RATE_* defines */
55 struct ast_frame fr; /* Frame information */
56 char waste[AST_FRIENDLY_OFFSET]; /* Buffer for sending frames, etc */
57 char empty; /* Empty character */
58 unsigned char g726[FRAME_TIME * 5]; /* G.726 encoded voice */
61 AST_MUTEX_DEFINE_STATIC(g726_lock);
62 static int glistcnt = 0;
64 static char *desc = "Raw G.726 (16/24/32/40kbps) data";
65 static char *name40 = "g726-40";
66 static char *name32 = "g726-32";
67 static char *name24 = "g726-24";
68 static char *name16 = "g726-16";
69 static char *exts40 = "g726-40";
70 static char *exts32 = "g726-32";
71 static char *exts24 = "g726-24";
72 static char *exts16 = "g726-16";
75 * Rate dependant format functions (open, rewrite)
77 static struct ast_filestream *g726_40_open(int fd)
79 /* We don't have any header to read or anything really, but
80 if we did, it would go here. We also might want to check
81 and be sure it's a valid file. */
82 struct ast_filestream *tmp;
83 if ((tmp = malloc(sizeof(struct ast_filestream)))) {
84 memset(tmp, 0, sizeof(struct ast_filestream));
85 if (ast_mutex_lock(&g726_lock)) {
86 ast_log(LOG_WARNING, "Unable to lock g726 list.\n");
92 tmp->fr.data = tmp->g726;
93 tmp->fr.frametype = AST_FRAME_VOICE;
94 tmp->fr.subclass = AST_FORMAT_G726;
95 /* datalen will vary for each frame */
100 ast_log(LOG_DEBUG, "Created filestream G.726-%dk.\n",
102 ast_mutex_unlock(&g726_lock);
103 ast_update_use_count();
108 static struct ast_filestream *g726_32_open(int fd)
110 /* We don't have any header to read or anything really, but
111 if we did, it would go here. We also might want to check
112 and be sure it's a valid file. */
113 struct ast_filestream *tmp;
114 if ((tmp = malloc(sizeof(struct ast_filestream)))) {
115 memset(tmp, 0, sizeof(struct ast_filestream));
116 if (ast_mutex_lock(&g726_lock)) {
117 ast_log(LOG_WARNING, "Unable to lock g726 list.\n");
123 tmp->fr.data = tmp->g726;
124 tmp->fr.frametype = AST_FRAME_VOICE;
125 tmp->fr.subclass = AST_FORMAT_G726;
126 /* datalen will vary for each frame */
127 tmp->fr.src = name32;
131 ast_log(LOG_DEBUG, "Created filestream G.726-%dk.\n",
133 ast_mutex_unlock(&g726_lock);
134 ast_update_use_count();
139 static struct ast_filestream *g726_24_open(int fd)
141 /* We don't have any header to read or anything really, but
142 if we did, it would go here. We also might want to check
143 and be sure it's a valid file. */
144 struct ast_filestream *tmp;
145 if ((tmp = malloc(sizeof(struct ast_filestream)))) {
146 memset(tmp, 0, sizeof(struct ast_filestream));
147 if (ast_mutex_lock(&g726_lock)) {
148 ast_log(LOG_WARNING, "Unable to lock g726 list.\n");
154 tmp->fr.data = tmp->g726;
155 tmp->fr.frametype = AST_FRAME_VOICE;
156 tmp->fr.subclass = AST_FORMAT_G726;
157 /* datalen will vary for each frame */
158 tmp->fr.src = name24;
162 ast_log(LOG_DEBUG, "Created filestream G.726-%dk.\n",
164 ast_mutex_unlock(&g726_lock);
165 ast_update_use_count();
170 static struct ast_filestream *g726_16_open(int fd)
172 /* We don't have any header to read or anything really, but
173 if we did, it would go here. We also might want to check
174 and be sure it's a valid file. */
175 struct ast_filestream *tmp;
176 if ((tmp = malloc(sizeof(struct ast_filestream)))) {
177 memset(tmp, 0, sizeof(struct ast_filestream));
178 if (ast_mutex_lock(&g726_lock)) {
179 ast_log(LOG_WARNING, "Unable to lock g726 list.\n");
185 tmp->fr.data = tmp->g726;
186 tmp->fr.frametype = AST_FRAME_VOICE;
187 tmp->fr.subclass = AST_FORMAT_G726;
188 /* datalen will vary for each frame */
189 tmp->fr.src = name16;
193 ast_log(LOG_DEBUG, "Created filestream G.726-%dk.\n",
195 ast_mutex_unlock(&g726_lock);
196 ast_update_use_count();
201 static struct ast_filestream *g726_40_rewrite(int fd, char *comment)
203 /* We don't have any header to read or anything really, but
204 if we did, it would go here. We also might want to check
205 and be sure it's a valid file. */
206 struct ast_filestream *tmp;
207 if ((tmp = malloc(sizeof(struct ast_filestream)))) {
208 memset(tmp, 0, sizeof(struct ast_filestream));
209 if (ast_mutex_lock(&g726_lock)) {
210 ast_log(LOG_WARNING, "Unable to lock g726 list.\n");
218 ast_log(LOG_DEBUG, "Created filestream G.726-%dk.\n",
220 ast_mutex_unlock(&g726_lock);
221 ast_update_use_count();
223 ast_log(LOG_WARNING, "Out of memory\n");
227 static struct ast_filestream *g726_32_rewrite(int fd, char *comment)
229 /* We don't have any header to read or anything really, but
230 if we did, it would go here. We also might want to check
231 and be sure it's a valid file. */
232 struct ast_filestream *tmp;
233 if ((tmp = malloc(sizeof(struct ast_filestream)))) {
234 memset(tmp, 0, sizeof(struct ast_filestream));
235 if (ast_mutex_lock(&g726_lock)) {
236 ast_log(LOG_WARNING, "Unable to lock g726 list.\n");
244 ast_log(LOG_DEBUG, "Created filestream G.726-%dk.\n",
246 ast_mutex_unlock(&g726_lock);
247 ast_update_use_count();
249 ast_log(LOG_WARNING, "Out of memory\n");
253 static struct ast_filestream *g726_24_rewrite(int fd, char *comment)
255 /* We don't have any header to read or anything really, but
256 if we did, it would go here. We also might want to check
257 and be sure it's a valid file. */
258 struct ast_filestream *tmp;
259 if ((tmp = malloc(sizeof(struct ast_filestream)))) {
260 memset(tmp, 0, sizeof(struct ast_filestream));
261 if (ast_mutex_lock(&g726_lock)) {
262 ast_log(LOG_WARNING, "Unable to lock g726 list.\n");
270 ast_log(LOG_DEBUG, "Created filestream G.726-%dk.\n",
272 ast_mutex_unlock(&g726_lock);
273 ast_update_use_count();
275 ast_log(LOG_WARNING, "Out of memory\n");
279 static struct ast_filestream *g726_16_rewrite(int fd, char *comment)
281 /* We don't have any header to read or anything really, but
282 if we did, it would go here. We also might want to check
283 and be sure it's a valid file. */
284 struct ast_filestream *tmp;
285 if ((tmp = malloc(sizeof(struct ast_filestream)))) {
286 memset(tmp, 0, sizeof(struct ast_filestream));
287 if (ast_mutex_lock(&g726_lock)) {
288 ast_log(LOG_WARNING, "Unable to lock g726 list.\n");
296 ast_log(LOG_DEBUG, "Created filestream G.726-%dk.\n",
298 ast_mutex_unlock(&g726_lock);
299 ast_update_use_count();
301 ast_log(LOG_WARNING, "Out of memory\n");
306 * Rate independent format functions (close, read, write)
308 static void g726_close(struct ast_filestream *s)
310 if (ast_mutex_lock(&g726_lock)) {
311 ast_log(LOG_WARNING, "Unable to lock g726 list.\n");
316 ast_log(LOG_DEBUG, "Closed filestream G.726-%dk.\n", 40 - s->rate * 8);
317 ast_mutex_unlock(&g726_lock);
318 ast_update_use_count();
324 static struct ast_frame *g726_read(struct ast_filestream *s, int *whennext)
327 /* Send a frame from the file to the appropriate channel */
328 s->fr.frametype = AST_FRAME_VOICE;
329 s->fr.subclass = AST_FORMAT_G726;
330 s->fr.offset = AST_FRIENDLY_OFFSET;
331 s->fr.samples = 8 * FRAME_TIME;
332 s->fr.datalen = frame_size[s->rate];
334 s->fr.data = s->g726;
335 if ((res = read(s->fd, s->g726, s->fr.datalen)) != s->fr.datalen) {
337 ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
340 *whennext = s->fr.samples;
344 static int g726_write(struct ast_filestream *fs, struct ast_frame *f)
347 if (f->frametype != AST_FRAME_VOICE) {
348 ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
351 if (f->subclass != AST_FORMAT_G726) {
352 ast_log(LOG_WARNING, "Asked to write non-G726 frame (%d)!\n",
356 if (f->datalen % frame_size[fs->rate]) {
357 ast_log(LOG_WARNING, "Invalid data length %d, should be multiple of %d\n",
358 f->datalen, frame_size[fs->rate]);
361 if ((res = write(fs->fd, f->data, f->datalen)) != f->datalen) {
362 ast_log(LOG_WARNING, "Bad write (%d/%d): %s\n",
363 res, frame_size[fs->rate], strerror(errno));
369 static char *g726_getcomment(struct ast_filestream *s)
374 static int g726_seek(struct ast_filestream *fs, long sample_offset, int whence)
379 static int g726_trunc(struct ast_filestream *fs)
384 static long g726_tell(struct ast_filestream *fs)
390 * Module interface (load_module, unload_module, usecount, description, key)
396 res = ast_format_register(name40, exts40, AST_FORMAT_G726,
407 ast_log(LOG_WARNING, "Failed to register format %s.\n", name40);
410 res = ast_format_register(name32, exts32, AST_FORMAT_G726,
421 ast_log(LOG_WARNING, "Failed to register format %s.\n", name32);
424 res = ast_format_register(name24, exts24, AST_FORMAT_G726,
435 ast_log(LOG_WARNING, "Failed to register format %s.\n", name24);
438 res = ast_format_register(name16, exts16, AST_FORMAT_G726,
449 ast_log(LOG_WARNING, "Failed to register format %s.\n", name16);
459 res = ast_format_unregister(name16);
461 ast_log(LOG_WARNING, "Failed to unregister format %s.\n", name16);
464 res = ast_format_unregister(name24);
466 ast_log(LOG_WARNING, "Failed to unregister format %s.\n", name24);
469 res = ast_format_unregister(name32);
471 ast_log(LOG_WARNING, "Failed to unregister format %s.\n", name32);
474 res = ast_format_unregister(name40);
476 ast_log(LOG_WARNING, "Failed to unregister format %s.\n", name40);
485 if (ast_mutex_lock(&g726_lock)) {
486 ast_log(LOG_WARNING, "Unable to lock g726 list.\n");
490 ast_mutex_unlock(&g726_lock);
501 return ASTERISK_GPL_KEY;