Wed Jan 8 2020 09:50:12

Asterisk developer's documentation


format_wav_gsm.c File Reference

Save GSM in the proprietary Microsoft format. More...

#include "asterisk.h"
#include "asterisk/mod_format.h"
#include "asterisk/module.h"
#include "asterisk/endian.h"
#include "msgsm.h"

Go to the source code of this file.

Data Structures

struct  wavg_desc
 

Macros

#define GSM_FRAME_SIZE   33
 
#define GSM_SAMPLES   160 /* samples in a GSM block */
 
#define MSGSM_DATA_OFFSET   60 /* offset of data bytes */
 
#define MSGSM_FRAME_SIZE   65
 
#define MSGSM_SAMPLES   (2*GSM_SAMPLES) /* samples in an MSGSM block */
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
static int check_header (FILE *f)
 
static int load_module (void)
 
static int unload_module (void)
 
static int update_header (FILE *f)
 
static int wav_open (struct ast_filestream *s)
 
static struct ast_framewav_read (struct ast_filestream *s, int *whennext)
 
static int wav_rewrite (struct ast_filestream *s, const char *comment)
 
static int wav_seek (struct ast_filestream *fs, off_t sample_offset, int whence)
 
static off_t wav_tell (struct ast_filestream *fs)
 
static int wav_trunc (struct ast_filestream *fs)
 
static int wav_write (struct ast_filestream *s, struct ast_frame *f)
 
static int write_header (FILE *f)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Microsoft WAV format (Proprietary GSM)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND }
 
static struct ast_module_infoast_module_info = &__mod_info
 
static char msgsm_silence []
 
static struct ast_format wav49_f
 

Detailed Description

Save GSM in the proprietary Microsoft format.

Microsoft WAV format (Proprietary GSM)

  • File name extension: WAV,wav49 (Upper case WAV, lower case is another format) This format can be played on Windows systems, used for e-mail attachments mainly.

Definition in file format_wav_gsm.c.

Macro Definition Documentation

#define GSM_FRAME_SIZE   33

Definition at line 48 of file format_wav_gsm.c.

Referenced by wav_read(), and wav_write().

#define GSM_SAMPLES   160 /* samples in a GSM block */

Definition at line 51 of file format_wav_gsm.c.

Referenced by wav_read().

#define MSGSM_DATA_OFFSET   60 /* offset of data bytes */

Definition at line 50 of file format_wav_gsm.c.

Referenced by update_header(), wav_seek(), and wav_tell().

#define MSGSM_FRAME_SIZE   65

Definition at line 49 of file format_wav_gsm.c.

Referenced by update_header(), wav_read(), wav_seek(), wav_tell(), wav_write(), and write_header().

#define MSGSM_SAMPLES   (2*GSM_SAMPLES) /* samples in an MSGSM block */

Definition at line 52 of file format_wav_gsm.c.

Referenced by update_header(), wav_seek(), wav_tell(), and write_header().

Function Documentation

static void __reg_module ( void  )
static

Definition at line 584 of file format_wav_gsm.c.

static void __unreg_module ( void  )
static

Definition at line 584 of file format_wav_gsm.c.

static int check_header ( FILE *  f)
static

Definition at line 92 of file format_wav_gsm.c.

References ast_log(), DEFAULT_SAMPLE_RATE, format, LOG_WARNING, and type.

Referenced by wav_open().

93 {
94  int type, size, formtype;
95  int fmt, hsize, fact;
96  short format, chans;
97  int freq;
98  int data;
99  if (fread(&type, 1, 4, f) != 4) {
100  ast_log(LOG_WARNING, "Read failed (type)\n");
101  return -1;
102  }
103  if (fread(&size, 1, 4, f) != 4) {
104  ast_log(LOG_WARNING, "Read failed (size)\n");
105  return -1;
106  }
107  size = ltohl(size);
108  if (fread(&formtype, 1, 4, f) != 4) {
109  ast_log(LOG_WARNING, "Read failed (formtype)\n");
110  return -1;
111  }
112  if (memcmp(&type, "RIFF", 4)) {
113  ast_log(LOG_WARNING, "Does not begin with RIFF\n");
114  return -1;
115  }
116  if (memcmp(&formtype, "WAVE", 4)) {
117  ast_log(LOG_WARNING, "Does not contain WAVE\n");
118  return -1;
119  }
120  if (fread(&fmt, 1, 4, f) != 4) {
121  ast_log(LOG_WARNING, "Read failed (fmt)\n");
122  return -1;
123  }
124  if (memcmp(&fmt, "fmt ", 4)) {
125  ast_log(LOG_WARNING, "Does not say fmt\n");
126  return -1;
127  }
128  if (fread(&hsize, 1, 4, f) != 4) {
129  ast_log(LOG_WARNING, "Read failed (formtype)\n");
130  return -1;
131  }
132  if (ltohl(hsize) != 20) {
133  ast_log(LOG_WARNING, "Unexpected header size %d\n", ltohl(hsize));
134  return -1;
135  }
136  if (fread(&format, 1, 2, f) != 2) {
137  ast_log(LOG_WARNING, "Read failed (format)\n");
138  return -1;
139  }
140  if (ltohs(format) != 49) {
141  ast_log(LOG_WARNING, "Not a GSM file %d\n", ltohs(format));
142  return -1;
143  }
144  if (fread(&chans, 1, 2, f) != 2) {
145  ast_log(LOG_WARNING, "Read failed (format)\n");
146  return -1;
147  }
148  if (ltohs(chans) != 1) {
149  ast_log(LOG_WARNING, "Not in mono %d\n", ltohs(chans));
150  return -1;
151  }
152  if (fread(&freq, 1, 4, f) != 4) {
153  ast_log(LOG_WARNING, "Read failed (freq)\n");
154  return -1;
155  }
156  if (ltohl(freq) != DEFAULT_SAMPLE_RATE) {
157  ast_log(LOG_WARNING, "Unexpected frequency %d\n", ltohl(freq));
158  return -1;
159  }
160  /* Ignore the byte frequency */
161  if (fread(&freq, 1, 4, f) != 4) {
162  ast_log(LOG_WARNING, "Read failed (X_1)\n");
163  return -1;
164  }
165  /* Ignore the two weird fields */
166  if (fread(&freq, 1, 4, f) != 4) {
167  ast_log(LOG_WARNING, "Read failed (X_2/X_3)\n");
168  return -1;
169  }
170  /* Ignore the byte frequency */
171  if (fread(&freq, 1, 4, f) != 4) {
172  ast_log(LOG_WARNING, "Read failed (Y_1)\n");
173  return -1;
174  }
175  /* Check for the word fact */
176  if (fread(&fact, 1, 4, f) != 4) {
177  ast_log(LOG_WARNING, "Read failed (fact)\n");
178  return -1;
179  }
180  if (memcmp(&fact, "fact", 4)) {
181  ast_log(LOG_WARNING, "Does not say fact\n");
182  return -1;
183  }
184  /* Ignore the "fact value" */
185  if (fread(&fact, 1, 4, f) != 4) {
186  ast_log(LOG_WARNING, "Read failed (fact header)\n");
187  return -1;
188  }
189  if (fread(&fact, 1, 4, f) != 4) {
190  ast_log(LOG_WARNING, "Read failed (fact value)\n");
191  return -1;
192  }
193  /* Check for the word data */
194  if (fread(&data, 1, 4, f) != 4) {
195  ast_log(LOG_WARNING, "Read failed (data)\n");
196  return -1;
197  }
198  if (memcmp(&data, "data", 4)) {
199  ast_log(LOG_WARNING, "Does not say data\n");
200  return -1;
201  }
202  /* Ignore the data length */
203  if (fread(&data, 1, 4, f) != 4) {
204  ast_log(LOG_WARNING, "Read failed (data)\n");
205  return -1;
206  }
207  return 0;
208 }
#define DEFAULT_SAMPLE_RATE
Definition: asterisk.h:41
#define LOG_WARNING
Definition: logger.h:144
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 struct ast_format f[]
Definition: format_g726.c:181
static const char type[]
Definition: chan_nbs.c:57
static snd_pcm_format_t format
Definition: chan_alsa.c:93
static int load_module ( void  )
static

Definition at line 568 of file format_wav_gsm.c.

References ast_format_register, AST_MODULE_LOAD_FAILURE, and AST_MODULE_LOAD_SUCCESS.

569 {
573 }
#define ast_format_register(f)
Definition: mod_format.h:131
static struct ast_format wav49_f
static int unload_module ( void  )
static

Definition at line 575 of file format_wav_gsm.c.

References ast_format_unregister(), and ast_format::name.

576 {
578 }
int ast_format_unregister(const char *name)
Unregisters a file format.
Definition: file.c:104
char name[80]
Definition: mod_format.h:44
static struct ast_format wav49_f
static int update_header ( FILE *  f)
static

Definition at line 210 of file format_wav_gsm.c.

References ast_log(), LOG_WARNING, MSGSM_DATA_OFFSET, MSGSM_FRAME_SIZE, and MSGSM_SAMPLES.

Referenced by wav_trunc(), and wav_write().

211 {
212  off_t cur,end,bytes;
213  int datalen, filelen, samples;
214 
215  cur = ftello(f);
216  fseek(f, 0, SEEK_END);
217  end = ftello(f);
218  /* in a gsm WAV, data starts 60 bytes in */
219  bytes = end - MSGSM_DATA_OFFSET;
220  samples = htoll(bytes / MSGSM_FRAME_SIZE * MSGSM_SAMPLES);
221  datalen = htoll(bytes);
222  filelen = htoll(MSGSM_DATA_OFFSET - 8 + bytes);
223  if (cur < 0) {
224  ast_log(LOG_WARNING, "Unable to find our position\n");
225  return -1;
226  }
227  if (fseek(f, 4, SEEK_SET)) {
228  ast_log(LOG_WARNING, "Unable to set our position\n");
229  return -1;
230  }
231  if (fwrite(&filelen, 1, 4, f) != 4) {
232  ast_log(LOG_WARNING, "Unable to write file size\n");
233  return -1;
234  }
235  if (fseek(f, 48, SEEK_SET)) {
236  ast_log(LOG_WARNING, "Unable to set our position\n");
237  return -1;
238  }
239  if (fwrite(&samples, 1, 4, f) != 4) {
240  ast_log(LOG_WARNING, "Unable to write samples\n");
241  return -1;
242  }
243  if (fseek(f, 56, SEEK_SET)) {
244  ast_log(LOG_WARNING, "Unable to set our position\n");
245  return -1;
246  }
247  if (fwrite(&datalen, 1, 4, f) != 4) {
248  ast_log(LOG_WARNING, "Unable to write datalen\n");
249  return -1;
250  }
251  if (fseeko(f, cur, SEEK_SET)) {
252  ast_log(LOG_WARNING, "Unable to return to position\n");
253  return -1;
254  }
255  return 0;
256 }
#define LOG_WARNING
Definition: logger.h:144
#define MSGSM_SAMPLES
#define MSGSM_DATA_OFFSET
int bytes
Definition: format_wav.c:49
#define MSGSM_FRAME_SIZE
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 struct ast_format f[]
Definition: format_g726.c:181
static int wav_open ( struct ast_filestream s)
static

Definition at line 372 of file format_wav_gsm.c.

References ast_filestream::_private, check_header(), ast_filestream::f, if(), and wavg_desc::secondhalf.

373 {
374  /* We don't have any header to read or anything really, but
375  if we did, it would go here. We also might want to check
376  and be sure it's a valid file. */
377  struct wavg_desc *fs = (struct wavg_desc *)s->_private;
378 
379  if (check_header(s->f))
380  return -1;
381  fs->secondhalf = 0; /* not strictly necessary */
382  return 0;
383 }
static int check_header(FILE *f)
void * _private
Definition: mod_format.h:119
if(yyss+yystacksize-1<=yyssp)
Definition: ast_expr2.c:1874
static struct ast_frame* wav_read ( struct ast_filestream s,
int *  whennext 
)
static

Definition at line 396 of file format_wav_gsm.c.

References ast_filestream::_private, AST_FORMAT_GSM, AST_FRAME_SET_BUFFER, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), ast_filestream::buf, ast_frame_subclass::codec, conv65(), ast_frame::data, errno, ast_filestream::f, ast_filestream::fr, ast_frame::frametype, GSM_FRAME_SIZE, GSM_SAMPLES, LOG_WARNING, ast_frame::mallocd, MSGSM_FRAME_SIZE, ast_frame::offset, ast_frame::ptr, ast_frame::samples, wavg_desc::secondhalf, and ast_frame::subclass.

397 {
398  /* Send a frame from the file to the appropriate channel */
399  struct wavg_desc *fs = (struct wavg_desc *)s->_private;
400 
404  s->fr.samples = GSM_SAMPLES;
405  s->fr.mallocd = 0;
407  if (fs->secondhalf) {
408  /* Just return a frame based on the second GSM frame */
409  s->fr.data.ptr = (char *)s->fr.data.ptr + GSM_FRAME_SIZE;
410  s->fr.offset += GSM_FRAME_SIZE;
411  } else {
412  /* read and convert */
413  unsigned char msdata[MSGSM_FRAME_SIZE];
414  int res;
415 
416  if ((res = fread(msdata, 1, MSGSM_FRAME_SIZE, s->f)) != MSGSM_FRAME_SIZE) {
417  if (res && (res != 1))
418  ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
419  return NULL;
420  }
421  /* Convert from MS format to two real GSM frames */
422  conv65(msdata, s->fr.data.ptr);
423  }
424  fs->secondhalf = !fs->secondhalf;
425  *whennext = GSM_SAMPLES;
426  return &s->fr;
427 }
union ast_frame_subclass subclass
Definition: frame.h:146
int offset
Definition: frame.h:156
void * ptr
Definition: frame.h:160
#define LOG_WARNING
Definition: logger.h:144
format_t codec
Definition: frame.h:137
#define GSM_FRAME_SIZE
#define AST_FRAME_SET_BUFFER(fr, _base, _ofs, _datalen)
Definition: frame.h:183
#define AST_FRIENDLY_OFFSET
Offset into a frame&#39;s data buffer.
Definition: frame.h:204
struct ast_frame fr
Definition: mod_format.h:117
static void conv65(wav_byte *c, gsm_byte *d)
Definition: msgsm.h:455
void * _private
Definition: mod_format.h:119
#define MSGSM_FRAME_SIZE
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 GSM_SAMPLES
int mallocd
Definition: frame.h:152
enum ast_frame_type frametype
Definition: frame.h:144
union ast_frame::@172 data
#define AST_FORMAT_GSM
Definition: frame.h:244
int samples
Definition: frame.h:150
static int wav_rewrite ( struct ast_filestream s,
const char *  comment 
)
static

Definition at line 385 of file format_wav_gsm.c.

References ast_filestream::f, and write_header().

386 {
387  /* We don't have any header to read or anything really, but
388  if we did, it would go here. We also might want to check
389  and be sure it's a valid file. */
390 
391  if (write_header(s->f))
392  return -1;
393  return 0;
394 }
static int write_header(FILE *f)
static int wav_seek ( struct ast_filestream fs,
off_t  sample_offset,
int  whence 
)
static

Definition at line 476 of file format_wav_gsm.c.

References ast_filestream::_private, ast_log(), AST_LOG_WARNING, errno, ast_filestream::f, if(), LOG_WARNING, MSGSM_DATA_OFFSET, MSGSM_FRAME_SIZE, MSGSM_SAMPLES, wavg_desc::secondhalf, and SEEK_FORCECUR.

477 {
478  off_t offset = 0, min = MSGSM_DATA_OFFSET, distance, max, cur;
479  struct wavg_desc *s = (struct wavg_desc *)fs->_private;
480 
481  if ((cur = ftello(fs->f)) < 0) {
482  ast_log(AST_LOG_WARNING, "Unable to determine current position in WAV filestream %p: %s\n", fs, strerror(errno));
483  return -1;
484  }
485 
486  if (fseeko(fs->f, 0, SEEK_END) < 0) {
487  ast_log(AST_LOG_WARNING, "Unable to seek to end of WAV filestream %p: %s\n", fs, strerror(errno));
488  return -1;
489  }
490 
491  /* XXX ideally, should round correctly */
492  if ((max = ftello(fs->f)) < 0) {
493  ast_log(AST_LOG_WARNING, "Unable to determine max position in WAV filestream %p: %s\n", fs, strerror(errno));
494  return -1;
495  }
496 
497  /* Compute the distance in bytes, rounded to the block size */
498  distance = (sample_offset/MSGSM_SAMPLES) * MSGSM_FRAME_SIZE;
499  if (whence == SEEK_SET)
500  offset = distance + min;
501  else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
502  offset = distance + cur;
503  else if (whence == SEEK_END)
504  offset = max - distance;
505  /* always protect against seeking past end of header */
506  if (offset < min)
507  offset = min;
508  if (whence != SEEK_FORCECUR) {
509  if (offset > max)
510  offset = max;
511  } else if (offset > max) {
512  int i;
513  fseek(fs->f, 0, SEEK_END);
514  for (i=0; i< (offset - max) / MSGSM_FRAME_SIZE; i++) {
515  if (!fwrite(msgsm_silence, 1, MSGSM_FRAME_SIZE, fs->f)) {
516  ast_log(LOG_WARNING, "fwrite() failed: %s\n", strerror(errno));
517  }
518  }
519  }
520  s->secondhalf = 0;
521  return fseeko(fs->f, offset, SEEK_SET);
522 }
#define LOG_WARNING
Definition: logger.h:144
#define AST_LOG_WARNING
Definition: logger.h:149
#define MSGSM_SAMPLES
#define MSGSM_DATA_OFFSET
void * _private
Definition: mod_format.h:119
#define MSGSM_FRAME_SIZE
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 char msgsm_silence[]
if(yyss+yystacksize-1<=yyssp)
Definition: ast_expr2.c:1874
static off_t wav_tell ( struct ast_filestream fs)
static

Definition at line 544 of file format_wav_gsm.c.

References ast_filestream::f, MSGSM_DATA_OFFSET, MSGSM_FRAME_SIZE, and MSGSM_SAMPLES.

545 {
546  off_t offset;
547  offset = ftello(fs->f);
548  /* since this will most likely be used later in play or record, lets stick
549  * to that level of resolution, just even frames boundaries */
551 }
#define MSGSM_SAMPLES
#define MSGSM_DATA_OFFSET
#define MSGSM_FRAME_SIZE
static int wav_trunc ( struct ast_filestream fs)
static

Definition at line 524 of file format_wav_gsm.c.

References ast_log(), AST_LOG_WARNING, errno, ast_filestream::f, and update_header().

525 {
526  int fd;
527  off_t cur;
528 
529  if ((fd = fileno(fs->f)) < 0) {
530  ast_log(AST_LOG_WARNING, "Unable to determine file descriptor for WAV filestream %p: %s\n", fs, strerror(errno));
531  return -1;
532  }
533  if ((cur = ftello(fs->f)) < 0) {
534  ast_log(AST_LOG_WARNING, "Unable to determine current position in WAV filestream %p: %s\n", fs, strerror(errno));
535  return -1;
536  }
537  /* Truncate file to current length */
538  if (ftruncate(fd, cur)) {
539  return -1;
540  }
541  return update_header(fs->f);
542 }
static int update_header(FILE *f)
#define AST_LOG_WARNING
Definition: logger.h:149
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
static int wav_write ( struct ast_filestream s,
struct ast_frame f 
)
static

Definition at line 429 of file format_wav_gsm.c.

References ast_filestream::_private, AST_FORMAT_GSM, AST_FRAME_VOICE, ast_getformatname(), ast_log(), ast_filestream::buf, ast_frame_subclass::codec, conv66(), ast_frame::data, ast_frame::datalen, errno, ast_filestream::f, ast_frame::frametype, GSM_FRAME_SIZE, if(), len(), LOG_WARNING, MSGSM_FRAME_SIZE, ast_frame::ptr, wavg_desc::secondhalf, ast_frame::subclass, and update_header().

430 {
431  int len;
432  int size;
433  struct wavg_desc *fs = (struct wavg_desc *)s->_private;
434 
435  if (f->frametype != AST_FRAME_VOICE) {
436  ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
437  return -1;
438  }
439  if (f->subclass.codec != AST_FORMAT_GSM) {
440  ast_log(LOG_WARNING, "Asked to write non-GSM frame (%s)!\n", ast_getformatname(f->subclass.codec));
441  return -1;
442  }
443  /* XXX this might fail... if the input is a multiple of MSGSM_FRAME_SIZE
444  * we assume it is already in the correct format.
445  */
446  if (!(f->datalen % MSGSM_FRAME_SIZE)) {
447  size = MSGSM_FRAME_SIZE;
448  fs->secondhalf = 0;
449  } else {
450  size = GSM_FRAME_SIZE;
451  }
452  for (len = 0; len < f->datalen ; len += size) {
453  int res;
454  unsigned char *src, msdata[MSGSM_FRAME_SIZE];
455  if (fs->secondhalf) { /* second half of raw gsm to be converted */
456  memcpy(s->buf + GSM_FRAME_SIZE, f->data.ptr + len, GSM_FRAME_SIZE);
457  conv66((unsigned char *) s->buf, msdata);
458  src = msdata;
459  fs->secondhalf = 0;
460  } else if (size == GSM_FRAME_SIZE) { /* first half of raw gsm */
461  memcpy(s->buf, f->data.ptr + len, GSM_FRAME_SIZE);
462  src = NULL; /* nothing to write */
463  fs->secondhalf = 1;
464  } else { /* raw msgsm data */
465  src = f->data.ptr + len;
466  }
467  if (src && (res = fwrite(src, 1, MSGSM_FRAME_SIZE, s->f)) != MSGSM_FRAME_SIZE) {
468  ast_log(LOG_WARNING, "Bad write (%d/65): %s\n", res, strerror(errno));
469  return -1;
470  }
471  update_header(s->f); /* XXX inefficient! */
472  }
473  return 0;
474 }
union ast_frame_subclass subclass
Definition: frame.h:146
static int update_header(FILE *f)
void * ptr
Definition: frame.h:160
#define LOG_WARNING
Definition: logger.h:144
format_t codec
Definition: frame.h:137
#define GSM_FRAME_SIZE
int datalen
Definition: frame.h:148
void * _private
Definition: mod_format.h:119
#define MSGSM_FRAME_SIZE
char * ast_getformatname(format_t format)
Get the name of a format.
Definition: frame.c:578
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
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
static void conv66(gsm_byte *d, wav_byte *c)
Definition: msgsm.h:114
if(yyss+yystacksize-1<=yyssp)
Definition: ast_expr2.c:1874
enum ast_frame_type frametype
Definition: frame.h:144
union ast_frame::@172 data
#define AST_FORMAT_GSM
Definition: frame.h:244
static int write_header ( FILE *  f)
static

Definition at line 258 of file format_wav_gsm.c.

References ast_log(), LOG_WARNING, MSGSM_FRAME_SIZE, and MSGSM_SAMPLES.

Referenced by wav_rewrite().

259 {
260  /* Samples per second (always 8000 for this format). */
261  unsigned int sample_rate = htoll(8000);
262  /* Bytes per second (always 1625 for this format). */
263  unsigned int byte_sample_rate = htoll(1625);
264  /* This is the size of the "fmt " subchunk */
265  unsigned int fmtsize = htoll(20);
266  /* WAV #49 */
267  unsigned short fmt = htols(49);
268  /* Mono = 1 channel */
269  unsigned short chans = htols(1);
270  /* Each block of data is exactly 65 bytes in size. */
271  unsigned int block_align = htoll(MSGSM_FRAME_SIZE);
272  /* Not actually 2, but rounded up to the nearest bit */
273  unsigned short bits_per_sample = htols(2);
274  /* Needed for compressed formats */
275  unsigned short extra_format = htols(MSGSM_SAMPLES);
276  /* This is the size of the "fact" subchunk */
277  unsigned int factsize = htoll(4);
278  /* Number of samples in the data chunk */
279  unsigned int num_samples = htoll(0);
280  /* Number of bytes in the data chunk */
281  unsigned int size = htoll(0);
282  /* Write a GSM header, ignoring sizes which will be filled in later */
283 
284  /* 0: Chunk ID */
285  if (fwrite("RIFF", 1, 4, f) != 4) {
286  ast_log(LOG_WARNING, "Unable to write header\n");
287  return -1;
288  }
289  /* 4: Chunk Size */
290  if (fwrite(&size, 1, 4, f) != 4) {
291  ast_log(LOG_WARNING, "Unable to write header\n");
292  return -1;
293  }
294  /* 8: Chunk Format */
295  if (fwrite("WAVE", 1, 4, f) != 4) {
296  ast_log(LOG_WARNING, "Unable to write header\n");
297  return -1;
298  }
299  /* 12: Subchunk 1: ID */
300  if (fwrite("fmt ", 1, 4, f) != 4) {
301  ast_log(LOG_WARNING, "Unable to write header\n");
302  return -1;
303  }
304  /* 16: Subchunk 1: Size (minus 8) */
305  if (fwrite(&fmtsize, 1, 4, f) != 4) {
306  ast_log(LOG_WARNING, "Unable to write header\n");
307  return -1;
308  }
309  /* 20: Subchunk 1: Audio format (49) */
310  if (fwrite(&fmt, 1, 2, f) != 2) {
311  ast_log(LOG_WARNING, "Unable to write header\n");
312  return -1;
313  }
314  /* 22: Subchunk 1: Number of channels */
315  if (fwrite(&chans, 1, 2, f) != 2) {
316  ast_log(LOG_WARNING, "Unable to write header\n");
317  return -1;
318  }
319  /* 24: Subchunk 1: Sample rate */
320  if (fwrite(&sample_rate, 1, 4, f) != 4) {
321  ast_log(LOG_WARNING, "Unable to write header\n");
322  return -1;
323  }
324  /* 28: Subchunk 1: Byte rate */
325  if (fwrite(&byte_sample_rate, 1, 4, f) != 4) {
326  ast_log(LOG_WARNING, "Unable to write header\n");
327  return -1;
328  }
329  /* 32: Subchunk 1: Block align */
330  if (fwrite(&block_align, 1, 4, f) != 4) {
331  ast_log(LOG_WARNING, "Unable to write header\n");
332  return -1;
333  }
334  /* 36: Subchunk 1: Bits per sample */
335  if (fwrite(&bits_per_sample, 1, 2, f) != 2) {
336  ast_log(LOG_WARNING, "Unable to write header\n");
337  return -1;
338  }
339  /* 38: Subchunk 1: Extra format bytes */
340  if (fwrite(&extra_format, 1, 2, f) != 2) {
341  ast_log(LOG_WARNING, "Unable to write header\n");
342  return -1;
343  }
344  /* 40: Subchunk 2: ID */
345  if (fwrite("fact", 1, 4, f) != 4) {
346  ast_log(LOG_WARNING, "Unable to write header\n");
347  return -1;
348  }
349  /* 44: Subchunk 2: Size (minus 8) */
350  if (fwrite(&factsize, 1, 4, f) != 4) {
351  ast_log(LOG_WARNING, "Unable to write header\n");
352  return -1;
353  }
354  /* 48: Subchunk 2: Number of samples */
355  if (fwrite(&num_samples, 1, 4, f) != 4) {
356  ast_log(LOG_WARNING, "Unable to write header\n");
357  return -1;
358  }
359  /* 52: Subchunk 3: ID */
360  if (fwrite("data", 1, 4, f) != 4) {
361  ast_log(LOG_WARNING, "Unable to write header\n");
362  return -1;
363  }
364  /* 56: Subchunk 3: Size */
365  if (fwrite(&size, 1, 4, f) != 4) {
366  ast_log(LOG_WARNING, "Unable to write header\n");
367  return -1;
368  }
369  return 0;
370 }
#define LOG_WARNING
Definition: logger.h:144
#define MSGSM_SAMPLES
#define MSGSM_FRAME_SIZE
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 struct ast_format f[]
Definition: format_g726.c:181

Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Microsoft WAV format (Proprietary GSM)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND }
static

Definition at line 584 of file format_wav_gsm.c.

Definition at line 584 of file format_wav_gsm.c.

char msgsm_silence[]
static

Definition at line 55 of file format_wav_gsm.c.

struct ast_format wav49_f
static

Definition at line 553 of file format_wav_gsm.c.