Thu Jul 9 13:41:15 2009

Asterisk developer's documentation


codec_gsm.c File Reference

Translate between signed linear and Global System for Mobile Communications (GSM). More...

#include "asterisk.h"
#include "asterisk/translate.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/utils.h"
#include "gsm.h"
#include "../formats/msgsm.h"
#include "slin_gsm_ex.h"
#include "gsm_slin_ex.h"

Go to the source code of this file.

Data Structures

struct  gsm_translator_pvt

Defines

#define BUFFER_SAMPLES   8000
#define GSM_FRAME_LEN   33
#define GSM_SAMPLES   160
#define MSGSM_FRAME_LEN   65

Functions

static void __reg_module (void)
static void __unreg_module (void)
static void gsm_destroy_stuff (struct ast_trans_pvt *pvt)
static int gsm_new (struct ast_trans_pvt *pvt)
static int gsmtolin_framein (struct ast_trans_pvt *pvt, struct ast_frame *f)
 decode and store in outbuf.
static struct ast_framegsmtolin_sample (void)
static int lintogsm_framein (struct ast_trans_pvt *pvt, struct ast_frame *f)
 store samples into working buffer for later decode
static struct ast_framelintogsm_frameout (struct ast_trans_pvt *pvt)
 encode and produce a frame
static struct ast_framelintogsm_sample (void)
static int load_module (void)
static int parse_config (int reload)
static int reload (void)
 standard module glue
static int unload_module (void)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "GSM Coder/Decoder" , .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 = "068e67f60f50dd9ee86464c05884a49d" , .load = load_module, .unload = unload_module, .reload = reload, }
static const struct ast_module_infoast_module_info = &__mod_info
static struct ast_translator gsmtolin
static struct ast_translator lintogsm


Detailed Description

Translate between signed linear and Global System for Mobile Communications (GSM).

Definition in file codec_gsm.c.


Define Documentation

#define BUFFER_SAMPLES   8000

Definition at line 54 of file codec_gsm.c.

#define GSM_FRAME_LEN   33

Definition at line 56 of file codec_gsm.c.

Referenced by gsmtolin_framein(), and lintogsm_frameout().

#define GSM_SAMPLES   160

Definition at line 55 of file codec_gsm.c.

Referenced by gsm_read(), gsm_seek(), gsm_tell(), gsmtolin_framein(), gsmtolin_sample(), lintogsm_frameout(), and wav_read().

#define MSGSM_FRAME_LEN   65

Definition at line 57 of file codec_gsm.c.

Referenced by gsmtolin_framein().


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 286 of file codec_gsm.c.

static void __unreg_module ( void   )  [static]

Definition at line 286 of file codec_gsm.c.

static void gsm_destroy_stuff ( struct ast_trans_pvt pvt  )  [static]

Definition at line 192 of file codec_gsm.c.

References gsm_translator_pvt::gsm, and ast_trans_pvt::pvt.

00193 {
00194    struct gsm_translator_pvt *tmp = pvt->pvt;
00195    if (tmp->gsm)
00196       gsm_destroy(tmp->gsm);
00197 }

static int gsm_new ( struct ast_trans_pvt pvt  )  [static]

Definition at line 64 of file codec_gsm.c.

References gsm_translator_pvt::gsm, and ast_trans_pvt::pvt.

00065 {
00066    struct gsm_translator_pvt *tmp = pvt->pvt;
00067    
00068    return (tmp->gsm = gsm_create()) ? 0 : -1;
00069 }

static int gsmtolin_framein ( struct ast_trans_pvt pvt,
struct ast_frame f 
) [static]

decode and store in outbuf.

Definition at line 102 of file codec_gsm.c.

References ast_log(), BUFFER_SAMPLES, conv65(), ast_trans_pvt::datalen, f, gsm_translator_pvt::gsm, GSM_FRAME_LEN, GSM_SAMPLES, len(), LOG_WARNING, MSGSM_FRAME_LEN, ast_trans_pvt::outbuf, ast_trans_pvt::pvt, and ast_trans_pvt::samples.

00103 {
00104    struct gsm_translator_pvt *tmp = pvt->pvt;
00105    int x;
00106    int16_t *dst = (int16_t *)pvt->outbuf;
00107    /* guess format from frame len. 65 for MSGSM, 33 for regular GSM */
00108    int flen = (f->datalen % MSGSM_FRAME_LEN == 0) ?
00109       MSGSM_FRAME_LEN : GSM_FRAME_LEN;
00110 
00111    for (x=0; x < f->datalen; x += flen) {
00112       unsigned char data[2 * GSM_FRAME_LEN];
00113       unsigned char *src;
00114       int len;
00115       if (flen == MSGSM_FRAME_LEN) {
00116          len = 2*GSM_SAMPLES;
00117          src = data;
00118          /* Translate MSGSM format to Real GSM format before feeding in */
00119          /* XXX what's the point here! we should just work
00120           * on the full format.
00121           */
00122          conv65(f->data + x, data);
00123       } else {
00124          len = GSM_SAMPLES;
00125          src = f->data + x;
00126       }
00127       /* XXX maybe we don't need to check */
00128       if (pvt->samples + len > BUFFER_SAMPLES) {   
00129          ast_log(LOG_WARNING, "Out of buffer space\n");
00130          return -1;
00131       }
00132       if (gsm_decode(tmp->gsm, src, dst + pvt->samples)) {
00133          ast_log(LOG_WARNING, "Invalid GSM data (1)\n");
00134          return -1;
00135       }
00136       pvt->samples += GSM_SAMPLES;
00137       pvt->datalen += 2 * GSM_SAMPLES;
00138       if (flen == MSGSM_FRAME_LEN) {
00139          if (gsm_decode(tmp->gsm, data + GSM_FRAME_LEN, dst + pvt->samples)) {
00140             ast_log(LOG_WARNING, "Invalid GSM data (2)\n");
00141             return -1;
00142          }
00143          pvt->samples += GSM_SAMPLES;
00144          pvt->datalen += 2 * GSM_SAMPLES;
00145       }
00146    }
00147    return 0;
00148 }

static struct ast_frame* gsmtolin_sample ( void   )  [static]

Definition at line 86 of file codec_gsm.c.

References AST_FORMAT_GSM, AST_FRAME_VOICE, f, GSM_SAMPLES, and gsm_slin_ex.

00087 {
00088    static struct ast_frame f;
00089    f.frametype = AST_FRAME_VOICE;
00090    f.subclass = AST_FORMAT_GSM;
00091    f.datalen = sizeof(gsm_slin_ex);
00092    /* All frames are 20 ms long */
00093    f.samples = GSM_SAMPLES;
00094    f.mallocd = 0;
00095    f.offset = 0;
00096    f.src = __PRETTY_FUNCTION__;
00097    f.data = gsm_slin_ex;
00098    return &f;
00099 }

static int lintogsm_framein ( struct ast_trans_pvt pvt,
struct ast_frame f 
) [static]

store samples into working buffer for later decode

Definition at line 151 of file codec_gsm.c.

References ast_log(), gsm_translator_pvt::buf, BUFFER_SAMPLES, f, LOG_WARNING, ast_trans_pvt::pvt, and ast_trans_pvt::samples.

00152 {
00153    struct gsm_translator_pvt *tmp = pvt->pvt;
00154 
00155    /* XXX We should look at how old the rest of our stream is, and if it
00156       is too old, then we should overwrite it entirely, otherwise we can
00157       get artifacts of earlier talk that do not belong */
00158    if (pvt->samples + f->samples > BUFFER_SAMPLES) {
00159       ast_log(LOG_WARNING, "Out of buffer space\n");
00160       return -1;
00161    }
00162    memcpy(tmp->buf + pvt->samples, f->data, f->datalen);
00163    pvt->samples += f->samples;
00164    return 0;
00165 }

static struct ast_frame* lintogsm_frameout ( struct ast_trans_pvt pvt  )  [static]

encode and produce a frame

Definition at line 168 of file codec_gsm.c.

References ast_trans_frameout(), gsm_translator_pvt::buf, gsm_translator_pvt::gsm, GSM_FRAME_LEN, GSM_SAMPLES, ast_trans_pvt::outbuf, ast_trans_pvt::pvt, and ast_trans_pvt::samples.

00169 {
00170    struct gsm_translator_pvt *tmp = pvt->pvt;
00171    int datalen = 0;
00172    int samples = 0;
00173 
00174    /* We can't work on anything less than a frame in size */
00175    if (pvt->samples < GSM_SAMPLES)
00176       return NULL;
00177    while (pvt->samples >= GSM_SAMPLES) {
00178       /* Encode a frame of data */
00179       gsm_encode(tmp->gsm, tmp->buf + samples, (gsm_byte *) pvt->outbuf + datalen);
00180       datalen += GSM_FRAME_LEN;
00181       samples += GSM_SAMPLES;
00182       pvt->samples -= GSM_SAMPLES;
00183    }
00184 
00185    /* Move the data at the end of the buffer to the front */
00186    if (pvt->samples)
00187       memmove(tmp->buf, tmp->buf + samples, pvt->samples * 2);
00188 
00189    return ast_trans_frameout(pvt, datalen, samples);
00190 }

static struct ast_frame* lintogsm_sample ( void   )  [static]

Definition at line 71 of file codec_gsm.c.

References AST_FORMAT_SLINEAR, AST_FRAME_VOICE, f, and slin_gsm_ex.

00072 {
00073    static struct ast_frame f;
00074    f.frametype = AST_FRAME_VOICE;
00075    f.subclass = AST_FORMAT_SLINEAR;
00076    f.datalen = sizeof(slin_gsm_ex);
00077    /* Assume 8000 Hz */
00078    f.samples = sizeof(slin_gsm_ex)/2;
00079    f.mallocd = 0;
00080    f.offset = 0;
00081    f.src = __PRETTY_FUNCTION__;
00082    f.data = slin_gsm_ex;
00083    return &f;
00084 }

static int load_module ( void   )  [static]

Definition at line 266 of file codec_gsm.c.

References AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_register_translator, ast_unregister_translator(), gsmtolin, lintogsm, and parse_config().

00267 {
00268    int res;
00269 
00270    if (parse_config(0))
00271       return AST_MODULE_LOAD_DECLINE;
00272    res = ast_register_translator(&gsmtolin);
00273    if (!res) 
00274       res=ast_register_translator(&lintogsm);
00275    else
00276       ast_unregister_translator(&gsmtolin);
00277    if (res) 
00278       return AST_MODULE_LOAD_FAILURE;
00279    return AST_MODULE_LOAD_SUCCESS;
00280 }

static int parse_config ( int  reload  )  [static]

Definition at line 227 of file codec_gsm.c.

References ast_config_load, ast_true(), ast_variable_browse(), ast_verb, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEUNCHANGED, gsmtolin, ast_translator::useplc, and var.

00228 {
00229    struct ast_variable *var;
00230    struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
00231    struct ast_config *cfg = ast_config_load("codecs.conf", config_flags);
00232    if (cfg == NULL)
00233       return 0;
00234    if (cfg == CONFIG_STATUS_FILEUNCHANGED) 
00235       return 0;
00236    for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
00237           if (!strcasecmp(var->name, "genericplc")) {
00238              gsmtolin.useplc = ast_true(var->value) ? 1 : 0;
00239             ast_verb(3, "codec_gsm: %susing generic PLC\n", gsmtolin.useplc ? "" : "not ");
00240           }
00241    }
00242    ast_config_destroy(cfg);
00243    return 0;
00244 }

static int reload ( void   )  [static]

standard module glue

Definition at line 247 of file codec_gsm.c.

References AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, and parse_config().

00248 {
00249    if (parse_config(1)) {
00250       return AST_MODULE_LOAD_DECLINE;
00251    }
00252    return AST_MODULE_LOAD_SUCCESS;
00253 }

static int unload_module ( void   )  [static]

Definition at line 255 of file codec_gsm.c.

References ast_unregister_translator(), gsmtolin, and lintogsm.

00256 {
00257    int res;
00258 
00259    res = ast_unregister_translator(&lintogsm);
00260    if (!res)
00261       res = ast_unregister_translator(&gsmtolin);
00262 
00263    return res;
00264 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "GSM Coder/Decoder" , .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 = "068e67f60f50dd9ee86464c05884a49d" , .load = load_module, .unload = unload_module, .reload = reload, } [static]

Definition at line 286 of file codec_gsm.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 286 of file codec_gsm.c.

struct ast_translator gsmtolin [static]

Definition at line 199 of file codec_gsm.c.

Referenced by load_module(), parse_config(), and unload_module().

struct ast_translator lintogsm [static]

Definition at line 213 of file codec_gsm.c.

Referenced by load_module(), and unload_module().


Generated on Thu Jul 9 13:41:15 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7