Asterisk - The Open Source Telephony Project GIT-master-a358458
format_wav_gsm.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 1999 - 2005, Digium, Inc.
5 *
6 * Mark Spencer <markster@digium.com>
7 *
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.
13 *
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.
17 */
18
19/*! \file
20 *
21 * \brief Save GSM in the proprietary Microsoft format.
22 *
23 * Microsoft WAV format (Proprietary GSM)
24 * \arg File name extension: WAV,wav49 (Upper case WAV, lower case is another format)
25 * This format can be played on Windows systems, used for
26 * e-mail attachments mainly.
27 * \ingroup formats
28 */
29
30/*** MODULEINFO
31 <support_level>core</support_level>
32 ***/
33
34#include "asterisk.h"
35
36#include "asterisk/mod_format.h"
37#include "asterisk/module.h"
38#include "asterisk/endian.h"
40
41#include "msgsm.h"
42
43/* Some Ideas for this code came from makewave.c by Jeffrey Chilton */
44
45/* Portions of the conversion code are by guido@sienanet.it */
46
47#define GSM_FRAME_SIZE 33
48#define MSGSM_FRAME_SIZE 65
49#define MSGSM_DATA_OFFSET 60 /* offset of data bytes */
50#define GSM_SAMPLES 160 /* samples in a GSM block */
51#define MSGSM_SAMPLES (2*GSM_SAMPLES) /* samples in an MSGSM block */
52
53/* begin binary data: */
54static char msgsm_silence[] = /* 65 */
55{0x48,0x17,0xD6,0x84,0x02,0x80,0x24,0x49,0x92,0x24,0x89,0x02,0x80,0x24,0x49
56,0x92,0x24,0x89,0x02,0x80,0x24,0x49,0x92,0x24,0x89,0x02,0x80,0x24,0x49,0x92
57,0x24,0x09,0x82,0x74,0x61,0x4D,0x28,0x00,0x48,0x92,0x24,0x49,0x92,0x28,0x00
58,0x48,0x92,0x24,0x49,0x92,0x28,0x00,0x48,0x92,0x24,0x49,0x92,0x28,0x00,0x48
59,0x92,0x24,0x49,0x92,0x00};
60/* end binary data. size = 65 bytes */
61
62struct wavg_desc {
63 /* Believe it or not, we must decode/recode to account for the
64 weird MS format */
65 int secondhalf; /* Are we on the second half */
66};
67
68#if __BYTE_ORDER == __LITTLE_ENDIAN
69#define htoll(b) (b)
70#define htols(b) (b)
71#define ltohl(b) (b)
72#define ltohs(b) (b)
73#else
74#if __BYTE_ORDER == __BIG_ENDIAN
75#define htoll(b) \
76 (((((b) ) & 0xFF) << 24) | \
77 ((( (b) >> 8) & 0xFF) << 16) | \
78 ((( (b) >> 16) & 0xFF) << 8) | \
79 ((( (b) >> 24) & 0xFF) ))
80#define htols(b) \
81 (((((b) ) & 0xFF) << 8) | \
82 ((( (b) >> 8) & 0xFF) ))
83#define ltohl(b) htoll(b)
84#define ltohs(b) htols(b)
85#else
86#error "Endianess not defined"
87#endif
88#endif
89
90
91static int check_header(FILE *f)
92{
93 int type, size, formtype;
94 int fmt, hsize, fact;
95 short format, chans;
96 int freq;
97 int data;
98 if (fread(&type, 1, 4, f) != 4) {
99 ast_log(LOG_WARNING, "Read failed (type)\n");
100 return -1;
101 }
102 if (fread(&size, 1, 4, f) != 4) {
103 ast_log(LOG_WARNING, "Read failed (size)\n");
104 return -1;
105 }
106#if __BYTE_ORDER == __BIG_ENDIAN
107 size = ltohl(size);
108#endif
109 if (fread(&formtype, 1, 4, f) != 4) {
110 ast_log(LOG_WARNING, "Read failed (formtype)\n");
111 return -1;
112 }
113 if (memcmp(&type, "RIFF", 4)) {
114 ast_log(LOG_WARNING, "Does not begin with RIFF\n");
115 return -1;
116 }
117 if (memcmp(&formtype, "WAVE", 4)) {
118 ast_log(LOG_WARNING, "Does not contain WAVE\n");
119 return -1;
120 }
121 if (fread(&fmt, 1, 4, f) != 4) {
122 ast_log(LOG_WARNING, "Read failed (fmt)\n");
123 return -1;
124 }
125 if (memcmp(&fmt, "fmt ", 4)) {
126 ast_log(LOG_WARNING, "Does not say fmt\n");
127 return -1;
128 }
129 if (fread(&hsize, 1, 4, f) != 4) {
130 ast_log(LOG_WARNING, "Read failed (formtype)\n");
131 return -1;
132 }
133 if (ltohl(hsize) != 20) {
134 ast_log(LOG_WARNING, "Unexpected header size %d\n", ltohl(hsize));
135 return -1;
136 }
137 if (fread(&format, 1, 2, f) != 2) {
138 ast_log(LOG_WARNING, "Read failed (format)\n");
139 return -1;
140 }
141 if (ltohs(format) != 49) {
142 ast_log(LOG_WARNING, "Not a GSM file %d\n", ltohs(format));
143 return -1;
144 }
145 if (fread(&chans, 1, 2, f) != 2) {
146 ast_log(LOG_WARNING, "Read failed (format)\n");
147 return -1;
148 }
149 if (ltohs(chans) != 1) {
150 ast_log(LOG_WARNING, "Not in mono %d\n", ltohs(chans));
151 return -1;
152 }
153 if (fread(&freq, 1, 4, f) != 4) {
154 ast_log(LOG_WARNING, "Read failed (freq)\n");
155 return -1;
156 }
157 if (ltohl(freq) != DEFAULT_SAMPLE_RATE) {
158 ast_log(LOG_WARNING, "Unexpected frequency %d\n", ltohl(freq));
159 return -1;
160 }
161 /* Ignore the byte frequency */
162 if (fread(&freq, 1, 4, f) != 4) {
163 ast_log(LOG_WARNING, "Read failed (X_1)\n");
164 return -1;
165 }
166 /* Ignore the two weird fields */
167 if (fread(&freq, 1, 4, f) != 4) {
168 ast_log(LOG_WARNING, "Read failed (X_2/X_3)\n");
169 return -1;
170 }
171 /* Ignore the byte frequency */
172 if (fread(&freq, 1, 4, f) != 4) {
173 ast_log(LOG_WARNING, "Read failed (Y_1)\n");
174 return -1;
175 }
176 /* Check for the word fact */
177 if (fread(&fact, 1, 4, f) != 4) {
178 ast_log(LOG_WARNING, "Read failed (fact)\n");
179 return -1;
180 }
181 if (memcmp(&fact, "fact", 4)) {
182 ast_log(LOG_WARNING, "Does not say fact\n");
183 return -1;
184 }
185 /* Ignore the "fact value" */
186 if (fread(&fact, 1, 4, f) != 4) {
187 ast_log(LOG_WARNING, "Read failed (fact header)\n");
188 return -1;
189 }
190 if (fread(&fact, 1, 4, f) != 4) {
191 ast_log(LOG_WARNING, "Read failed (fact value)\n");
192 return -1;
193 }
194 /* Check for the word data */
195 if (fread(&data, 1, 4, f) != 4) {
196 ast_log(LOG_WARNING, "Read failed (data)\n");
197 return -1;
198 }
199 if (memcmp(&data, "data", 4)) {
200 ast_log(LOG_WARNING, "Does not say data\n");
201 return -1;
202 }
203 /* Ignore the data length */
204 if (fread(&data, 1, 4, f) != 4) {
205 ast_log(LOG_WARNING, "Read failed (data)\n");
206 return -1;
207 }
208 return 0;
209}
210
211static int update_header(FILE *f)
212{
213 off_t cur,end,bytes;
214 int datalen, filelen, samples;
215
216 cur = ftello(f);
217 fseek(f, 0, SEEK_END);
218 end = ftello(f);
219 /* in a gsm WAV, data starts 60 bytes in */
220 bytes = end - MSGSM_DATA_OFFSET;
221 samples = htoll(bytes / MSGSM_FRAME_SIZE * MSGSM_SAMPLES);
222 datalen = htoll(bytes);
223 filelen = htoll(MSGSM_DATA_OFFSET - 8 + bytes);
224 if (cur < 0) {
225 ast_log(LOG_WARNING, "Unable to find our position\n");
226 return -1;
227 }
228 if (fseek(f, 4, SEEK_SET)) {
229 ast_log(LOG_WARNING, "Unable to set our position\n");
230 return -1;
231 }
232 if (fwrite(&filelen, 1, 4, f) != 4) {
233 ast_log(LOG_WARNING, "Unable to write file size\n");
234 return -1;
235 }
236 if (fseek(f, 48, SEEK_SET)) {
237 ast_log(LOG_WARNING, "Unable to set our position\n");
238 return -1;
239 }
240 if (fwrite(&samples, 1, 4, f) != 4) {
241 ast_log(LOG_WARNING, "Unable to write samples\n");
242 return -1;
243 }
244 if (fseek(f, 56, SEEK_SET)) {
245 ast_log(LOG_WARNING, "Unable to set our position\n");
246 return -1;
247 }
248 if (fwrite(&datalen, 1, 4, f) != 4) {
249 ast_log(LOG_WARNING, "Unable to write datalen\n");
250 return -1;
251 }
252 if (fseeko(f, cur, SEEK_SET)) {
253 ast_log(LOG_WARNING, "Unable to return to position\n");
254 return -1;
255 }
256 return 0;
257}
258
259static int write_header(FILE *f)
260{
261 /* Samples per second (always 8000 for this format). */
262 unsigned int sample_rate = htoll(8000);
263 /* Bytes per second (always 1625 for this format). */
264 unsigned int byte_sample_rate = htoll(1625);
265 /* This is the size of the "fmt " subchunk */
266 unsigned int fmtsize = htoll(20);
267 /* WAV #49 */
268 unsigned short fmt = htols(49);
269 /* Mono = 1 channel */
270 unsigned short chans = htols(1);
271 /* Each block of data is exactly 65 bytes in size. */
272 unsigned int block_align = htoll(MSGSM_FRAME_SIZE);
273 /* Not actually 2, but rounded up to the nearest bit */
274 unsigned short bits_per_sample = htols(2);
275 /* Needed for compressed formats */
276 unsigned short extra_format = htols(MSGSM_SAMPLES);
277 /* This is the size of the "fact" subchunk */
278 unsigned int factsize = htoll(4);
279 /* Number of samples in the data chunk */
280 unsigned int num_samples = htoll(0);
281 /* Number of bytes in the data chunk */
282 unsigned int size = htoll(0);
283 /* Write a GSM header, ignoring sizes which will be filled in later */
284
285 /* 0: Chunk ID */
286 if (fwrite("RIFF", 1, 4, f) != 4) {
287 ast_log(LOG_WARNING, "Unable to write header\n");
288 return -1;
289 }
290 /* 4: Chunk Size */
291 if (fwrite(&size, 1, 4, f) != 4) {
292 ast_log(LOG_WARNING, "Unable to write header\n");
293 return -1;
294 }
295 /* 8: Chunk Format */
296 if (fwrite("WAVE", 1, 4, f) != 4) {
297 ast_log(LOG_WARNING, "Unable to write header\n");
298 return -1;
299 }
300 /* 12: Subchunk 1: ID */
301 if (fwrite("fmt ", 1, 4, f) != 4) {
302 ast_log(LOG_WARNING, "Unable to write header\n");
303 return -1;
304 }
305 /* 16: Subchunk 1: Size (minus 8) */
306 if (fwrite(&fmtsize, 1, 4, f) != 4) {
307 ast_log(LOG_WARNING, "Unable to write header\n");
308 return -1;
309 }
310 /* 20: Subchunk 1: Audio format (49) */
311 if (fwrite(&fmt, 1, 2, f) != 2) {
312 ast_log(LOG_WARNING, "Unable to write header\n");
313 return -1;
314 }
315 /* 22: Subchunk 1: Number of channels */
316 if (fwrite(&chans, 1, 2, f) != 2) {
317 ast_log(LOG_WARNING, "Unable to write header\n");
318 return -1;
319 }
320 /* 24: Subchunk 1: Sample rate */
321 if (fwrite(&sample_rate, 1, 4, f) != 4) {
322 ast_log(LOG_WARNING, "Unable to write header\n");
323 return -1;
324 }
325 /* 28: Subchunk 1: Byte rate */
326 if (fwrite(&byte_sample_rate, 1, 4, f) != 4) {
327 ast_log(LOG_WARNING, "Unable to write header\n");
328 return -1;
329 }
330 /* 32: Subchunk 1: Block align */
331 if (fwrite(&block_align, 1, 4, f) != 4) {
332 ast_log(LOG_WARNING, "Unable to write header\n");
333 return -1;
334 }
335 /* 36: Subchunk 1: Bits per sample */
336 if (fwrite(&bits_per_sample, 1, 2, f) != 2) {
337 ast_log(LOG_WARNING, "Unable to write header\n");
338 return -1;
339 }
340 /* 38: Subchunk 1: Extra format bytes */
341 if (fwrite(&extra_format, 1, 2, f) != 2) {
342 ast_log(LOG_WARNING, "Unable to write header\n");
343 return -1;
344 }
345 /* 40: Subchunk 2: ID */
346 if (fwrite("fact", 1, 4, f) != 4) {
347 ast_log(LOG_WARNING, "Unable to write header\n");
348 return -1;
349 }
350 /* 44: Subchunk 2: Size (minus 8) */
351 if (fwrite(&factsize, 1, 4, f) != 4) {
352 ast_log(LOG_WARNING, "Unable to write header\n");
353 return -1;
354 }
355 /* 48: Subchunk 2: Number of samples */
356 if (fwrite(&num_samples, 1, 4, f) != 4) {
357 ast_log(LOG_WARNING, "Unable to write header\n");
358 return -1;
359 }
360 /* 52: Subchunk 3: ID */
361 if (fwrite("data", 1, 4, f) != 4) {
362 ast_log(LOG_WARNING, "Unable to write header\n");
363 return -1;
364 }
365 /* 56: Subchunk 3: Size */
366 if (fwrite(&size, 1, 4, f) != 4) {
367 ast_log(LOG_WARNING, "Unable to write header\n");
368 return -1;
369 }
370 return 0;
371}
372
373static int wav_open(struct ast_filestream *s)
374{
375 /* We don't have any header to read or anything really, but
376 if we did, it would go here. We also might want to check
377 and be sure it's a valid file. */
378 struct wavg_desc *fs = (struct wavg_desc *)s->_private;
379
380 if (check_header(s->f))
381 return -1;
382 fs->secondhalf = 0; /* not strictly necessary */
383 return 0;
384}
385
386static int wav_rewrite(struct ast_filestream *s, const char *comment)
387{
388 /* We don't have any header to read or anything really, but
389 if we did, it would go here. We also might want to check
390 and be sure it's a valid file. */
391
392 if (write_header(s->f))
393 return -1;
394 return 0;
395}
396
397static void wav_close(struct ast_filestream *s)
398{
399 if (s->mode == O_RDONLY) {
400 return;
401 }
402
403 if (s->filename) {
404 update_header(s->f);
405 }
406}
407
408static struct ast_frame *wav_read(struct ast_filestream *s, int *whennext)
409{
410 /* Send a frame from the file to the appropriate channel */
411 struct wavg_desc *fs = (struct wavg_desc *)s->_private;
412
415 if (fs->secondhalf) {
416 /* Just return a frame based on the second GSM frame */
417 s->fr.data.ptr = (char *)s->fr.data.ptr + GSM_FRAME_SIZE;
419 } else {
420 /* read and convert */
421 unsigned char msdata[MSGSM_FRAME_SIZE];
422 size_t res;
423
424 if ((res = fread(msdata, 1, MSGSM_FRAME_SIZE, s->f)) != MSGSM_FRAME_SIZE) {
425 if (res && res != 1) {
426 ast_log(LOG_WARNING, "Short read of %s data (expected %d bytes, read %zu): %s\n",
428 strerror(errno));
429 }
430 return NULL;
431 }
432 /* Convert from MS format to two real GSM frames */
433 conv65(msdata, s->fr.data.ptr);
434 }
435 fs->secondhalf = !fs->secondhalf;
436 *whennext = GSM_SAMPLES;
437 return &s->fr;
438}
439
440static int wav_write(struct ast_filestream *s, struct ast_frame *f)
441{
442 int len;
443 int size;
444 struct wavg_desc *fs = (struct wavg_desc *)s->_private;
445
446 /* XXX this might fail... if the input is a multiple of MSGSM_FRAME_SIZE
447 * we assume it is already in the correct format.
448 */
449 if (!(f->datalen % MSGSM_FRAME_SIZE)) {
450 size = MSGSM_FRAME_SIZE;
451 fs->secondhalf = 0;
452 } else {
453 size = GSM_FRAME_SIZE;
454 }
455 for (len = 0; len < f->datalen ; len += size) {
456 int res;
457 unsigned char *src, msdata[MSGSM_FRAME_SIZE];
458 if (fs->secondhalf) { /* second half of raw gsm to be converted */
459 memcpy(s->buf + GSM_FRAME_SIZE, f->data.ptr + len, GSM_FRAME_SIZE);
460 conv66((unsigned char *) s->buf, msdata);
461 src = msdata;
462 fs->secondhalf = 0;
463 } else if (size == GSM_FRAME_SIZE) { /* first half of raw gsm */
464 memcpy(s->buf, f->data.ptr + len, GSM_FRAME_SIZE);
465 src = NULL; /* nothing to write */
466 fs->secondhalf = 1;
467 } else { /* raw msgsm data */
468 src = f->data.ptr + len;
469 }
470 if (src && (res = fwrite(src, 1, MSGSM_FRAME_SIZE, s->f)) != MSGSM_FRAME_SIZE) {
471 ast_log(LOG_WARNING, "Bad write (%d/65): %s\n", res, strerror(errno));
472 return -1;
473 }
474 }
475 return 0;
476}
477
478static int wav_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
479{
480 off_t offset = 0, min = MSGSM_DATA_OFFSET, distance, max, cur;
481 struct wavg_desc *s = (struct wavg_desc *)fs->_private;
482
483 if ((cur = ftello(fs->f)) < 0) {
484 ast_log(AST_LOG_WARNING, "Unable to determine current position in WAV filestream %p: %s\n", fs, strerror(errno));
485 return -1;
486 }
487
488 if (fseeko(fs->f, 0, SEEK_END) < 0) {
489 ast_log(AST_LOG_WARNING, "Unable to seek to end of WAV filestream %p: %s\n", fs, strerror(errno));
490 return -1;
491 }
492
493 /* XXX ideally, should round correctly */
494 if ((max = ftello(fs->f)) < 0) {
495 ast_log(AST_LOG_WARNING, "Unable to determine max position in WAV filestream %p: %s\n", fs, strerror(errno));
496 return -1;
497 }
498
499 /* Compute the distance in bytes, rounded to the block size */
500 distance = (sample_offset/MSGSM_SAMPLES) * MSGSM_FRAME_SIZE;
501 if (whence == SEEK_SET)
502 offset = distance + min;
503 else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
504 offset = distance + cur;
505 else if (whence == SEEK_END)
506 offset = max - distance;
507 /* always protect against seeking past end of header */
508 if (offset < min)
509 offset = min;
510 if (whence != SEEK_FORCECUR) {
511 if (offset > max)
512 offset = max;
513 } else if (offset > max) {
514 int i;
515 fseek(fs->f, 0, SEEK_END);
516 for (i=0; i< (offset - max) / MSGSM_FRAME_SIZE; i++) {
517 if (fwrite(msgsm_silence, 1, MSGSM_FRAME_SIZE, fs->f) != MSGSM_FRAME_SIZE) {
518 ast_log(LOG_WARNING, "fwrite() failed: %s\n", strerror(errno));
519 }
520 }
521 }
522 s->secondhalf = 0;
523 return fseeko(fs->f, offset, SEEK_SET);
524}
525
526static int wav_trunc(struct ast_filestream *fs)
527{
528 int fd;
529 off_t cur;
530
531 if ((fd = fileno(fs->f)) < 0) {
532 ast_log(AST_LOG_WARNING, "Unable to determine file descriptor for WAV filestream %p: %s\n", fs, strerror(errno));
533 return -1;
534 }
535 if ((cur = ftello(fs->f)) < 0) {
536 ast_log(AST_LOG_WARNING, "Unable to determine current position in WAV filestream %p: %s\n", fs, strerror(errno));
537 return -1;
538 }
539 /* Truncate file to current length */
540 if (ftruncate(fd, cur)) {
541 return -1;
542 }
543 return update_header(fs->f);
544}
545
546static off_t wav_tell(struct ast_filestream *fs)
547{
548 off_t offset;
549 offset = ftello(fs->f);
550 /* since this will most likely be used later in play or record, lets stick
551 * to that level of resolution, just even frames boundaries */
553}
554
555static struct ast_format_def wav49_f = {
556 .name = "wav49",
557 .exts = "WAV|wav49",
558 .open = wav_open,
559 .rewrite = wav_rewrite,
560 .write = wav_write,
561 .seek = wav_seek,
562 .trunc = wav_trunc,
563 .tell = wav_tell,
564 .read = wav_read,
565 .close = wav_close,
566 .buf_size = 2*GSM_FRAME_SIZE + AST_FRIENDLY_OFFSET,
567 .desc_size = sizeof(struct wavg_desc),
568};
569
570static int load_module(void)
571{
576}
577
578static int unload_module(void)
579{
581}
582
583AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Microsoft WAV format (Proprietary GSM)",
584 .support_level = AST_MODULE_SUPPORT_CORE,
585 .load = load_module,
586 .unload = unload_module,
587 .load_pri = AST_MODPRI_APP_DEPEND
#define comment
Definition: ael_lex.c:965
if(!yyg->yy_init)
Definition: ast_expr2f.c:854
Asterisk main include file. File version handling, generic pbx functions.
#define DEFAULT_SAMPLE_RATE
Definition: asterisk.h:48
static struct chans chans
#define ast_log
Definition: astobj2.c:42
static const char type[]
Definition: chan_ooh323.c:109
char * end
Definition: eagi_proxy.c:73
Asterisk architecture endianess compatibility definitions.
#define min(a, b)
Definition: f2c.h:197
#define max(a, b)
Definition: f2c.h:198
#define SEEK_FORCECUR
Definition: file.h:51
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
Media Format Cache API.
struct ast_format * ast_format_gsm
Built-in cached gsm format.
Definition: format_cache.c:96
static off_t wav_tell(struct ast_filestream *fs)
static struct ast_frame * wav_read(struct ast_filestream *s, int *whennext)
static int update_header(FILE *f)
#define MSGSM_FRAME_SIZE
static int write_header(FILE *f)
#define GSM_FRAME_SIZE
static char msgsm_silence[]
#define MSGSM_SAMPLES
static int check_header(FILE *f)
#define MSGSM_DATA_OFFSET
#define GSM_SAMPLES
static int wav_trunc(struct ast_filestream *fs)
static void wav_close(struct ast_filestream *s)
static int wav_rewrite(struct ast_filestream *s, const char *comment)
static int load_module(void)
static int wav_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
static int unload_module(void)
static int wav_open(struct ast_filestream *s)
static int wav_write(struct ast_filestream *s, struct ast_frame *f)
static struct ast_format_def wav49_f
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define AST_FRAME_SET_BUFFER(fr, _base, _ofs, _datalen)
#define AST_FRIENDLY_OFFSET
Offset into a frame's data buffer.
#define AST_LOG_WARNING
#define LOG_WARNING
int errno
Header for providers of file and format handling routines. Clients of these routines should include "...
int ast_format_def_unregister(const char *name)
Unregisters a file format.
Definition: file.c:162
#define ast_format_def_register(f)
Definition: mod_format.h:136
Asterisk module definitions.
@ AST_MODFLAG_LOAD_ORDER
Definition: module.h:317
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
Definition: module.h:543
@ AST_MODPRI_APP_DEPEND
Definition: module.h:328
@ AST_MODULE_SUPPORT_CORE
Definition: module.h:121
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
static void conv66(gsm_byte *d, wav_byte *c)
Definition: msgsm.h:116
static void conv65(wav_byte *c, gsm_byte *d)
Definition: msgsm.h:457
#define NULL
Definition: resample.c:96
This structure is allocated by file.c in one chunk, together with buf_size and desc_size bytes of mem...
Definition: mod_format.h:101
struct ast_frame fr
frame produced by read, typically
Definition: mod_format.h:122
void * _private
Definition: mod_format.h:124
char * filename
Definition: mod_format.h:107
Each supported file format is described by the following structure.
Definition: mod_format.h:43
char name[80]
Definition: mod_format.h:44
struct ast_format * format
Definition: mod_format.h:48
struct ast_format * format
Data structure associated with a single frame of data.
struct ast_frame_subclass subclass
union ast_frame::@226 data
Definition: astman.c:88