Asterisk - The Open Source Telephony Project GIT-master-67613d1
format_pcm.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 1999 - 2006, 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 Flat, binary, ulaw PCM file format.
22 * \arg File name extension: alaw, al, alw, pcm, ulaw, ul, mu, ulw, g722, au
23 *
24 * \ingroup formats
25 */
26
27/*** MODULEINFO
28 <support_level>core</support_level>
29 ***/
30
31#include "asterisk.h"
32
33#include "asterisk/mod_format.h"
34#include "asterisk/module.h"
35#include "asterisk/endian.h"
36#include "asterisk/ulaw.h"
37#include "asterisk/alaw.h"
39
40#define BUF_SIZE 160 /* 160 bytes, and same number of samples */
41
44
45/* #define REALTIME_WRITE */ /* XXX does it work at all ? */
46
47#ifdef REALTIME_WRITE
48struct pcm_desc {
49 unsigned long start_time;
50};
51
52/* Returns time in msec since system boot. */
53static unsigned long get_time(void)
54{
55 struct tms buf;
56 clock_t cur;
57
58 cur = times( &buf );
59 if( cur < 0 ) {
60 ast_log( LOG_WARNING, "Cannot get current time\n" );
61 return 0;
62 }
63 return cur * 1000 / sysconf( _SC_CLK_TCK );
64}
65
66static int pcma_open(struct ast_filestream *s)
67{
69 pd->starttime = get_time();
70 return 0;
71}
72
73static int pcma_rewrite(struct ast_filestream *s, const char *comment)
74{
75 return pcma_open(s);
76}
77#endif
78
79static struct ast_frame *pcm_read(struct ast_filestream *s, int *whennext)
80{
81 size_t res;
82
83 /* Send a frame from the file to the appropriate channel */
85 if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) < 1) {
86 if (res) {
87 ast_log(LOG_WARNING, "Short read of %s data (expected %d bytes, read %zu): %s\n",
89 strerror(errno));
90 }
91 return NULL;
92 }
93 s->fr.datalen = res;
94 *whennext = s->fr.samples = res;
95 return &s->fr;
96}
97
98static int pcm_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
99{
100 off_t cur, max, offset = 0;
101 int ret = -1; /* assume error */
102
103 if ((cur = ftello(fs->f)) < 0) {
104 ast_log(AST_LOG_WARNING, "Unable to determine current position in pcm filestream %p: %s\n", fs, strerror(errno));
105 return -1;
106 }
107
108 if (fseeko(fs->f, 0, SEEK_END) < 0) {
109 ast_log(AST_LOG_WARNING, "Unable to seek to end of pcm filestream %p: %s\n", fs, strerror(errno));
110 return -1;
111 }
112
113 if ((max = ftello(fs->f)) < 0) {
114 ast_log(AST_LOG_WARNING, "Unable to determine max position in pcm filestream %p: %s\n", fs, strerror(errno));
115 return -1;
116 }
117
118 switch (whence) {
119 case SEEK_SET:
120 offset = sample_offset;
121 break;
122 case SEEK_END:
123 offset = max - sample_offset;
124 break;
125 case SEEK_CUR:
126 case SEEK_FORCECUR:
127 offset = cur + sample_offset;
128 break;
129 default:
130 ast_log(LOG_WARNING, "invalid whence %d, assuming SEEK_SET\n", whence);
131 offset = sample_offset;
132 }
133 if (offset < 0) {
134 ast_log(LOG_WARNING, "negative offset %ld, resetting to 0\n", (long) offset);
135 offset = 0;
136 }
137 if (whence == SEEK_FORCECUR && offset > max) { /* extend the file */
138 size_t left = offset - max;
140
141 while (left) {
142 size_t written = fwrite(src, 1, MIN(left, BUF_SIZE), fs->f);
143 if (written < MIN(left, BUF_SIZE)) {
144 break; /* error */
145 }
146 left -= written;
147 }
148 ret = 0; /* successful */
149 } else {
150 if (offset > max) {
151 ast_log(LOG_WARNING, "offset too large %ld, truncating to %ld\n", (long) offset, (long) max);
152 offset = max;
153 }
154 ret = fseeko(fs->f, offset, SEEK_SET);
155 }
156 return ret;
157}
158
159static int pcm_trunc(struct ast_filestream *fs)
160{
161 int cur, fd;
162
163 if ((fd = fileno(fs->f)) < 0) {
164 ast_log(AST_LOG_WARNING, "Unable to determine file descriptor for pcm filestream %p: %s\n", fs, strerror(errno));
165 return -1;
166 }
167 if ((cur = ftello(fs->f)) < 0) {
168 ast_log(AST_LOG_WARNING, "Unable to determine current position in pcm filestream %p: %s\n", fs, strerror(errno));
169 return -1;
170 }
171 /* Truncate file to current length */
172 return ftruncate(fd, cur);
173}
174
175static off_t pcm_tell(struct ast_filestream *fs)
176{
177 return ftello(fs->f);
178}
179
180static int pcm_write(struct ast_filestream *fs, struct ast_frame *f)
181{
182 int res;
183
184#ifdef REALTIME_WRITE
186 struct pcm_desc *pd = (struct pcm_desc *)fs->_private;
187 struct stat stat_buf;
188 unsigned long cur_time = get_time();
189 unsigned long fpos = ( cur_time - pd->start_time ) * 8; /* 8 bytes per msec */
190 /* Check if we have written to this position yet. If we have, then increment pos by one frame
191 * for some degree of protection against receiving packets in the same clock tick.
192 */
193
194 fstat(fileno(fs->f), &stat_buf );
195 if (stat_buf.st_size > fpos )
196 fpos += f->datalen; /* Incrementing with the size of this current frame */
197
198 if (stat_buf.st_size < fpos) {
199 /* fill the gap with 0x55 rather than 0. */
200 char buf[1024];
201 unsigned long cur, to_write;
202
203 cur = stat_buf.st_size;
204 if (fseek(fs->f, cur, SEEK_SET) < 0) {
205 ast_log( LOG_WARNING, "Cannot seek in file: %s\n", strerror(errno) );
206 return -1;
207 }
208 memset(buf, 0x55, 512);
209 while (cur < fpos) {
210 to_write = fpos - cur;
211 if (to_write > sizeof(buf))
212 to_write = sizeof(buf);
213 if (fwrite(buf, 1, to_write, fs->f) != to_write) {
214 ast_log(LOG_ERROR, "Failed to write to file: %s\n", strerror(errno));
215 return -1;
216 }
217 cur += to_write;
218 }
219 }
220
221 if (fseek(s->f, fpos, SEEK_SET) < 0) {
222 ast_log( LOG_WARNING, "Cannot seek in file: %s\n", strerror(errno) );
223 return -1;
224 }
225 }
226#endif /* REALTIME_WRITE */
227
228 if ((res = fwrite(f->data.ptr, 1, f->datalen, fs->f)) != f->datalen) {
229 ast_log(LOG_WARNING, "Bad write (%d/%d): %s\n", res, f->datalen, strerror(errno));
230 return -1;
231 }
232 return 0;
233}
234
235/* SUN .au support routines */
236
237#define MIN_AU_HEADER_SIZE 24
238#define AU_HEADER(var) uint32_t var[6]
239
240#define AU_HDR_MAGIC_OFF 0
241#define AU_HDR_HDR_SIZE_OFF 1
242#define AU_HDR_DATA_SIZE_OFF 2
243#define AU_HDR_ENCODING_OFF 3
244#define AU_HDR_SAMPLE_RATE_OFF 4
245#define AU_HDR_CHANNELS_OFF 5
246
247#define AU_ENC_8BIT_ULAW 1
248
249#define AU_MAGIC 0x2e736e64
250#if __BYTE_ORDER == __BIG_ENDIAN
251#define htoll(b) (b)
252#define htols(b) (b)
253#define ltohl(b) (b)
254#define ltohs(b) (b)
255#else
256#if __BYTE_ORDER == __LITTLE_ENDIAN
257#define htoll(b) \
258 (((((b) ) & 0xFF) << 24) | \
259 ((((b) >> 8) & 0xFF) << 16) | \
260 ((((b) >> 16) & 0xFF) << 8) | \
261 ((((b) >> 24) & 0xFF) ))
262#define htols(b) \
263 (((((b) ) & 0xFF) << 8) | \
264 ((((b) >> 8) & 0xFF) ))
265#define ltohl(b) htoll(b)
266#define ltohs(b) htols(b)
267#else
268#error "Endianess not defined"
269#endif
270#endif
271
272struct au_desc {
273 uint32_t hdr_size;
274};
275
276static int check_header(struct ast_filestream *fs)
277{
279 uint32_t magic;
280 uint32_t hdr_size;
281 uint32_t data_size;
282 uint32_t encoding;
283 uint32_t sample_rate;
284 uint32_t channels;
285
286 struct au_desc *desc = fs->_private;
287 FILE *f = fs->f;
288
289 if (fread(header, 1, MIN_AU_HEADER_SIZE, f) != MIN_AU_HEADER_SIZE) {
290 ast_log(LOG_WARNING, "Read failed (header)\n");
291 return -1;
292 }
293 magic = ltohl(header[AU_HDR_MAGIC_OFF]);
294 if (magic != (uint32_t) AU_MAGIC) {
295 ast_log(LOG_WARNING, "Bad magic: 0x%x\n", magic);
296 }
300 }
301/* data_size = ltohl(header[AU_HDR_DATA_SIZE_OFF]); */
303 if (encoding != AU_ENC_8BIT_ULAW) {
304 ast_log(LOG_WARNING, "Unexpected format: %u. Only 8bit ULAW allowed (%d)\n", encoding, AU_ENC_8BIT_ULAW);
305 return -1;
306 }
307 sample_rate = ltohl(header[AU_HDR_SAMPLE_RATE_OFF]);
308 if (sample_rate != DEFAULT_SAMPLE_RATE) {
309 ast_log(LOG_WARNING, "Sample rate can only be 8000 not %u\n", sample_rate);
310 return -1;
311 }
313 if (channels != 1) {
314 ast_log(LOG_WARNING, "Not in mono: channels=%u\n", channels);
315 return -1;
316 }
317 /* Skip to data */
318 fseek(f, 0, SEEK_END);
319 data_size = ftell(f) - hdr_size;
320 if (fseek(f, hdr_size, SEEK_SET) == -1 ) {
321 ast_log(LOG_WARNING, "Failed to skip to data: %u\n", hdr_size);
322 return -1;
323 }
324
325 /* We'll need this later */
326 desc->hdr_size = hdr_size;
327
328 return data_size;
329}
330
331static int update_header(struct ast_filestream *fs)
332{
333 off_t cur, end;
334 uint32_t datalen;
335 int bytes;
336 struct au_desc *desc = fs->_private;
337 FILE *f = fs->f;
338
339 cur = ftell(f);
340 fseek(f, 0, SEEK_END);
341 end = ftell(f);
342 /* data starts 24 bytes in */
343 bytes = end - desc->hdr_size;
344 datalen = htoll(bytes);
345
346 if (cur < 0) {
347 ast_log(LOG_WARNING, "Unable to find our position\n");
348 return -1;
349 }
350 if (fseek(f, AU_HDR_DATA_SIZE_OFF * sizeof(uint32_t), SEEK_SET)) {
351 ast_log(LOG_WARNING, "Unable to set our position\n");
352 return -1;
353 }
354 if (fwrite(&datalen, 1, sizeof(datalen), f) != sizeof(datalen)) {
355 ast_log(LOG_WARNING, "Unable to set write file size\n");
356 return -1;
357 }
358 if (fseek(f, cur, SEEK_SET)) {
359 ast_log(LOG_WARNING, "Unable to return to position\n");
360 return -1;
361 }
362 return 0;
363}
364
365static int write_header(struct ast_filestream *fs)
366{
367 struct au_desc *desc = fs->_private;
368 FILE *f = fs->f;
369
371
372 header[AU_HDR_MAGIC_OFF] = htoll((uint32_t) AU_MAGIC);
373 header[AU_HDR_HDR_SIZE_OFF] = htoll(desc->hdr_size);
377 header[AU_HDR_CHANNELS_OFF] = htoll(1);
378
379 /* Write an au header, ignoring sizes which will be filled in later */
380 fseek(f, 0, SEEK_SET);
381 if (fwrite(header, 1, MIN_AU_HEADER_SIZE, f) != MIN_AU_HEADER_SIZE) {
382 ast_log(LOG_WARNING, "Unable to write header\n");
383 return -1;
384 }
385 return 0;
386}
387
388static int au_open(struct ast_filestream *s)
389{
390 if (check_header(s) < 0)
391 return -1;
392 return 0;
393}
394
395static int au_rewrite(struct ast_filestream *s, const char *comment)
396{
397 struct au_desc *desc = s->_private;
398
399 desc->hdr_size = MIN_AU_HEADER_SIZE;
400
401 if (write_header(s))
402 return -1;
403 return 0;
404}
405
406/* XXX check this, probably incorrect */
407static int au_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
408{
409 off_t min, max, cur;
410 long offset = 0;
411 struct au_desc *desc = fs->_private;
412
413 min = desc->hdr_size;
414
415 if ((cur = ftello(fs->f)) < 0) {
416 ast_log(AST_LOG_WARNING, "Unable to determine current position in au filestream %p: %s\n", fs, strerror(errno));
417 return -1;
418 }
419
420 if (fseeko(fs->f, 0, SEEK_END) < 0) {
421 ast_log(AST_LOG_WARNING, "Unable to seek to end of au filestream %p: %s\n", fs, strerror(errno));
422 return -1;
423 }
424
425 if ((max = ftello(fs->f)) < 0) {
426 ast_log(AST_LOG_WARNING, "Unable to determine max position in au filestream %p: %s\n", fs, strerror(errno));
427 return -1;
428 }
429
430 if (whence == SEEK_SET)
431 offset = sample_offset + min;
432 else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
433 offset = sample_offset + cur;
434 else if (whence == SEEK_END)
435 offset = max - sample_offset;
436
437 if (whence != SEEK_FORCECUR) {
438 offset = (offset > max) ? max : offset;
439 }
440
441 /* always protect the header space. */
442 offset = (offset < min) ? min : offset;
443
444 return fseeko(fs->f, offset, SEEK_SET);
445}
446
447static int au_trunc(struct ast_filestream *fs)
448{
449 int fd;
450 off_t cur;
451
452 if ((fd = fileno(fs->f)) < 0) {
453 ast_log(AST_LOG_WARNING, "Unable to determine file descriptor for au filestream %p: %s\n", fs, strerror(errno));
454 return -1;
455 }
456 if ((cur = ftello(fs->f)) < 0) {
457 ast_log(AST_LOG_WARNING, "Unable to determine current position in au filestream %p: %s\n", fs, strerror(errno));
458 return -1;
459 }
460 /* Truncate file to current length */
461 if (ftruncate(fd, cur)) {
462 return -1;
463 }
464 return update_header(fs);
465}
466
467static off_t au_tell(struct ast_filestream *fs)
468{
469 struct au_desc *desc = fs->_private;
470 off_t offset = ftello(fs->f);
471 return offset - desc->hdr_size;
472}
473
474static struct ast_frame *g722_read(struct ast_filestream *s, int *whennext)
475{
476 struct ast_frame *f = pcm_read(s, whennext);
477 *whennext = s->fr.samples = (*whennext * 2);
478 return f;
479}
480
481static int g722_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
482{
483 return pcm_seek(fs, sample_offset / 2, whence);
484}
485
486static off_t g722_tell(struct ast_filestream *fs)
487{
488 return pcm_tell(fs) * 2;
489}
490
491static struct ast_format_def alaw_f = {
492 .name = "alaw",
493 .exts = "alaw|al|alw",
494 .write = pcm_write,
495 .seek = pcm_seek,
496 .trunc = pcm_trunc,
497 .tell = pcm_tell,
498 .read = pcm_read,
499 .buf_size = BUF_SIZE + AST_FRIENDLY_OFFSET,
500#ifdef REALTIME_WRITE
501 .open = pcma_open,
502 .rewrite = pcma_rewrite,
503 .desc_size = sizeof(struct pcm_desc),
504#endif
505};
506
507static struct ast_format_def pcm_f = {
508 .name = "pcm",
509 .exts = "pcm|ulaw|ul|mu|ulw",
510 .mime_types = "audio/basic",
511 .write = pcm_write,
512 .seek = pcm_seek,
513 .trunc = pcm_trunc,
514 .tell = pcm_tell,
515 .read = pcm_read,
516 .buf_size = BUF_SIZE + AST_FRIENDLY_OFFSET,
517};
518
519static struct ast_format_def g722_f = {
520 .name = "g722",
521 .exts = "g722",
522 .write = pcm_write,
523 .seek = g722_seek,
524 .trunc = pcm_trunc,
525 .tell = g722_tell,
526 .read = g722_read,
527 .buf_size = (BUF_SIZE * 2) + AST_FRIENDLY_OFFSET,
528};
529
530static struct ast_format_def au_f = {
531 .name = "au",
532 .exts = "au",
533 .open = au_open,
534 .rewrite = au_rewrite,
535 .write = pcm_write,
536 .seek = au_seek,
537 .trunc = au_trunc,
538 .tell = au_tell,
539 .read = pcm_read,
540 .buf_size = BUF_SIZE + AST_FRIENDLY_OFFSET, /* this many shorts */
541 .desc_size = sizeof(struct au_desc),
542};
543
544static int unload_module(void)
545{
550}
551
552static int load_module(void)
553{
554 int i;
555
556 /* XXX better init ? */
557 for (i = 0; i < ARRAY_LEN(ulaw_silence); i++)
558 ulaw_silence[i] = AST_LIN2MU(0);
559 for (i = 0; i < ARRAY_LEN(alaw_silence); i++)
560 alaw_silence[i] = AST_LIN2A(0);
561
572 }
574}
575
576AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Raw/Sun uLaw/ALaw 8KHz (PCM,PCMA,AU), G.722 16Khz",
577 .support_level = AST_MODULE_SUPPORT_CORE,
578 .load = load_module,
579 .unload = unload_module,
580 .load_pri = AST_MODPRI_APP_DEPEND
#define comment
Definition: ael_lex.c:965
A-Law to Signed linear conversion.
#define AST_LIN2A(a)
Definition: alaw.h:50
Asterisk main include file. File version handling, generic pbx functions.
#define DEFAULT_SAMPLE_RATE
Definition: asterisk.h:48
#define ast_log
Definition: astobj2.c:42
static char * encoding
Definition: cdr_pgsql.c:70
static const char desc[]
Definition: cdr_radius.c:84
static struct channel_usage channels
char * end
Definition: eagi_proxy.c:73
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
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
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition: format.c:201
@ AST_FORMAT_CMP_EQUAL
Definition: format.h:36
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_ulaw
Built-in cached ulaw format.
Definition: format_cache.c:86
struct ast_format * ast_format_alaw
Built-in cached alaw format.
Definition: format_cache.c:91
struct ast_format * ast_format_g722
Built-in cached g722 format.
Definition: format_cache.c:106
static char alaw_silence[BUF_SIZE]
Definition: format_pcm.c:43
#define AU_MAGIC
Definition: format_pcm.c:249
#define AU_HDR_SAMPLE_RATE_OFF
Definition: format_pcm.c:244
#define AU_ENC_8BIT_ULAW
Definition: format_pcm.c:247
static int update_header(struct ast_filestream *fs)
Definition: format_pcm.c:331
static struct ast_format_def pcm_f
Definition: format_pcm.c:507
static int au_rewrite(struct ast_filestream *s, const char *comment)
Definition: format_pcm.c:395
static off_t au_tell(struct ast_filestream *fs)
Definition: format_pcm.c:467
static struct ast_format_def alaw_f
Definition: format_pcm.c:491
static int write_header(struct ast_filestream *fs)
Definition: format_pcm.c:365
#define AU_HEADER(var)
Definition: format_pcm.c:238
#define MIN_AU_HEADER_SIZE
Definition: format_pcm.c:237
static struct ast_format_def au_f
Definition: format_pcm.c:530
static struct ast_format_def g722_f
Definition: format_pcm.c:519
static struct ast_frame * g722_read(struct ast_filestream *s, int *whennext)
Definition: format_pcm.c:474
static off_t g722_tell(struct ast_filestream *fs)
Definition: format_pcm.c:486
#define BUF_SIZE
Definition: format_pcm.c:40
#define AU_HDR_MAGIC_OFF
Definition: format_pcm.c:240
static int check_header(struct ast_filestream *fs)
Definition: format_pcm.c:276
static int pcm_trunc(struct ast_filestream *fs)
Definition: format_pcm.c:159
static off_t pcm_tell(struct ast_filestream *fs)
Definition: format_pcm.c:175
#define AU_HDR_CHANNELS_OFF
Definition: format_pcm.c:245
static int pcm_write(struct ast_filestream *fs, struct ast_frame *f)
Definition: format_pcm.c:180
#define AU_HDR_HDR_SIZE_OFF
Definition: format_pcm.c:241
static int load_module(void)
Definition: format_pcm.c:552
#define AU_HDR_DATA_SIZE_OFF
Definition: format_pcm.c:242
static struct ast_frame * pcm_read(struct ast_filestream *s, int *whennext)
Definition: format_pcm.c:79
static int g722_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
Definition: format_pcm.c:481
static int unload_module(void)
Definition: format_pcm.c:544
#define AU_HDR_ENCODING_OFF
Definition: format_pcm.c:243
static int au_open(struct ast_filestream *s)
Definition: format_pcm.c:388
static int au_trunc(struct ast_filestream *fs)
Definition: format_pcm.c:447
static char ulaw_silence[BUF_SIZE]
Definition: format_pcm.c:42
static int au_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
Definition: format_pcm.c:407
static int pcm_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
Definition: format_pcm.c:98
#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_ERROR
#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
#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
struct ast_format_def * fmt
Definition: mod_format.h:103
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
const char * src
uint32_t hdr_size
Definition: format_pcm.c:273
u-Law to Signed linear conversion
#define AST_LIN2MU(a)
Definition: ulaw.h:49
#define MIN(a, b)
Definition: utils.h:231
#define ARRAY_LEN(a)
Definition: utils.h:666