Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Macros | Functions | Variables
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 "asterisk/format_cache.h"
#include "msgsm.h"
Include dependency graph for format_wav_gsm.c:

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)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int check_header (FILE *f)
 
static int load_module (void)
 
static int unload_module (void)
 
static int update_header (FILE *f)
 
static void wav_close (struct ast_filestream *s)
 
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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static char msgsm_silence []
 
static struct ast_format_def wav49_f
 

Detailed Description

Save GSM in the proprietary Microsoft format.

Microsoft WAV format (Proprietary GSM)

Definition in file format_wav_gsm.c.

Macro Definition Documentation

◆ GSM_FRAME_SIZE

#define GSM_FRAME_SIZE   33

Definition at line 47 of file format_wav_gsm.c.

Referenced by wav_read(), and wav_write().

◆ GSM_SAMPLES

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

Definition at line 50 of file format_wav_gsm.c.

Referenced by wav_read().

◆ MSGSM_DATA_OFFSET

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

Definition at line 49 of file format_wav_gsm.c.

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

◆ MSGSM_FRAME_SIZE

#define MSGSM_FRAME_SIZE   65

Definition at line 48 of file format_wav_gsm.c.

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

◆ MSGSM_SAMPLES

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

Definition at line 51 of file format_wav_gsm.c.

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

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 588 of file format_wav_gsm.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 588 of file format_wav_gsm.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 588 of file format_wav_gsm.c.

◆ check_header()

static int check_header ( FILE *  f)
static

Definition at line 91 of file format_wav_gsm.c.

References ast_log, chans, DEFAULT_SAMPLE_RATE, format, LOG_WARNING, and type.

Referenced by wav_open().

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 }
static const char type[]
Definition: chan_ooh323.c:109
#define DEFAULT_SAMPLE_RATE
Definition: asterisk.h:46
#define LOG_WARNING
Definition: logger.h:274
#define ast_log
Definition: astobj2.c:42
static snd_pcm_format_t format
Definition: chan_alsa.c:102
static struct chans chans

◆ load_module()

static int load_module ( void  )
static

Definition at line 570 of file format_wav_gsm.c.

References ast_format_def_register, ast_format_gsm, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, and ast_format_def::format.

Referenced by unload_module().

571 {
576 }
#define ast_format_def_register(f)
Definition: mod_format.h:136
struct ast_format * ast_format_gsm
Built-in cached gsm format.
Definition: format_cache.c:101
struct ast_format * format
Definition: mod_format.h:48
static struct ast_format_def wav49_f
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 578 of file format_wav_gsm.c.

References ast_format_def_unregister(), AST_MODFLAG_LOAD_ORDER, AST_MODPRI_APP_DEPEND, AST_MODULE_INFO(), AST_MODULE_SUPPORT_CORE, ASTERISK_GPL_KEY, load_module(), and ast_format_def::name.

579 {
581 }
int ast_format_def_unregister(const char *name)
Unregisters a file format.
Definition: file.c:162
static struct ast_format_def wav49_f
char name[80]
Definition: mod_format.h:44

◆ update_header()

static int update_header ( FILE *  f)
static

Definition at line 211 of file format_wav_gsm.c.

References ast_log, end, LOG_WARNING, MSGSM_DATA_OFFSET, MSGSM_FRAME_SIZE, and MSGSM_SAMPLES.

Referenced by wav_close(), and wav_trunc().

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 }
#define LOG_WARNING
Definition: logger.h:274
#define MSGSM_SAMPLES
#define MSGSM_DATA_OFFSET
char * end
Definition: eagi_proxy.c:73
#define ast_log
Definition: astobj2.c:42
int bytes
Definition: format_wav.c:50
#define MSGSM_FRAME_SIZE

◆ wav_close()

static void wav_close ( struct ast_filestream s)
static

Definition at line 397 of file format_wav_gsm.c.

References ast_filestream::f, ast_filestream::filename, ast_filestream::mode, and update_header().

398 {
399  if (s->mode == O_RDONLY) {
400  return;
401  }
402 
403  if (s->filename) {
404  update_header(s->f);
405  }
406 }
static int update_header(FILE *f)
char * filename
Definition: mod_format.h:107

◆ wav_open()

static int wav_open ( struct ast_filestream s)
static

Definition at line 373 of file format_wav_gsm.c.

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

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 }
if(!yyg->yy_init)
Definition: ast_expr2f.c:868
static int check_header(FILE *f)
void * _private
Definition: mod_format.h:124

◆ wav_read()

static struct ast_frame* wav_read ( struct ast_filestream s,
int *  whennext 
)
static

Definition at line 408 of file format_wav_gsm.c.

References ast_filestream::_private, ast_format_get_name(), AST_FRAME_SET_BUFFER, AST_FRIENDLY_OFFSET, ast_log, ast_filestream::buf, conv65(), ast_frame::data, errno, ast_filestream::f, ast_frame_subclass::format, ast_filestream::fr, GSM_FRAME_SIZE, GSM_SAMPLES, LOG_WARNING, MSGSM_FRAME_SIZE, NULL, ast_frame::offset, ast_frame::ptr, ast_frame::samples, wavg_desc::secondhalf, and ast_frame::subclass.

409 {
410  /* Send a frame from the file to the appropriate channel */
411  struct wavg_desc *fs = (struct wavg_desc *)s->_private;
412 
413  s->fr.samples = GSM_SAMPLES;
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;
418  s->fr.offset += 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 }
#define LOG_WARNING
Definition: logger.h:274
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
#define NULL
Definition: resample.c:96
struct ast_frame_subclass subclass
#define GSM_FRAME_SIZE
#define ast_log
Definition: astobj2.c:42
#define AST_FRIENDLY_OFFSET
Offset into a frame&#39;s data buffer.
struct ast_frame fr
frame produced by read, typically
Definition: mod_format.h:122
static void conv65(wav_byte *c, gsm_byte *d)
Definition: msgsm.h:457
void * _private
Definition: mod_format.h:124
#define MSGSM_FRAME_SIZE
#define AST_FRAME_SET_BUFFER(fr, _base, _ofs, _datalen)
int errno
#define GSM_SAMPLES
union ast_frame::@263 data
struct ast_format * format

◆ wav_rewrite()

static int wav_rewrite ( struct ast_filestream s,
const char *  comment 
)
static

Definition at line 386 of file format_wav_gsm.c.

References ast_filestream::f, and write_header().

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 }
static int write_header(FILE *f)

◆ wav_seek()

static int wav_seek ( struct ast_filestream fs,
off_t  sample_offset,
int  whence 
)
static

Definition at line 478 of file format_wav_gsm.c.

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

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 }
#define LOG_WARNING
Definition: logger.h:274
#define AST_LOG_WARNING
Definition: logger.h:279
if(!yyg->yy_init)
Definition: ast_expr2f.c:868
#define MSGSM_SAMPLES
#define MSGSM_DATA_OFFSET
#define ast_log
Definition: astobj2.c:42
void * _private
Definition: mod_format.h:124
#define MSGSM_FRAME_SIZE
int errno
#define SEEK_FORCECUR
Definition: file.h:51
static char msgsm_silence[]
#define min(a, b)
Definition: f2c.h:197
#define max(a, b)
Definition: f2c.h:198

◆ wav_tell()

static off_t wav_tell ( struct ast_filestream fs)
static

Definition at line 546 of file format_wav_gsm.c.

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

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 }
#define MSGSM_SAMPLES
#define MSGSM_DATA_OFFSET
#define MSGSM_FRAME_SIZE

◆ wav_trunc()

static int wav_trunc ( struct ast_filestream fs)
static

Definition at line 526 of file format_wav_gsm.c.

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

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 }
static int update_header(FILE *f)
#define AST_LOG_WARNING
Definition: logger.h:279
#define ast_log
Definition: astobj2.c:42
int errno

◆ wav_write()

static int wav_write ( struct ast_filestream s,
struct ast_frame f 
)
static

Definition at line 440 of file format_wav_gsm.c.

References ast_filestream::_private, ast_log, ast_filestream::buf, conv66(), ast_frame::data, ast_frame::datalen, errno, ast_filestream::f, GSM_FRAME_SIZE, if(), len(), LOG_WARNING, MSGSM_FRAME_SIZE, NULL, ast_frame::ptr, and wavg_desc::secondhalf.

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 }
#define LOG_WARNING
Definition: logger.h:274
if(!yyg->yy_init)
Definition: ast_expr2f.c:868
#define NULL
Definition: resample.c:96
#define GSM_FRAME_SIZE
#define ast_log
Definition: astobj2.c:42
void * _private
Definition: mod_format.h:124
#define MSGSM_FRAME_SIZE
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int errno
static void conv66(gsm_byte *d, wav_byte *c)
Definition: msgsm.h:116
union ast_frame::@263 data

◆ write_header()

static int write_header ( FILE *  f)
static

Definition at line 259 of file format_wav_gsm.c.

References ast_log, LOG_WARNING, MSGSM_FRAME_SIZE, and MSGSM_SAMPLES.

Referenced by wav_rewrite().

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 }
#define LOG_WARNING
Definition: logger.h:274
#define MSGSM_SAMPLES
#define ast_log
Definition: astobj2.c:42
#define MSGSM_FRAME_SIZE
Definition: astman.c:88

Variable Documentation

◆ __mod_info

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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND }
static

Definition at line 588 of file format_wav_gsm.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 588 of file format_wav_gsm.c.

◆ msgsm_silence

char msgsm_silence[]
static

Definition at line 54 of file format_wav_gsm.c.

Referenced by wav_seek().

◆ wav49_f

struct ast_format_def wav49_f
static

Definition at line 555 of file format_wav_gsm.c.