Fri Nov 12 11:58:26 2010

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 "asterisk/slin.h"
#include "ex_adpcm.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 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 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 = "0901e4e500243c855563a2d78b0c03e4" , .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 366 of file codec_adpcm.c.

static void __unreg_module ( void   )  [static]

Definition at line 366 of file codec_adpcm.c.

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

Definition at line 162 of file codec_adpcm.c.

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

Referenced by lintoadpcm_frameout().

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

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

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

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

Definition at line 89 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().

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

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

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

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

convert inbuf and store into frame

Definition at line 254 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.

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

static int load_module ( void   )  [static]

Definition at line 346 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().

00347 {
00348    int res;
00349 
00350    if (parse_config(0))
00351       return AST_MODULE_LOAD_DECLINE;
00352    res = ast_register_translator(&adpcmtolin);
00353    if (!res)
00354       res = ast_register_translator(&lintoadpcm);
00355    else
00356       ast_unregister_translator(&adpcmtolin);
00357    if (res)
00358       return AST_MODULE_LOAD_FAILURE;
00359    return AST_MODULE_LOAD_SUCCESS;
00360 }

static int parse_config ( int  reload  )  [static]

Definition at line 311 of file codec_adpcm.c.

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

Referenced by load_module(), and reload().

00312 {
00313    struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
00314    struct ast_config *cfg = ast_config_load("codecs.conf", config_flags);
00315    struct ast_variable *var;
00316    if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID)
00317       return 0;
00318    for (var = ast_variable_browse(cfg, "plc"); var ; var = var->next) {
00319       if (!strcasecmp(var->name, "genericplc")) {
00320          adpcmtolin.useplc = ast_true(var->value) ? 1 : 0;
00321          ast_verb(3, "codec_adpcm: %susing generic PLC\n", adpcmtolin.useplc ? "" : "not ");
00322       }
00323    }
00324    ast_config_destroy(cfg);
00325    return 0;
00326 }

static int reload ( void   )  [static]

standard module glue

Definition at line 329 of file codec_adpcm.c.

References AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, and parse_config().

00330 {
00331    if (parse_config(1))
00332       return AST_MODULE_LOAD_DECLINE;
00333    return AST_MODULE_LOAD_SUCCESS;
00334 }

static int unload_module ( void   )  [static]

Definition at line 336 of file codec_adpcm.c.

References ast_unregister_translator().

00337 {
00338    int res;
00339 
00340    res = ast_unregister_translator(&lintoadpcm);
00341    res |= ast_unregister_translator(&adpcmtolin);
00342 
00343    return res;
00344 }


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 = "0901e4e500243c855563a2d78b0c03e4" , .load = load_module, .unload = unload_module, .reload = reload, } [static]

Definition at line 366 of file codec_adpcm.c.

struct ast_translator adpcmtolin [static]

Definition at line 287 of file codec_adpcm.c.

Definition at line 366 of file codec_adpcm.c.

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

Definition at line 54 of file codec_adpcm.c.

struct ast_translator lintoadpcm [static]

Definition at line 299 of file codec_adpcm.c.

int stpsz[49] [static]

Definition at line 60 of file codec_adpcm.c.


Generated by  doxygen 1.6.2