Wed Jan 8 2020 09:49:47

Asterisk developer's documentation


format_wav.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 Work with WAV in the proprietary Microsoft format.
22  * Microsoft WAV format (8000hz Signed Linear)
23  * \arg File name extension: wav (lower case)
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: 407511 $")
34 
35 #include "asterisk/mod_format.h"
36 #include "asterisk/module.h"
37 #include "asterisk/endian.h"
38 
39 /* Some Ideas for this code came from makewave.c by Jeffrey Chilton */
40 
41 /* Portions of the conversion code are by guido@sienanet.it */
42 
43 #define WAV_BUF_SIZE 320
44 
45 #define WAV_HEADER_SIZE 44
46 
47 struct wav_desc { /* format-specific parameters */
48  int hz;
49  int bytes;
51  int maxlen;
52  struct timeval last;
53 };
54 
55 #define BLOCKSIZE 160
56 
57 #if __BYTE_ORDER == __LITTLE_ENDIAN
58 #define htoll(b) (b)
59 #define htols(b) (b)
60 #define ltohl(b) (b)
61 #define ltohs(b) (b)
62 #else
63 #if __BYTE_ORDER == __BIG_ENDIAN
64 #define htoll(b) \
65  (((((b) ) & 0xFF) << 24) | \
66  ((((b) >> 8) & 0xFF) << 16) | \
67  ((((b) >> 16) & 0xFF) << 8) | \
68  ((((b) >> 24) & 0xFF) ))
69 #define htols(b) \
70  (((((b) ) & 0xFF) << 8) | \
71  ((((b) >> 8) & 0xFF) ))
72 #define ltohl(b) htoll(b)
73 #define ltohs(b) htols(b)
74 #else
75 #error "Endianess not defined"
76 #endif
77 #endif
78 
79 
80 static int check_header_fmt(FILE *f, int hsize, int hz)
81 {
82  short format, chans, bysam, bisam;
83  int bysec;
84  int freq;
85  if (hsize < 16) {
86  ast_log(LOG_WARNING, "Unexpected header size %d\n", hsize);
87  return -1;
88  }
89  if (fread(&format, 1, 2, f) != 2) {
90  ast_log(LOG_WARNING, "Read failed (format)\n");
91  return -1;
92  }
93  if (ltohs(format) != 1) {
94  ast_log(LOG_WARNING, "Not a supported wav file format (%d). Only PCM encoded, 16 bit, mono, 8kHz files are supported with a lowercase '.wav' extension.\n", ltohs(format));
95  return -1;
96  }
97  if (fread(&chans, 1, 2, f) != 2) {
98  ast_log(LOG_WARNING, "Read failed (format)\n");
99  return -1;
100  }
101  if (ltohs(chans) != 1) {
102  ast_log(LOG_WARNING, "Not in mono %d\n", ltohs(chans));
103  return -1;
104  }
105  if (fread(&freq, 1, 4, f) != 4) {
106  ast_log(LOG_WARNING, "Read failed (freq)\n");
107  return -1;
108  }
109  if (((ltohl(freq) != 8000) && (ltohl(freq) != 16000)) ||
110  ((ltohl(freq) == 8000) && (hz != 8000)) ||
111  ((ltohl(freq) == 16000) && (hz != 16000))) {
112  ast_log(LOG_WARNING, "Unexpected frequency mismatch %d (expecting %d)\n", ltohl(freq),hz);
113  return -1;
114  }
115  /* Ignore the byte frequency */
116  if (fread(&bysec, 1, 4, f) != 4) {
117  ast_log(LOG_WARNING, "Read failed (BYTES_PER_SECOND)\n");
118  return -1;
119  }
120  /* Check bytes per sample */
121  if (fread(&bysam, 1, 2, f) != 2) {
122  ast_log(LOG_WARNING, "Read failed (BYTES_PER_SAMPLE)\n");
123  return -1;
124  }
125  if (ltohs(bysam) != 2) {
126  ast_log(LOG_WARNING, "Can only handle 16bits per sample: %d\n", ltohs(bysam));
127  return -1;
128  }
129  if (fread(&bisam, 1, 2, f) != 2) {
130  ast_log(LOG_WARNING, "Read failed (Bits Per Sample): %d\n", ltohs(bisam));
131  return -1;
132  }
133  /* Skip any additional header */
134  if (fseek(f,hsize-16,SEEK_CUR) == -1 ) {
135  ast_log(LOG_WARNING, "Failed to skip remaining header bytes: %d\n", hsize-16 );
136  return -1;
137  }
138  return 0;
139 }
140 
141 static int check_header(FILE *f, int hz)
142 {
143  int type, size, formtype;
144  int data;
145  if (fread(&type, 1, 4, f) != 4) {
146  ast_log(LOG_WARNING, "Read failed (type)\n");
147  return -1;
148  }
149  if (fread(&size, 1, 4, f) != 4) {
150  ast_log(LOG_WARNING, "Read failed (size)\n");
151  return -1;
152  }
153  size = ltohl(size);
154  if (fread(&formtype, 1, 4, f) != 4) {
155  ast_log(LOG_WARNING, "Read failed (formtype)\n");
156  return -1;
157  }
158  if (memcmp(&type, "RIFF", 4)) {
159  ast_log(LOG_WARNING, "Does not begin with RIFF\n");
160  return -1;
161  }
162  if (memcmp(&formtype, "WAVE", 4)) {
163  ast_log(LOG_WARNING, "Does not contain WAVE\n");
164  return -1;
165  }
166  /* Skip any facts and get the first data block */
167  for(;;)
168  {
169  char buf[4];
170 
171  /* Begin data chunk */
172  if (fread(&buf, 1, 4, f) != 4) {
173  ast_log(LOG_WARNING, "Read failed (block header format)\n");
174  return -1;
175  }
176  /* Data has the actual length of data in it */
177  if (fread(&data, 1, 4, f) != 4) {
178  ast_log(LOG_WARNING, "Read failed (block '%.4s' header length)\n", buf);
179  return -1;
180  }
181  data = ltohl(data);
182  if (memcmp(&buf, "fmt ", 4) == 0) {
183  if (check_header_fmt(f, data, hz))
184  return -1;
185  continue;
186  }
187  if(memcmp(buf, "data", 4) == 0 )
188  break;
189  ast_log(LOG_DEBUG, "Skipping unknown block '%.4s'\n", buf);
190  if (fseek(f,data,SEEK_CUR) == -1 ) {
191  ast_log(LOG_WARNING, "Failed to skip '%.4s' block: %d\n", buf, data);
192  return -1;
193  }
194  }
195 #if 0
196  curpos = lseek(fd, 0, SEEK_CUR);
197  truelength = lseek(fd, 0, SEEK_END);
198  lseek(fd, curpos, SEEK_SET);
199  truelength -= curpos;
200 #endif
201  return data;
202 }
203 
204 static int update_header(FILE *f)
205 {
206  off_t cur,end;
207  int datalen,filelen,bytes;
208 
209  cur = ftello(f);
210  fseek(f, 0, SEEK_END);
211  end = ftello(f);
212  /* data starts 44 bytes in */
213  bytes = end - 44;
214  datalen = htoll(bytes);
215  /* chunk size is bytes of data plus 36 bytes of header */
216  filelen = htoll(36 + bytes);
217 
218  if (cur < 0) {
219  ast_log(LOG_WARNING, "Unable to find our position: %s\n", strerror(errno));
220  return -1;
221  }
222  if (fseek(f, 4, SEEK_SET)) {
223  ast_log(LOG_WARNING, "Unable to set our position: %s\n", strerror(errno));
224  return -1;
225  }
226  if (fwrite(&filelen, 1, 4, f) != 4) {
227  ast_log(LOG_WARNING, "Unable to set write file size: %s\n", strerror(errno));
228  return -1;
229  }
230  if (fseek(f, 40, SEEK_SET)) {
231  ast_log(LOG_WARNING, "Unable to set our position: %s\n", strerror(errno));
232  return -1;
233  }
234  if (fwrite(&datalen, 1, 4, f) != 4) {
235  ast_log(LOG_WARNING, "Unable to set write datalen: %s\n", strerror(errno));
236  return -1;
237  }
238  if (fseeko(f, cur, SEEK_SET)) {
239  ast_log(LOG_WARNING, "Unable to return to position: %s\n", strerror(errno));
240  return -1;
241  }
242  return 0;
243 }
244 
245 static int write_header(FILE *f, int writehz)
246 {
247  unsigned int hz;
248  unsigned int bhz;
249  unsigned int hs = htoll(16);
250  unsigned short fmt = htols(1);
251  unsigned short chans = htols(1);
252  unsigned short bysam = htols(2);
253  unsigned short bisam = htols(16);
254  unsigned int size = htoll(0);
255 
256  if (writehz == 16000) {
257  hz = htoll(16000);
258  bhz = htoll(32000);
259  } else {
260  hz = htoll(8000);
261  bhz = htoll(16000);
262  }
263  /* Write a wav header, ignoring sizes which will be filled in later */
264  fseek(f,0,SEEK_SET);
265  if (fwrite("RIFF", 1, 4, f) != 4) {
266  ast_log(LOG_WARNING, "Unable to write header\n");
267  return -1;
268  }
269  if (fwrite(&size, 1, 4, f) != 4) {
270  ast_log(LOG_WARNING, "Unable to write header\n");
271  return -1;
272  }
273  if (fwrite("WAVEfmt ", 1, 8, f) != 8) {
274  ast_log(LOG_WARNING, "Unable to write header\n");
275  return -1;
276  }
277  if (fwrite(&hs, 1, 4, f) != 4) {
278  ast_log(LOG_WARNING, "Unable to write header\n");
279  return -1;
280  }
281  if (fwrite(&fmt, 1, 2, f) != 2) {
282  ast_log(LOG_WARNING, "Unable to write header\n");
283  return -1;
284  }
285  if (fwrite(&chans, 1, 2, f) != 2) {
286  ast_log(LOG_WARNING, "Unable to write header\n");
287  return -1;
288  }
289  if (fwrite(&hz, 1, 4, f) != 4) {
290  ast_log(LOG_WARNING, "Unable to write header\n");
291  return -1;
292  }
293  if (fwrite(&bhz, 1, 4, f) != 4) {
294  ast_log(LOG_WARNING, "Unable to write header\n");
295  return -1;
296  }
297  if (fwrite(&bysam, 1, 2, f) != 2) {
298  ast_log(LOG_WARNING, "Unable to write header\n");
299  return -1;
300  }
301  if (fwrite(&bisam, 1, 2, f) != 2) {
302  ast_log(LOG_WARNING, "Unable to write header\n");
303  return -1;
304  }
305  if (fwrite("data", 1, 4, f) != 4) {
306  ast_log(LOG_WARNING, "Unable to write header\n");
307  return -1;
308  }
309  if (fwrite(&size, 1, 4, f) != 4) {
310  ast_log(LOG_WARNING, "Unable to write header\n");
311  return -1;
312  }
313  return 0;
314 }
315 
316 static int wav_open(struct ast_filestream *s)
317 {
318  /* We don't have any header to read or anything really, but
319  if we did, it would go here. We also might want to check
320  and be sure it's a valid file. */
321  struct wav_desc *tmp = (struct wav_desc *)s->_private;
322  if ((tmp->maxlen = check_header(s->f, (s->fmt->format == AST_FORMAT_SLINEAR16 ? 16000 : 8000))) < 0)
323  return -1;
324  return 0;
325 }
326 
327 static int wav_rewrite(struct ast_filestream *s, const char *comment)
328 {
329  /* We don't have any header to read or anything really, but
330  if we did, it would go here. We also might want to check
331  and be sure it's a valid file. */
332 
333  struct wav_desc *tmp = (struct wav_desc *)s->_private;
334  tmp->hz = (s->fmt->format == AST_FORMAT_SLINEAR16 ? 16000 : 8000);
335  if (write_header(s->f,tmp->hz))
336  return -1;
337  return 0;
338 }
339 
340 static void wav_close(struct ast_filestream *s)
341 {
342  char zero = 0;
343  struct wav_desc *fs = (struct wav_desc *)s->_private;
344 
345  if (s->mode == O_RDONLY) {
346  return;
347  }
348 
349  if (s->filename) {
350  update_header(s->f);
351  }
352 
353  /* Pad to even length */
354  if (fs->bytes & 0x1) {
355  if (!fwrite(&zero, 1, 1, s->f)) {
356  ast_log(LOG_WARNING, "fwrite() failed: %s\n", strerror(errno));
357  }
358  }
359 }
360 
361 static struct ast_frame *wav_read(struct ast_filestream *s, int *whennext)
362 {
363  int res;
364  int samples; /* actual samples read */
365 #if __BYTE_ORDER == __BIG_ENDIAN
366  int x;
367  short *tmp;
368 #endif
369  int bytes;
370  off_t here;
371  /* Send a frame from the file to the appropriate channel */
372  struct wav_desc *fs = (struct wav_desc *)s->_private;
373 
374  bytes = (fs->hz == 16000 ? (WAV_BUF_SIZE * 2) : WAV_BUF_SIZE);
375 
376  here = ftello(s->f);
377  if (fs->maxlen - here < bytes) /* truncate if necessary */
378  bytes = fs->maxlen - here;
379  if (bytes < 0)
380  bytes = 0;
381 /* ast_debug(1, "here: %d, maxlen: %d, bytes: %d\n", here, s->maxlen, bytes); */
383  s->fr.subclass.codec = (fs->hz == 16000 ? AST_FORMAT_SLINEAR16 : AST_FORMAT_SLINEAR);
384  s->fr.mallocd = 0;
386 
387  if ( (res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) <= 0 ) {
388  if (res)
389  ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
390  return NULL;
391  }
392  s->fr.datalen = res;
393  s->fr.samples = samples = res / 2;
394 
395 #if __BYTE_ORDER == __BIG_ENDIAN
396  tmp = (short *)(s->fr.data.ptr);
397  /* file format is little endian so we need to swap */
398  for( x = 0; x < samples; x++)
399  tmp[x] = (tmp[x] << 8) | ((tmp[x] & 0xff00) >> 8);
400 #endif
401 
402  *whennext = samples;
403  return &s->fr;
404 }
405 
406 static int wav_write(struct ast_filestream *fs, struct ast_frame *f)
407 {
408 #if __BYTE_ORDER == __BIG_ENDIAN
409  int x;
410  short tmp[16000], *tmpi;
411 #endif
412  struct wav_desc *s = (struct wav_desc *)fs->_private;
413  int res;
414 
415  if (f->frametype != AST_FRAME_VOICE) {
416  ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
417  return -1;
418  }
420  ast_log(LOG_WARNING, "Asked to write non-SLINEAR%s frame (%s)!\n", s->hz == 16000 ? "16" : "", ast_getformatname(f->subclass.codec));
421  return -1;
422  }
423  if (f->subclass.codec != fs->fmt->format) {
424  ast_log(LOG_WARNING, "Can't change SLINEAR frequency during write\n");
425  return -1;
426  }
427  if (!f->datalen)
428  return -1;
429 
430 #if __BYTE_ORDER == __BIG_ENDIAN
431  /* swap and write */
432  if (f->datalen > sizeof(tmp)) {
433  ast_log(LOG_WARNING, "Data length is too long\n");
434  return -1;
435  }
436  tmpi = f->data.ptr;
437  for (x=0; x < f->datalen/2; x++)
438  tmp[x] = (tmpi[x] << 8) | ((tmpi[x] & 0xff00) >> 8);
439 
440  if ((res = fwrite(tmp, 1, f->datalen, fs->f)) != f->datalen ) {
441 #else
442  /* just write */
443  if ((res = fwrite(f->data.ptr, 1, f->datalen, fs->f)) != f->datalen ) {
444 #endif
445  ast_log(LOG_WARNING, "Bad write (%d): %s\n", res, strerror(errno));
446  return -1;
447  }
448 
449  s->bytes += f->datalen;
450 
451  return 0;
452 
453 }
454 
455 static int wav_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
456 {
457  off_t min = WAV_HEADER_SIZE, max, cur, offset = 0, samples;
458 
459  samples = sample_offset * 2; /* SLINEAR is 16 bits mono, so sample_offset * 2 = bytes */
460 
461  if ((cur = ftello(fs->f)) < 0) {
462  ast_log(AST_LOG_WARNING, "Unable to determine current position in wav filestream %p: %s\n", fs, strerror(errno));
463  return -1;
464  }
465 
466  if (fseeko(fs->f, 0, SEEK_END) < 0) {
467  ast_log(AST_LOG_WARNING, "Unable to seek to end of wav filestream %p: %s\n", fs, strerror(errno));
468  return -1;
469  }
470 
471  if ((max = ftello(fs->f)) < 0) {
472  ast_log(AST_LOG_WARNING, "Unable to determine max position in wav filestream %p: %s\n", fs, strerror(errno));
473  return -1;
474  }
475 
476  if (whence == SEEK_SET)
477  offset = samples + min;
478  else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
479  offset = samples + cur;
480  else if (whence == SEEK_END)
481  offset = max - samples;
482  if (whence != SEEK_FORCECUR) {
483  offset = (offset > max)?max:offset;
484  }
485  /* always protect the header space. */
486  offset = (offset < min)?min:offset;
487  return fseeko(fs->f, offset, SEEK_SET);
488 }
489 
490 static int wav_trunc(struct ast_filestream *fs)
491 {
492  int fd;
493  off_t cur;
494 
495  if ((fd = fileno(fs->f)) < 0) {
496  ast_log(AST_LOG_WARNING, "Unable to determine file descriptor for wav filestream %p: %s\n", fs, strerror(errno));
497  return -1;
498  }
499  if ((cur = ftello(fs->f)) < 0) {
500  ast_log(AST_LOG_WARNING, "Unable to determine current position in wav filestream %p: %s\n", fs, strerror(errno));
501  return -1;
502  }
503  /* Truncate file to current length */
504  if (ftruncate(fd, cur)) {
505  return -1;
506  }
507  return update_header(fs->f);
508 }
509 
510 static off_t wav_tell(struct ast_filestream *fs)
511 {
512  off_t offset;
513  offset = ftello(fs->f);
514  /* subtract header size to get samples, then divide by 2 for 16 bit samples */
515  return (offset - 44)/2;
516 }
517 
518 static const struct ast_format wav16_f = {
519  .name = "wav16",
520  .exts = "wav16",
521  .format = AST_FORMAT_SLINEAR16,
522  .open = wav_open,
523  .rewrite = wav_rewrite,
524  .write = wav_write,
525  .seek = wav_seek,
526  .trunc = wav_trunc,
527  .tell = wav_tell,
528  .read = wav_read,
529  .close = wav_close,
530  .buf_size = (WAV_BUF_SIZE * 2) + AST_FRIENDLY_OFFSET,
531  .desc_size = sizeof(struct wav_desc),
532 };
533 
534 static const struct ast_format wav_f = {
535  .name = "wav",
536  .exts = "wav",
537  .format = AST_FORMAT_SLINEAR,
538  .open = wav_open,
539  .rewrite = wav_rewrite,
540  .write = wav_write,
541  .seek = wav_seek,
542  .trunc = wav_trunc,
543  .tell = wav_tell,
544  .read = wav_read,
545  .close = wav_close,
546  .buf_size = WAV_BUF_SIZE + AST_FRIENDLY_OFFSET,
547  .desc_size = sizeof(struct wav_desc),
548 };
549 
550 static int load_module(void)
551 {
552  if (ast_format_register(&wav_f)
553  || ast_format_register(&wav16_f))
556 }
557 
558 static int unload_module(void)
559 {
560  return ast_format_unregister(wav_f.name)
561  || ast_format_unregister(wav16_f.name);
562 }
563 
564 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Microsoft WAV/WAV16 format (8kHz/16kHz Signed Linear)",
565  .load = load_module,
566  .unload = unload_module,
567  .load_pri = AST_MODPRI_APP_DEPEND
568 );
int lasttimeout
Definition: format_wav.c:50
union ast_frame_subclass subclass
Definition: frame.h:146
Asterisk main include file. File version handling, generic pbx functions.
#define ast_format_register(f)
Definition: mod_format.h:131
static int write_header(FILE *f, int writehz)
Definition: format_wav.c:245
static int wav_write(struct ast_filestream *fs, struct ast_frame *f)
Definition: format_wav.c:406
static int update_header(FILE *f)
Definition: format_wav.c:204
static int check_header_fmt(FILE *f, int hsize, int hz)
Definition: format_wav.c:80
#define WAV_HEADER_SIZE
Definition: format_wav.c:45
void * ptr
Definition: frame.h:160
#define LOG_WARNING
Definition: logger.h:144
#define AST_LOG_WARNING
Definition: logger.h:149
static int wav_rewrite(struct ast_filestream *s, const char *comment)
Definition: format_wav.c:327
Each supported file format is described by the following structure.
Definition: mod_format.h:43
static void wav_close(struct ast_filestream *s)
Definition: format_wav.c:340
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
Definition: module.h:374
static struct ast_format wav_f
Definition: format_wav.c:534
format_t codec
Definition: frame.h:137
int hz
Definition: format_wav.c:48
static struct ast_format wav16_f
Definition: format_wav.c:518
#define LOG_DEBUG
Definition: logger.h:122
struct timeval last
Definition: format_wav.c:52
#define AST_FRAME_SET_BUFFER(fr, _base, _ofs, _datalen)
Definition: frame.h:183
format_t format
Definition: mod_format.h:47
#define AST_FRIENDLY_OFFSET
Offset into a frame&#39;s data buffer.
Definition: frame.h:204
Asterisk architecture endianess compatibility definitions.
int datalen
Definition: frame.h:148
struct ast_frame fr
Definition: mod_format.h:117
struct ast_format * fmt
Definition: mod_format.h:102
static int wav_trunc(struct ast_filestream *fs)
Definition: format_wav.c:490
#define WAV_BUF_SIZE
Definition: format_wav.c:43
int bytes
Definition: format_wav.c:49
static int wav_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
Definition: format_wav.c:455
#define AST_FORMAT_SLINEAR16
Definition: frame.h:272
static int load_module(void)
Definition: format_wav.c:550
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
#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
int errno
#define SEEK_FORCECUR
Definition: file.h:50
static struct ast_format f[]
Definition: format_g726.c:181
if(yyss+yystacksize-1<=yyssp)
Definition: ast_expr2.c:1874
static int wav_open(struct ast_filestream *s)
Definition: format_wav.c:316
static const char type[]
Definition: chan_nbs.c:57
int mallocd
Definition: frame.h:152
char * filename
Definition: mod_format.h:106
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
#define AST_FORMAT_SLINEAR
Definition: frame.h:254
int desc_size
Definition: mod_format.h:90
Data structure associated with a single frame of data.
Definition: frame.h:142
static int unload_module(void)
Definition: format_wav.c:558
enum ast_frame_type frametype
Definition: frame.h:144
int maxlen
Definition: format_wav.c:51
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:38
Asterisk module definitions.
static struct ast_frame * wav_read(struct ast_filestream *s, int *whennext)
Definition: format_wav.c:361
static snd_pcm_format_t format
Definition: chan_alsa.c:93
union ast_frame::@172 data
static int check_header(FILE *f, int hz)
Definition: format_wav.c:141
#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
static off_t wav_tell(struct ast_filestream *fs)
Definition: format_wav.c:510