Fri Sep 25 19:28:35 2009

Asterisk developer's documentation


format_gsm.c File Reference

Save to raw, headerless GSM data. More...

#include "asterisk.h"
#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/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_gsm.c:

Go to the source code of this file.

Defines

#define GSM_FRAME_SIZE   33
#define GSM_SAMPLES   160

Functions

 AST_MODULE_INFO_STANDARD (ASTERISK_GPL_KEY,"Raw GSM data")
static struct ast_framegsm_read (struct ast_filestream *s, int *whennext)
static int gsm_seek (struct ast_filestream *fs, off_t sample_offset, int whence)
static off_t gsm_tell (struct ast_filestream *fs)
static int gsm_trunc (struct ast_filestream *fs)
static int gsm_write (struct ast_filestream *fs, struct ast_frame *f)
static int load_module (void)
static int unload_module (void)

Variables

static struct ast_format gsm_f
char gsm_silence []


Detailed Description

Save to raw, headerless GSM data.

Definition in file format_gsm.c.


Define Documentation

#define GSM_FRAME_SIZE   33

Definition at line 53 of file format_gsm.c.

Referenced by gsm_read(), gsm_seek(), gsm_tell(), gsm_write(), wav_read(), and wav_write().

#define GSM_SAMPLES   160

Definition at line 54 of file format_gsm.c.


Function Documentation

AST_MODULE_INFO_STANDARD ( ASTERISK_GPL_KEY  ,
"Raw GSM data"   
)

static struct ast_frame* gsm_read ( struct ast_filestream s,
int *  whennext 
) [static, read]

Definition at line 64 of file format_gsm.c.

References AST_FORMAT_GSM, AST_FRAME_SET_BUFFER, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), ast_filestream::buf, ast_frame::data, errno, ast_filestream::f, ast_filestream::fr, ast_frame::frametype, GSM_FRAME_SIZE, GSM_SAMPLES, LOG_WARNING, ast_frame::mallocd, ast_frame::samples, and ast_frame::subclass.

00065 {
00066    int res;
00067 
00068    s->fr.frametype = AST_FRAME_VOICE;
00069    s->fr.subclass = AST_FORMAT_GSM;
00070    AST_FRAME_SET_BUFFER(&(s->fr), s->buf, AST_FRIENDLY_OFFSET, GSM_FRAME_SIZE)
00071    s->fr.mallocd = 0;
00072    if ((res = fread(s->fr.data, 1, GSM_FRAME_SIZE, s->f)) != GSM_FRAME_SIZE) {
00073       if (res)
00074          ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
00075       return NULL;
00076    }
00077    *whennext = s->fr.samples = GSM_SAMPLES;
00078    return &s->fr;
00079 }

static int gsm_seek ( struct ast_filestream fs,
off_t  sample_offset,
int  whence 
) [static]

Definition at line 118 of file format_gsm.c.

References ast_filestream::f, GSM_FRAME_SIZE, GSM_SAMPLES, offset, and SEEK_FORCECUR.

00119 {
00120    off_t offset=0,min,cur,max,distance;
00121    
00122    min = 0;
00123    cur = ftello(fs->f);
00124    fseeko(fs->f, 0, SEEK_END);
00125    max = ftello(fs->f);
00126    /* have to fudge to frame here, so not fully to sample */
00127    distance = (sample_offset/GSM_SAMPLES) * GSM_FRAME_SIZE;
00128    if(whence == SEEK_SET)
00129       offset = distance;
00130    else if(whence == SEEK_CUR || whence == SEEK_FORCECUR)
00131       offset = distance + cur;
00132    else if(whence == SEEK_END)
00133       offset = max - distance;
00134    /* Always protect against seeking past the begining. */
00135    offset = (offset < min)?min:offset;
00136    if (whence != SEEK_FORCECUR) {
00137       offset = (offset > max)?max:offset;
00138    } else if (offset > max) {
00139       int i;
00140       fseeko(fs->f, 0, SEEK_END);
00141       for (i=0; i< (offset - max) / GSM_FRAME_SIZE; i++) {
00142          fwrite(gsm_silence, 1, GSM_FRAME_SIZE, fs->f);
00143       }
00144    }
00145    return fseeko(fs->f, offset, SEEK_SET);
00146 }

static off_t gsm_tell ( struct ast_filestream fs  )  [static]

Definition at line 153 of file format_gsm.c.

References ast_filestream::f, GSM_FRAME_SIZE, GSM_SAMPLES, and offset.

00154 {
00155    off_t offset = ftello(fs->f);
00156    return (offset/GSM_FRAME_SIZE)*GSM_SAMPLES;
00157 }

static int gsm_trunc ( struct ast_filestream fs  )  [static]

Definition at line 148 of file format_gsm.c.

References ast_filestream::f.

00149 {
00150    return ftruncate(fileno(fs->f), ftello(fs->f));
00151 }

static int gsm_write ( struct ast_filestream fs,
struct ast_frame f 
) [static]

Definition at line 81 of file format_gsm.c.

References AST_FORMAT_GSM, AST_FRAME_VOICE, ast_log(), conv65(), ast_frame::data, ast_frame::datalen, errno, ast_filestream::f, ast_frame::frametype, GSM_FRAME_SIZE, len, LOG_WARNING, and ast_frame::subclass.

00082 {
00083    int res;
00084    unsigned char gsm[2*GSM_FRAME_SIZE];
00085 
00086    if (f->frametype != AST_FRAME_VOICE) {
00087       ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
00088       return -1;
00089    }
00090    if (f->subclass != AST_FORMAT_GSM) {
00091       ast_log(LOG_WARNING, "Asked to write non-GSM frame (%d)!\n", f->subclass);
00092       return -1;
00093    }
00094    if (!(f->datalen % 65)) {
00095       /* This is in MSGSM format, need to be converted */
00096       int len=0;
00097       while(len < f->datalen) {
00098          conv65(f->data + len, gsm);
00099          if ((res = fwrite(gsm, 1, 2*GSM_FRAME_SIZE, fs->f)) != 2*GSM_FRAME_SIZE) {
00100             ast_log(LOG_WARNING, "Bad write (%d/66): %s\n", res, strerror(errno));
00101             return -1;
00102          }
00103          len += 65;
00104       }
00105    } else {
00106       if (f->datalen % GSM_FRAME_SIZE) {
00107          ast_log(LOG_WARNING, "Invalid data length, %d, should be multiple of 33\n", f->datalen);
00108          return -1;
00109       }
00110       if ((res = fwrite(f->data, 1, f->datalen, fs->f)) != f->datalen) {
00111             ast_log(LOG_WARNING, "Bad write (%d/33): %s\n", res, strerror(errno));
00112             return -1;
00113       }
00114    }
00115    return 0;
00116 }

static int load_module ( void   )  [static]

Definition at line 171 of file format_gsm.c.

References ast_format_register.

00172 {
00173    return ast_format_register(&gsm_f);
00174 }

static int unload_module ( void   )  [static]

Definition at line 176 of file format_gsm.c.

References ast_format_unregister(), and ast_format::name.

00177 {
00178    return ast_format_unregister(gsm_f.name);
00179 }  


Variable Documentation

struct ast_format gsm_f [static]

Definition at line 159 of file format_gsm.c.

char gsm_silence[]

Initial value:

 
{0xD8,0x20,0xA2,0xE1,0x5A,0x50,0x00,0x49,0x24,0x92,0x49,0x24,0x50,0x00,0x49
,0x24,0x92,0x49,0x24,0x50,0x00,0x49,0x24,0x92,0x49,0x24,0x50,0x00,0x49,0x24
,0x92,0x49,0x24}

Definition at line 58 of file format_gsm.c.


Generated on Fri Sep 25 19:28:35 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.5