Wed Jan 8 2020 09:49:47

Asterisk developer's documentation


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