Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:48:54 2009

## Asterisk developer's documentation

# format_wav_gsm.c File Reference

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

`#include <unistd.h>`
`#include <netinet/in.h>`
`#include <arpa/inet.h>`
`#include <stdlib.h>`
`#include <sys/time.h>`
`#include <stdio.h>`
`#include <errno.h>`
`#include <string.h>`
`#include "asterisk.h"`
`#include "asterisk/lock.h"`
`#include "asterisk/channel.h"`
`#include "asterisk/file.h"`
`#include "asterisk/logger.h"`
`#include "asterisk/sched.h"`
`#include "asterisk/module.h"`
`#include "asterisk/endian.h"`
`#include "msgsm.h"`

Include dependency graph for format_wav_gsm.c:

Go to the source code of this file.

## Data Structures

struct | ast_filestream

## Defines

#define | htoll(b) (b)
#define | htols(b) (b)
#define | ltohl(b) (b)
#define | ltohs(b) (b)

## Functions

| AST_MUTEX_DEFINE_STATIC (wav_lock)
static int | check_header (FILE *f)
char * | description ()
| Provides a description of the module.
char * | key ()
| Returns the ASTERISK_GPL_KEY.
int | load_module ()
| Initialize the module.
int | unload_module ()
| Cleanup all module structures, sockets, etc.
static int | update_header (FILE *f)
int | usecount ()
| Provides a usecount.
static void | wav_close (struct ast_filestream *s)
static char * | wav_getcomment (struct ast_filestream *s)
static struct ast_filestream * | wav_open (FILE *f)
static struct ast_frame * | wav_read (struct ast_filestream *s, int *whennext)
static struct ast_filestream * | wav_rewrite (FILE *f, const char *comment)
static int | wav_seek (struct ast_filestream *fs, long sample_offset, int whence)
static long | wav_tell (struct ast_filestream *fs)
static int | wav_trunc (struct ast_filestream *fs)
static int | wav_write (struct ast_filestream *fs, struct ast_frame *f)
static int | write_header (FILE *f)

## Variables

static char * | desc = "Microsoft WAV format (Proprietary GSM)"
static char * | exts = "WAV|wav49"
static int | glistcnt = 0
char | msgsm_silence []
static char * | name = "wav49"

## 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.

## Define Documentation

#define htoll | ( | b |  | ) | (b)

Definition at line 90 of file format_wav_gsm.c.

#define htols | ( | b |  | ) | (b)

Definition at line 91 of file format_wav_gsm.c.

#define ltohl | ( | b |  | ) | (b)

Definition at line 92 of file format_wav_gsm.c.

#define ltohs | ( | b |  | ) | (b)

Definition at line 93 of file format_wav_gsm.c.

## Function Documentation

AST_MUTEX_DEFINE_STATIC | ( | wav_lock |  | ) |

static int check_header | ( | FILE * | f | ) | `[static]`

Definition at line 112 of file format_wav_gsm.c.

References ast_log(), fmt, format, LOG_WARNING, ltohl, ltohs, and type.

    00113 {
    00114    int type, size, formtype;
    00115    int fmt, hsize, fact;
    00116    short format, chans;
    00117    int freq;
    00118    int data;
    00119    if (fread(&type, 1, 4, f) != 4) {
    00120       ast_log(LOG_WARNING, "Read failed (type)\n");
    00121       return -1;
    00122    }
    00123    if (fread(&size, 1, 4, f) != 4) {
    00124       ast_log(LOG_WARNING, "Read failed (size)\n");
    00125       return -1;
    00126    }
    00127    size = ltohl(size);
    00128    if (fread(&formtype, 1, 4, f) != 4) {
    00129       ast_log(LOG_WARNING, "Read failed (formtype)\n");
    00130       return -1;
    00131    }
    00132    if (memcmp(&type, "RIFF", 4)) {
    00133       ast_log(LOG_WARNING, "Does not begin with RIFF\n");
    00134       return -1;
    00135    }
    00136    if (memcmp(&formtype, "WAVE", 4)) {
    00137       ast_log(LOG_WARNING, "Does not contain WAVE\n");
    00138       return -1;
    00139    }
    00140    if (fread(&fmt, 1, 4, f) != 4) {
    00141       ast_log(LOG_WARNING, "Read failed (fmt)\n");
    00142       return -1;
    00143    }
    00144    if (memcmp(&fmt, "fmt ", 4)) {
    00145       ast_log(LOG_WARNING, "Does not say fmt\n");
    00146       return -1;
    00147    }
    00148    if (fread(&hsize, 1, 4, f) != 4) {
    00149       ast_log(LOG_WARNING, "Read failed (formtype)\n");
    00150       return -1;
    00151    }
    00152    if (ltohl(hsize) != 20) {
    00153       ast_log(LOG_WARNING, "Unexpected header size %d\n", ltohl(hsize));
    00154       return -1;
    00155    }
    00156    if (fread(&format, 1, 2, f) != 2) {
    00157       ast_log(LOG_WARNING, "Read failed (format)\n");
    00158       return -1;
    00159    }
    00160    if (ltohs(format) != 49) {
    00161       ast_log(LOG_WARNING, "Not a GSM file %d\n", ltohs(format));
    00162       return -1;
    00163    }
    00164    if (fread(&chans, 1, 2, f) != 2) {
    00165       ast_log(LOG_WARNING, "Read failed (format)\n");
    00166       return -1;
    00167    }
    00168    if (ltohs(chans) != 1) {
    00169       ast_log(LOG_WARNING, "Not in mono %d\n", ltohs(chans));
    00170       return -1;
    00171    }
    00172    if (fread(&freq, 1, 4, f) != 4) {
    00173       ast_log(LOG_WARNING, "Read failed (freq)\n");
    00174       return -1;
    00175    }
    00176    if (ltohl(freq) != 8000) {
    00177       ast_log(LOG_WARNING, "Unexpected freqency %d\n", ltohl(freq));
    00178       return -1;
    00179    }
    00180    /* Ignore the byte frequency */
    00181    if (fread(&freq, 1, 4, f) != 4) {
    00182       ast_log(LOG_WARNING, "Read failed (X_1)\n");
    00183       return -1;
    00184    }
    00185    /* Ignore the two weird fields */
    00186    if (fread(&freq, 1, 4, f) != 4) {
    00187       ast_log(LOG_WARNING, "Read failed (X_2/X_3)\n");
    00188       return -1;
    00189    }
    00190    /* Ignore the byte frequency */
    00191    if (fread(&freq, 1, 4, f) != 4) {
    00192       ast_log(LOG_WARNING, "Read failed (Y_1)\n");
    00193       return -1;
    00194    }
    00195    /* Check for the word fact */
    00196    if (fread(&fact, 1, 4, f) != 4) {
    00197       ast_log(LOG_WARNING, "Read failed (fact)\n");
    00198       return -1;
    00199    }
    00200    if (memcmp(&fact, "fact", 4)) {
    00201       ast_log(LOG_WARNING, "Does not say fact\n");
    00202       return -1;
    00203    }
    00204    /* Ignore the "fact value" */
    00205    if (fread(&fact, 1, 4, f) != 4) {
    00206       ast_log(LOG_WARNING, "Read failed (fact header)\n");
    00207       return -1;
    00208    }
    00209    if (fread(&fact, 1, 4, f) != 4) {
    00210       ast_log(LOG_WARNING, "Read failed (fact value)\n");
    00211       return -1;
    00212    }
    00213    /* Check for the word data */
    00214    if (fread(&data, 1, 4, f) != 4) {
    00215       ast_log(LOG_WARNING, "Read failed (data)\n");
    00216       return -1;
    00217    }
    00218    if (memcmp(&data, "data", 4)) {
    00219       ast_log(LOG_WARNING, "Does not say data\n");
    00220       return -1;
    00221    }
    00222    /* Ignore the data length */
    00223    if (fread(&data, 1, 4, f) != 4) {
    00224       ast_log(LOG_WARNING, "Read failed (data)\n");
    00225       return -1;
    00226    }
    00227    return 0;
    00228 }

char* description | ( | void |  | ) |

Provides a description of the module.

Returns:
  a short description of your module

Definition at line 580 of file format_wav_gsm.c.

    00581 {
    00582    return desc;
    00583 }

char* key | ( | void |  | ) |

Returns the ASTERISK_GPL_KEY.

This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:

     char *key(void) {
             return ASTERISK_GPL_KEY;
     }

Returns:
  ASTERISK_GPL_KEY

Definition at line 586 of file format_wav_gsm.c.

References ASTERISK_GPL_KEY.

    00587 {
    00588    return ASTERISK_GPL_KEY;
    00589 }

int load_module | ( | void |  | ) |

Initialize the module.

This function is called at module load time. Put all code in here that needs to set up your module's hardware, software, registrations, etc.

Returns:
  This function should return 0 on success and non-zero on failure. If the module is not loaded successfully, Asterisk will call its unload_module() function.

Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.

Returns:
  int Always 0.

TE STUFF END

Definition at line 554 of file format_wav_gsm.c.

References AST_FORMAT_GSM, ast_format_register(), wav_close(), wav_getcomment(), wav_open(), wav_read(), wav_rewrite(), wav_seek(), wav_tell(), wav_trunc(), and wav_write().

    00555 {
    00556    return ast_format_register(name, exts, AST_FORMAT_GSM,
    00557                         wav_open,
    00558                         wav_rewrite,
    00559                         wav_write,
    00560                         wav_seek,
    00561                         wav_trunc,
    00562                         wav_tell,
    00563                         wav_read,
    00564                         wav_close,
    00565                         wav_getcomment);
    00566
    00567
    00568 }

int unload_module | ( | void |  | ) |

Cleanup all module structures, sockets, etc.

This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).

Returns:
  Zero on success, or non-zero on error.

Definition at line 570 of file format_wav_gsm.c.

References ast_format_unregister().

    00571 {
    00572    return ast_format_unregister(name);
    00573 }

static int update_header | ( | FILE * | f | ) | `[static]`

Definition at line 230 of file format_wav_gsm.c.

References ast_log(), htoll, and LOG_WARNING.

    00231 {
    00232    off_t cur,end,bytes;
    00233    int datalen,filelen;
    00234
    00235    cur = ftell(f);
    00236    fseek(f, 0, SEEK_END);
    00237    end = ftell(f);
    00238    /* in a gsm WAV, data starts 60 bytes in */
    00239    bytes = end - 60;
    00240    datalen = htoll((bytes + 1) & ~0x1);
    00241    filelen = htoll(52 + ((bytes + 1) & ~0x1));
    00242    if (cur < 0) {
    00243       ast_log(LOG_WARNING, "Unable to find our position\n");
    00244       return -1;
    00245    }
    00246    if (fseek(f, 4, SEEK_SET)) {
    00247       ast_log(LOG_WARNING, "Unable to set our position\n");
    00248       return -1;
    00249    }
    00250    if (fwrite(&filelen, 1, 4, f) != 4) {
    00251       ast_log(LOG_WARNING, "Unable to set write file size\n");
    00252       return -1;
    00253    }
    00254    if (fseek(f, 56, SEEK_SET)) {
    00255       ast_log(LOG_WARNING, "Unable to set our position\n");
    00256       return -1;
    00257    }
    00258    if (fwrite(&datalen, 1, 4, f) != 4) {
    00259       ast_log(LOG_WARNING, "Unable to set write datalen\n");
    00260       return -1;
    00261    }
    00262    if (fseek(f, cur, SEEK_SET)) {
    00263       ast_log(LOG_WARNING, "Unable to return to position\n");
    00264       return -1;
    00265    }
    00266    return 0;
    00267 }

int usecount | ( | void |  | ) |

Provides a usecount.

This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.

Returns:
  The module's usecount.

Definition at line 575 of file format_wav_gsm.c.

    00576 {
    00577    return glistcnt;
    00578 }

static void wav_close | ( | struct ast_filestream * | s | ) | `[static]`

Definition at line 408 of file format_wav_gsm.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_update_use_count(), ast_filestream::f, free, and LOG_WARNING.

    00409 {
    00410    char zero = 0;
    00411    if (ast_mutex_lock(&wav_lock)) {
    00412       ast_log(LOG_WARNING, "Unable to lock wav list\n");
    00413       return;
    00414    }
    00415    glistcnt--;
    00416    ast_mutex_unlock(&wav_lock);
    00417    ast_update_use_count();
    00418    /* Pad to even length */
    00419    fseek(s->f, 0, SEEK_END);
    00420    if (ftell(s->f) & 0x1)
    00421       fwrite(&zero, 1, 1, s->f);
    00422    fclose(s->f);
    00423    free(s);
    00424    s = NULL;
    00425 }

static char* wav_getcomment | ( | struct ast_filestream * | s | ) | `[static]`

Definition at line 549 of file format_wav_gsm.c.

    00550 {
    00551    return NULL;
    00552 }

static struct ast_filestream* wav_open | ( | FILE * | f | ) | `[static, read]`

Definition at line 350 of file format_wav_gsm.c.

References AST_FORMAT_GSM, AST_FRAME_VOICE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_update_use_count(), check_header(), ast_frame::data, ast_filestream::f, ast_filestream::fr, ast_frame::frametype, free, ast_filestream::gsm, LOG_WARNING, malloc, ast_frame::mallocd, ast_filestream::secondhalf, ast_frame::src, and ast_frame::subclass.

    00351 {
    00352    /* We don't have any header to read or anything really, but
    00353       if we did, it would go here.  We also might want to check
    00354       and be sure it's a valid file.  */
    00355    struct ast_filestream *tmp;
    00356    if ((tmp = malloc(sizeof(struct ast_filestream)))) {
    00357       memset(tmp, 0, sizeof(struct ast_filestream));
    00358       if (check_header(f)) {
    00359          free(tmp);
    00360          return NULL;
    00361       }
    00362       if (ast_mutex_lock(&wav_lock)) {
    00363          ast_log(LOG_WARNING, "Unable to lock wav list\n");
    00364          free(tmp);
    00365          return NULL;
    00366       }
    00367       tmp->f = f;
    00368       tmp->fr.data = tmp->gsm;
    00369       tmp->fr.frametype = AST_FRAME_VOICE;
    00370       tmp->fr.subclass = AST_FORMAT_GSM;
    00371       /* datalen will vary for each frame */
    00372       tmp->fr.src = name;
    00373       tmp->fr.mallocd = 0;
    00374       tmp->secondhalf = 0;
    00375       glistcnt++;
    00376       ast_mutex_unlock(&wav_lock);
    00377       ast_update_use_count();
    00378    }
    00379    return tmp;
    00380 }

static struct ast_frame* wav_read | ( | struct ast_filestream * | s,
|  | int * | whennext |
| ) |  |  | `[static, read]`

Definition at line 427 of file format_wav_gsm.c.

References AST_FORMAT_GSM, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), conv65(), ast_frame::data, ast_frame::datalen, ast_filestream::f, ast_filestream::fr, ast_frame::frametype, ast_filestream::gsm, LOG_WARNING, ast_frame::mallocd, ast_frame::offset, ast_frame::samples, ast_filestream::secondhalf, and ast_frame::subclass.

    00428 {
    00429    int res;
    00430    char msdata[66];
    00431    /* Send a frame from the file to the appropriate channel */
    00432
    00433    s->fr.frametype = AST_FRAME_VOICE;
    00434    s->fr.subclass = AST_FORMAT_GSM;
    00435    s->fr.offset = AST_FRIENDLY_OFFSET;
    00436    s->fr.samples = 160;
    00437    s->fr.datalen = 33;
    00438    s->fr.mallocd = 0;
    00439    if (s->secondhalf) {
    00440       /* Just return a frame based on the second GSM frame */
    00441       s->fr.data = s->gsm + 33;
    00442    } else {
    00443       if ((res = fread(msdata, 1, 65, s->f)) != 65) {
    00444          if (res && (res != 1))
    00445             ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
    00446          return NULL;
    00447       }
    00448       /* Convert from MS format to two real GSM frames */
    00449       conv65(msdata, s->gsm);
    00450       s->fr.data = s->gsm;
    00451    }
    00452    s->secondhalf = !s->secondhalf;
    00453    *whennext = 160;
    00454    return &s->fr;
    00455 }

static struct ast_filestream* wav_rewrite | ( | FILE * | f,
|  | const char * | comment |
| ) |  |  | `[static, read]`

Definition at line 382 of file format_wav_gsm.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_update_use_count(), ast_filestream::f, free, LOG_WARNING, malloc, and write_header().

    00383 {
    00384    /* We don't have any header to read or anything really, but
    00385       if we did, it would go here.  We also might want to check
    00386       and be sure it's a valid file.  */
    00387    struct ast_filestream *tmp;
    00388    if ((tmp = malloc(sizeof(struct ast_filestream)))) {
    00389       memset(tmp, 0, sizeof(struct ast_filestream));
    00390       if (write_header(f)) {
    00391          free(tmp);
    00392          return NULL;
    00393       }
    00394       if (ast_mutex_lock(&wav_lock)) {
    00395          ast_log(LOG_WARNING, "Unable to lock wav list\n");
    00396          free(tmp);
    00397          return NULL;
    00398       }
    00399       tmp->f = f;
    00400       glistcnt++;
    00401       ast_mutex_unlock(&wav_lock);
    00402       ast_update_use_count();
    00403    } else
    00404       ast_log(LOG_WARNING, "Out of memory\n");
    00405    return tmp;
    00406 }

static int wav_seek | ( | struct ast_filestream * | fs,
|  | long | sample_offset,
|  | int | whence |
| ) |  |  | `[static]`

Definition at line 502 of file format_wav_gsm.c.

References ast_filestream::f, offset, ast_filestream::secondhalf, and SEEK_FORCECUR.

    00503 {
    00504    off_t offset=0,distance,cur,min,max;
    00505    min = 60;
    00506    cur = ftell(fs->f);
    00507    fseek(fs->f, 0, SEEK_END);
    00508    max = ftell(fs->f);
    00509    /* I'm getting sloppy here, I'm only going to go to even splits of the 2
    00510     * frames, if you want tighter cuts use format_gsm, format_pcm, or format_wav */
    00511    distance = (sample_offset/320) * 65;
    00512    if(whence == SEEK_SET)
    00513       offset = distance + min;
    00514    else if(whence == SEEK_CUR || whence == SEEK_FORCECUR)
    00515       offset = distance + cur;
    00516    else if(whence == SEEK_END)
    00517       offset = max - distance;
    00518    /* always protect against seeking past end of header */
    00519    offset = (offset < min)?min:offset;
    00520    if (whence != SEEK_FORCECUR) {
    00521       offset = (offset > max)?max:offset;
    00522    } else if (offset > max) {
    00523       int i;
    00524       fseek(fs->f, 0, SEEK_END);
    00525       for (i=0; i< (offset - max) / 65; i++) {
    00526          fwrite(msgsm_silence, 1, 65, fs->f);
    00527       }
    00528    }
    00529    fs->secondhalf = 0;
    00530    return fseek(fs->f, offset, SEEK_SET);
    00531 }

static long wav_tell | ( | struct ast_filestream * | fs | ) | `[static]`

Definition at line 540 of file format_wav_gsm.c.

References ast_filestream::f, and offset.

    00541 {
    00542    off_t offset;
    00543    offset = ftell(fs->f);
    00544    /* since this will most likely be used later in play or record, lets stick
    00545     * to that level of resolution, just even frames boundaries */
    00546    return (offset - 52)/65*320;
    00547 }

static int wav_trunc | ( | struct ast_filestream * | fs | ) | `[static]`

Definition at line 533 of file format_wav_gsm.c.

References ast_filestream::f, and update_header().

    00534 {
    00535    if (ftruncate(fileno(fs->f), ftell(fs->f)))
    00536       return -1;
    00537    return update_header(fs->f);
    00538 }

static int wav_write | ( | struct ast_filestream * | fs,
|  | struct ast_frame * | f |
| ) |  |  | `[static]`

Definition at line 457 of file format_wav_gsm.c.

References AST_FORMAT_GSM, AST_FRAME_VOICE, ast_log(), conv66(), ast_frame::data, ast_frame::datalen, ast_filestream::f, ast_frame::frametype, ast_filestream::gsm, LOG_WARNING, ast_filestream::secondhalf, ast_frame::subclass, and update_header().

    00458 {
    00459    int res;
    00460    char msdata[66];
    00461    int len =0;
    00462    int alreadyms=0;
    00463    if (f->frametype != AST_FRAME_VOICE) {
    00464       ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
    00465       return -1;
    00466    }
    00467    if (f->subclass != AST_FORMAT_GSM) {
    00468       ast_log(LOG_WARNING, "Asked to write non-GSM frame (%d)!\n", f->subclass);
    00469       return -1;
    00470    }
    00471    if (!(f->datalen % 65))
    00472       alreadyms = 1;
    00473    while(len < f->datalen) {
    00474       if (alreadyms) {
    00475          fs->secondhalf = 0;
    00476          if ((res = fwrite(f->data + len, 1, 65, fs->f)) != 65) {
    00477             ast_log(LOG_WARNING, "Bad write (%d/65): %s\n", res, strerror(errno));
    00478             return -1;
    00479          }
    00480          update_header(fs->f);
    00481          len += 65;
    00482       } else {
    00483          if (fs->secondhalf) {
    00484             memcpy(fs->gsm + 33, f->data + len, 33);
    00485             conv66(fs->gsm, msdata);
    00486             if ((res = fwrite(msdata, 1, 65, fs->f)) != 65) {
    00487                ast_log(LOG_WARNING, "Bad write (%d/65): %s\n", res, strerror(errno));
    00488                return -1;
    00489             }
    00490             update_header(fs->f);
    00491          } else {
    00492             /* Copy the data and do nothing */
    00493             memcpy(fs->gsm, f->data + len, 33);
    00494          }
    00495          fs->secondhalf = !fs->secondhalf;
    00496          len += 33;
    00497       }
    00498    }
    00499    return 0;
    00500 }

static int write_header | ( | FILE * | f | ) | `[static]`

Definition at line 269 of file format_wav_gsm.c.

References ast_log(), fmt, htoll, htols, and LOG_WARNING.

    00270 {
    00271    unsigned int hz=htoll(8000);
    00272    unsigned int bhz = htoll(1625);
    00273    unsigned int hs = htoll(20);
    00274    unsigned short fmt = htols(49);
    00275    unsigned short chans = htols(1);
    00276    unsigned int fhs = htoll(4);
    00277    unsigned int x_1 = htoll(65);
    00278    unsigned short x_2 = htols(2);
    00279    unsigned short x_3 = htols(320);
    00280    unsigned int y_1 = htoll(20160);
    00281    unsigned int size = htoll(0);
    00282    /* Write a GSM header, ignoring sizes which will be filled in later */
    00283    if (fwrite("RIFF", 1, 4, f) != 4) {
    00284       ast_log(LOG_WARNING, "Unable to write header\n");
    00285       return -1;
    00286    }
    00287    if (fwrite(&size, 1, 4, f) != 4) {
    00288       ast_log(LOG_WARNING, "Unable to write header\n");
    00289       return -1;
    00290    }
    00291    if (fwrite("WAVEfmt ", 1, 8, f) != 8) {
    00292       ast_log(LOG_WARNING, "Unable to write header\n");
    00293       return -1;
    00294    }
    00295    if (fwrite(&hs, 1, 4, f) != 4) {
    00296       ast_log(LOG_WARNING, "Unable to write header\n");
    00297       return -1;
    00298    }
    00299    if (fwrite(&fmt, 1, 2, f) != 2) {
    00300       ast_log(LOG_WARNING, "Unable to write header\n");
    00301       return -1;
    00302    }
    00303    if (fwrite(&chans, 1, 2, f) != 2) {
    00304       ast_log(LOG_WARNING, "Unable to write header\n");
    00305       return -1;
    00306    }
    00307    if (fwrite(&hz, 1, 4, f) != 4) {
    00308       ast_log(LOG_WARNING, "Unable to write header\n");
    00309       return -1;
    00310    }
    00311    if (fwrite(&bhz, 1, 4, f) != 4) {
    00312       ast_log(LOG_WARNING, "Unable to write header\n");
    00313       return -1;
    00314    }
    00315    if (fwrite(&x_1, 1, 4, f) != 4) {
    00316       ast_log(LOG_WARNING, "Unable to write header\n");
    00317       return -1;
    00318    }
    00319    if (fwrite(&x_2, 1, 2, f) != 2) {
    00320       ast_log(LOG_WARNING, "Unable to write header\n");
    00321       return -1;
    00322    }
    00323    if (fwrite(&x_3, 1, 2, f) != 2) {
    00324       ast_log(LOG_WARNING, "Unable to write header\n");
    00325       return -1;
    00326    }
    00327    if (fwrite("fact", 1, 4, f) != 4) {
    00328       ast_log(LOG_WARNING, "Unable to write header\n");
    00329       return -1;
    00330    }
    00331    if (fwrite(&fhs, 1, 4, f) != 4) {
    00332       ast_log(LOG_WARNING, "Unable to write header\n");
    00333       return -1;
    00334    }
    00335    if (fwrite(&y_1, 1, 4, f) != 4) {
    00336       ast_log(LOG_WARNING, "Unable to write header\n");
    00337       return -1;
    00338    }
    00339    if (fwrite("data", 1, 4, f) != 4) {
    00340       ast_log(LOG_WARNING, "Unable to write header\n");
    00341       return -1;
    00342    }
    00343    if (fwrite(&size, 1, 4, f) != 4) {
    00344       ast_log(LOG_WARNING, "Unable to write header\n");
    00345       return -1;
    00346    }
    00347    return 0;
    00348 }

## Variable Documentation

char* desc = "Microsoft WAV format (Proprietary GSM)"`[static]`

Definition at line 86 of file format_wav_gsm.c.

char* exts = "WAV|wav49"`[static]`

Definition at line 87 of file format_wav_gsm.c.

int glistcnt = 0`[static]`

Definition at line 83 of file format_wav_gsm.c.

char msgsm_silence[]

Definition at line 58 of file format_wav_gsm.c.

char* name = "wav49"`[static]`

Definition at line 85 of file format_wav_gsm.c.