Wed Oct 28 11:52:10 2009

Asterisk developer's documentation


codec_adpcm.c File Reference

codec_adpcm.c - translate between signed linear and Dialogic ADPCM More...

#include "asterisk.h"
#include "asterisk/lock.h"
#include "asterisk/linkedlists.h"
#include "asterisk/module.h"
#include "asterisk/config.h"
#include "asterisk/translate.h"
#include "asterisk/utils.h"
#include "slin_adpcm_ex.h"
#include "adpcm_slin_ex.h"

Include dependency graph for codec_adpcm.c:

Go to the source code of this file.

Data Structures

struct  adpcm_decoder_pvt
 Workspace for translating ADPCM signals to signed linear. More...
struct  adpcm_encoder_pvt
 Workspace for translating signed linear signals to ADPCM. More...
struct  adpcm_state

Defines

#define BUFFER_SAMPLES   8096

Functions

static void __reg_module (void)
static void __unreg_module (void)
static int adpcm (short csig, struct adpcm_state *state)
static int adpcmtolin_framein (struct ast_trans_pvt *pvt, struct ast_frame *f)
 decode 4-bit adpcm frame data and store in output buffer
static struct ast_frameadpcmtolin_sample (void)
 AdpcmToLin_Sample.
static short decode (int encoded, struct adpcm_state *state)
static int lintoadpcm_framein (struct ast_trans_pvt *pvt, struct ast_frame *f)
 fill input buffer with 16-bit signed linear PCM values.
static struct ast_framelintoadpcm_frameout (struct ast_trans_pvt *pvt)
 convert inbuf and store into frame
static struct ast_framelintoadpcm_sample (void)
 LinToAdpcm_Sample.
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 = "Adaptive Differential PCM 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 = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, }
static struct ast_translator adpcmtolin
static struct ast_module_infoast_module_info = &__mod_info
static int indsft [8] = { -1, -1, -1, -1, 2, 4, 6, 8 }
static struct ast_translator lintoadpcm
static int stpsz [49]


Detailed Description

codec_adpcm.c - translate between signed linear and Dialogic ADPCM

Definition in file codec_adpcm.c.


Define Documentation

#define BUFFER_SAMPLES   8096

Definition at line 44 of file codec_adpcm.c.


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 400 of file codec_adpcm.c.

static void __unreg_module ( void   )  [static]

Definition at line 400 of file codec_adpcm.c.

static int adpcm ( short  csig,
struct adpcm_state state 
) [inline, static]

Definition at line 163 of file codec_adpcm.c.

References decode(), adpcm_state::signal, and adpcm_state::ssindex.

Referenced by lintoadpcm_frameout().

00164 {
00165    int diff;
00166    int step;
00167    int encoded;
00168 
00169    /* 
00170     * Clip csig if too large or too small
00171     */
00172    csig >>= 4;
00173 
00174    step = stpsz[state->ssindex];
00175    diff = csig - state->signal;
00176 
00177 #ifdef NOT_BLI
00178    if (diff < 0) {
00179       encoded = (-diff << 2) / step;
00180       if (encoded > 7)
00181          encoded = 7;
00182       encoded |= 0x08;
00183    } else {
00184       encoded = (diff << 2) / step;
00185       if (encoded > 7)
00186          encoded = 7;
00187    }
00188 #else /* BLI code */
00189    if (diff < 0) {
00190       encoded = 8;
00191       diff = -diff;
00192    } else
00193       encoded = 0;
00194    if (diff >= step) {
00195       encoded |= 4;
00196       diff -= step;
00197    }
00198    step >>= 1;
00199    if (diff >= step) {
00200       encoded |= 2;
00201       diff -= step;
00202    }
00203    step >>= 1;
00204    if (diff >= step)
00205       encoded |= 1;
00206 #endif /* NOT_BLI */
00207 
00208    /* feedback to state */
00209    decode(encoded, state);
00210    
00211    return encoded;
00212 }

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

decode 4-bit adpcm frame data and store in output buffer

Definition at line 228 of file codec_adpcm.c.

References ast_frame::data, ast_trans_pvt::datalen, ast_frame::datalen, decode(), ast_trans_pvt::i16, ast_trans_pvt::outbuf, ast_frame::ptr, ast_trans_pvt::pvt, ast_frame::samples, ast_trans_pvt::samples, and adpcm_decoder_pvt::state.

00229 {
00230    struct adpcm_decoder_pvt *tmp = pvt->pvt;
00231    int x = f->datalen;
00232    unsigned char *src = f->data.ptr;
00233    int16_t *dst = pvt->outbuf.i16 + pvt->samples;
00234 
00235    while (x--) {
00236       *dst++ = decode((*src >> 4) & 0xf, &tmp->state);
00237       *dst++ = decode(*src++ & 0x0f, &tmp->state);
00238    }
00239    pvt->samples += f->samples;
00240    pvt->datalen += 2*f->samples;
00241    return 0;
00242 }

static struct ast_frame* adpcmtolin_sample ( void   )  [static, read]

AdpcmToLin_Sample.

Definition at line 289 of file codec_adpcm.c.

References adpcm_slin_ex, AST_FORMAT_ADPCM, AST_FRAME_VOICE, ast_frame::data, ast_frame::datalen, ast_frame::frametype, ast_frame::mallocd, ast_frame::offset, ast_frame::ptr, ast_frame::samples, ast_frame::src, and ast_frame::subclass.

00290 {
00291    static struct ast_frame f;
00292    f.frametype = AST_FRAME_VOICE;
00293    f.subclass = AST_FORMAT_ADPCM;
00294    f.datalen = sizeof(adpcm_slin_ex);
00295    f.samples = sizeof(adpcm_slin_ex) * 2;
00296    f.mallocd = 0;
00297    f.offset = 0;
00298    f.src = __PRETTY_FUNCTION__;
00299    f.data.ptr = adpcm_slin_ex;
00300    return &f;
00301 }

static short decode ( int  encoded,
struct adpcm_state state 
) [inline, static]

Definition at line 90 of file codec_adpcm.c.

References adpcm_state::next_flag, adpcm_state::signal, adpcm_state::ssindex, and adpcm_state::zero_count.

Referenced by adpcm(), and adpcmtolin_framein().

00091 {
00092    int diff;
00093    int step;
00094    int sign;
00095 
00096    step = stpsz[state->ssindex];
00097 
00098    sign = encoded & 0x08;
00099    encoded &= 0x07;
00100 #ifdef NOT_BLI
00101    diff = (((encoded << 1) + 1) * step) >> 3;
00102 #else /* BLI code */
00103    diff = step >> 3;
00104    if (encoded & 4)
00105       diff += step;
00106    if (encoded & 2)
00107       diff += step >> 1;
00108    if (encoded & 1)
00109       diff += step >> 2;
00110    if ((encoded >> 1) & step & 0x1)
00111       diff++;
00112 #endif
00113    if (sign)
00114       diff = -diff;
00115 
00116    if (state->next_flag & 0x1)
00117       state->signal -= 8;
00118    else if (state->next_flag & 0x2)
00119       state->signal += 8;
00120 
00121    state->signal += diff;
00122 
00123    if (state->signal > 2047)
00124       state->signal = 2047;
00125    else if (state->signal < -2047)
00126       state->signal = -2047;
00127 
00128    state->next_flag = 0;
00129 
00130 #ifdef AUTO_RETURN
00131    if (encoded)
00132       state->zero_count = 0;
00133    else if (++(state->zero_count) == 24) {
00134       state->zero_count = 0;
00135       if (state->signal > 0)
00136          state->next_flag = 0x1;
00137       else if (state->signal < 0)
00138          state->next_flag = 0x2;
00139    }
00140 #endif
00141 
00142    state->ssindex += indsft[encoded];
00143    if (state->ssindex < 0)
00144       state->ssindex = 0;
00145    else if (state->ssindex > 48)
00146       state->ssindex = 48;
00147 
00148    return state->signal << 4;
00149 }

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

fill input buffer with 16-bit signed linear PCM values.

Definition at line 245 of file codec_adpcm.c.

References ast_frame::data, ast_frame::datalen, adpcm_encoder_pvt::inbuf, ast_frame::ptr, ast_trans_pvt::pvt, ast_frame::samples, and ast_trans_pvt::samples.

00246 {
00247    struct adpcm_encoder_pvt *tmp = pvt->pvt;
00248 
00249    memcpy(&tmp->inbuf[pvt->samples], f->data.ptr, f->datalen);
00250    pvt->samples += f->samples;
00251    return 0;
00252 }

static struct ast_frame* lintoadpcm_frameout ( struct ast_trans_pvt pvt  )  [static, read]

convert inbuf and store into frame

Definition at line 255 of file codec_adpcm.c.

References adpcm(), ast_trans_frameout(), ast_trans_pvt::c, f, adpcm_encoder_pvt::inbuf, ast_trans_pvt::outbuf, ast_trans_pvt::pvt, ast_trans_pvt::samples, ast_frame::samples, and adpcm_encoder_pvt::state.

00256 {
00257    struct adpcm_encoder_pvt *tmp = pvt->pvt;
00258    struct ast_frame *f;
00259    int i;
00260    int samples = pvt->samples;   /* save original number */
00261   
00262    if (samples < 2)
00263       return NULL;
00264 
00265    pvt->samples &= ~1; /* atomic size is 2 samples */
00266 
00267    for (i = 0; i < pvt->samples; i += 2) {
00268       pvt->outbuf.c[i/2] =
00269          (adpcm(tmp->inbuf[i  ], &tmp->state) << 4) |
00270          (adpcm(tmp->inbuf[i+1], &tmp->state)     );
00271    };
00272 
00273    f = ast_trans_frameout(pvt, pvt->samples/2, 0);
00274 
00275    /*
00276     * If there is a left over sample, move it to the beginning
00277     * of the input buffer.
00278     */
00279 
00280    if (samples & 1) {   /* move the leftover sample at beginning */
00281       tmp->inbuf[0] = tmp->inbuf[samples - 1];
00282       pvt->samples = 1;
00283    }
00284    return f;
00285 }

static struct ast_frame* lintoadpcm_sample ( void   )  [static, read]

LinToAdpcm_Sample.

Definition at line 304 of file codec_adpcm.c.

References AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_frame::data, ast_frame::datalen, ast_frame::frametype, ast_frame::mallocd, ast_frame::offset, ast_frame::ptr, ast_frame::samples, slin_adpcm_ex, ast_frame::src, and ast_frame::subclass.

00305 {
00306    static struct ast_frame f;
00307    f.frametype = AST_FRAME_VOICE;
00308    f.subclass = AST_FORMAT_SLINEAR;
00309    f.datalen = sizeof(slin_adpcm_ex);
00310    /* Assume 8000 Hz */
00311    f.samples = sizeof(slin_adpcm_ex) / 2;
00312    f.mallocd = 0;
00313    f.offset = 0;
00314    f.src = __PRETTY_FUNCTION__;
00315    f.data.ptr = slin_adpcm_ex;
00316    return &f;
00317 }

static int load_module ( void   )  [static]

Definition at line 380 of file codec_adpcm.c.

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

00381 {
00382    int res;
00383 
00384    if (parse_config(0))
00385       return AST_MODULE_LOAD_DECLINE;
00386    res = ast_register_translator(&adpcmtolin);
00387    if (!res)
00388       res = ast_register_translator(&lintoadpcm);
00389    else
00390       ast_unregister_translator(&adpcmtolin);
00391    if (res)
00392       return AST_MODULE_LOAD_FAILURE;
00393    return AST_MODULE_LOAD_SUCCESS;
00394 }

static int parse_config ( int  reload  )  [static]

Definition at line 343 of file codec_adpcm.c.

References ast_config_destroy(), ast_config_load, ast_true(), ast_variable_browse(), ast_verb, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEUNCHANGED, ast_variable::name, ast_variable::next, ast_translator::useplc, ast_variable::value, and var.

Referenced by load_module(), and reload().

00344 {
00345    struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
00346    struct ast_config *cfg = ast_config_load("codecs.conf", config_flags);
00347    struct ast_variable *var;
00348    if (cfg == NULL)
00349       return 0;
00350    if (cfg == CONFIG_STATUS_FILEUNCHANGED)
00351       return 0;
00352    for (var = ast_variable_browse(cfg, "plc"); var ; var = var->next) {
00353       if (!strcasecmp(var->name, "genericplc")) {
00354          adpcmtolin.useplc = ast_true(var->value) ? 1 : 0;
00355          ast_verb(3, "codec_adpcm: %susing generic PLC\n", adpcmtolin.useplc ? "" : "not ");
00356       }
00357    }
00358    ast_config_destroy(cfg);
00359    return 0;
00360 }

static int reload ( void   )  [static]

standard module glue

Definition at line 363 of file codec_adpcm.c.

References AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, and parse_config().

00364 {
00365    if (parse_config(1))
00366       return AST_MODULE_LOAD_DECLINE;
00367    return AST_MODULE_LOAD_SUCCESS;
00368 }

static int unload_module ( void   )  [static]

Definition at line 370 of file codec_adpcm.c.

References ast_unregister_translator().

00371 {
00372    int res;
00373 
00374    res = ast_unregister_translator(&lintoadpcm);
00375    res |= ast_unregister_translator(&adpcmtolin);
00376 
00377    return res;
00378 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Adaptive Differential PCM 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 = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, } [static]

Definition at line 400 of file codec_adpcm.c.

struct ast_translator adpcmtolin [static]

Definition at line 319 of file codec_adpcm.c.

Definition at line 400 of file codec_adpcm.c.

int indsft[8] = { -1, -1, -1, -1, 2, 4, 6, 8 } [static]

Definition at line 55 of file codec_adpcm.c.

struct ast_translator lintoadpcm [static]

Definition at line 331 of file codec_adpcm.c.

int stpsz[49] [static]

Definition at line 61 of file codec_adpcm.c.


Generated on Wed Oct 28 11:52:10 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.6