Fri Aug 24 02:24:30 2007

Asterisk developer's documentation


codec_adpcm.c File Reference

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

#include "asterisk.h"
#include <fcntl.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "asterisk/lock.h"
#include "asterisk/logger.h"
#include "asterisk/linkedlists.h"
#include "asterisk/module.h"
#include "asterisk/config.h"
#include "asterisk/options.h"
#include "asterisk/translate.h"
#include "asterisk/channel.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 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.
 AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT,"Adaptive Differential PCM Coder/Decoder",.load=load_module,.unload=unload_module,.reload=reload,)
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 void parse_config (void)
static int reload (void)
 standard module glue
static int unload_module (void)

Variables

static struct ast_translator adpcmtolin
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 54 of file codec_adpcm.c.


Function Documentation

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

Definition at line 173 of file codec_adpcm.c.

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

Referenced by lintoadpcm_frameout().

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

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 238 of file codec_adpcm.c.

References ast_trans_pvt::datalen, decode(), f, ast_trans_pvt::outbuf, ast_trans_pvt::pvt, ast_trans_pvt::samples, and adpcm_decoder_pvt::state.

00239 {
00240    struct adpcm_decoder_pvt *tmp = pvt->pvt;
00241    int x = f->datalen;
00242    unsigned char *src = f->data;
00243    int16_t *dst = (int16_t *)pvt->outbuf + pvt->samples;
00244 
00245    while (x--) {
00246       *dst++ = decode((*src >> 4) & 0xf, &tmp->state);
00247       *dst++ = decode(*src++ & 0x0f, &tmp->state);
00248    }
00249    pvt->samples += f->samples;
00250    pvt->datalen += 2*f->samples;
00251    return 0;
00252 }

static struct ast_frame* adpcmtolin_sample ( void   )  [static]

AdpcmToLin_Sample.

Definition at line 299 of file codec_adpcm.c.

References adpcm_slin_ex, AST_FORMAT_ADPCM, AST_FRAME_VOICE, and f.

00300 {
00301    static struct ast_frame f;
00302    f.frametype = AST_FRAME_VOICE;
00303    f.subclass = AST_FORMAT_ADPCM;
00304    f.datalen = sizeof(adpcm_slin_ex);
00305    f.samples = sizeof(adpcm_slin_ex) * 2;
00306    f.mallocd = 0;
00307    f.offset = 0;
00308    f.src = __PRETTY_FUNCTION__;
00309    f.data = adpcm_slin_ex;
00310    return &f;
00311 }

AST_MODULE_INFO ( ASTERISK_GPL_KEY  ,
AST_MODFLAG_DEFAULT  ,
"Adaptive Differential PCM Coder/Decoder"  ,
load = load_module,
unload = unload_module,
reload = reload 
)

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

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

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

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 255 of file codec_adpcm.c.

References f, adpcm_encoder_pvt::inbuf, ast_trans_pvt::pvt, and ast_trans_pvt::samples.

00256 {
00257    struct adpcm_encoder_pvt *tmp = pvt->pvt;
00258 
00259    memcpy(&tmp->inbuf[pvt->samples], f->data, f->datalen);
00260    pvt->samples += f->samples;
00261    return 0;
00262 }

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

convert inbuf and store into frame

Definition at line 265 of file codec_adpcm.c.

References adpcm(), ast_trans_frameout(), 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.

00266 {
00267    struct adpcm_encoder_pvt *tmp = pvt->pvt;
00268    struct ast_frame *f;
00269    int i;
00270    int samples = pvt->samples;   /* save original number */
00271   
00272    if (samples < 2)
00273       return NULL;
00274 
00275    pvt->samples &= ~1; /* atomic size is 2 samples */
00276 
00277    for (i = 0; i < pvt->samples; i += 2) {
00278       pvt->outbuf[i/2] =
00279          (adpcm(tmp->inbuf[i  ], &tmp->state) << 4) |
00280          (adpcm(tmp->inbuf[i+1], &tmp->state)     );
00281    };
00282 
00283    f = ast_trans_frameout(pvt, pvt->samples/2, 0);
00284 
00285    /*
00286     * If there is a left over sample, move it to the beginning
00287     * of the input buffer.
00288     */
00289 
00290    if (samples & 1) {   /* move the leftover sample at beginning */
00291       tmp->inbuf[0] = tmp->inbuf[samples - 1];
00292       pvt->samples = 1;
00293    }
00294    return f;
00295 }

static struct ast_frame* lintoadpcm_sample ( void   )  [static]

LinToAdpcm_Sample.

Definition at line 314 of file codec_adpcm.c.

References AST_FORMAT_SLINEAR, AST_FRAME_VOICE, f, and slin_adpcm_ex.

00315 {
00316    static struct ast_frame f;
00317    f.frametype = AST_FRAME_VOICE;
00318    f.subclass = AST_FORMAT_SLINEAR;
00319    f.datalen = sizeof(slin_adpcm_ex);
00320    /* Assume 8000 Hz */
00321    f.samples = sizeof(slin_adpcm_ex) / 2;
00322    f.mallocd = 0;
00323    f.offset = 0;
00324    f.src = __PRETTY_FUNCTION__;
00325    f.data = slin_adpcm_ex;
00326    return &f;
00327 }

static int load_module ( void   )  [static]

Definition at line 386 of file codec_adpcm.c.

References adpcmtolin, ast_register_translator, ast_unregister_translator(), lintoadpcm, and parse_config().

00387 {
00388    int res;
00389 
00390    parse_config();
00391    res = ast_register_translator(&adpcmtolin);
00392    if (!res)
00393       res = ast_register_translator(&lintoadpcm);
00394    else
00395       ast_unregister_translator(&adpcmtolin);
00396 
00397    return res;
00398 }

static void parse_config ( void   )  [static]

Definition at line 353 of file codec_adpcm.c.

References adpcmtolin, ast_config_load(), ast_true(), ast_variable_browse(), ast_verbose(), option_verbose, ast_translator::useplc, var, and VERBOSE_PREFIX_3.

Referenced by load_module(), and reload().

00354 {
00355    struct ast_config *cfg = ast_config_load("codecs.conf");
00356    struct ast_variable *var;
00357    if (cfg == NULL)
00358       return;
00359    for (var = ast_variable_browse(cfg, "plc"); var ; var = var->next) {
00360       if (!strcasecmp(var->name, "genericplc")) {
00361          adpcmtolin.useplc = ast_true(var->value) ? 1 : 0;
00362          if (option_verbose > 2)
00363             ast_verbose(VERBOSE_PREFIX_3 "codec_adpcm: %susing generic PLC\n", adpcmtolin.useplc ? "" : "not ");
00364       }
00365    }
00366    ast_config_destroy(cfg);
00367 }

static int reload ( void   )  [static]

standard module glue

Definition at line 370 of file codec_adpcm.c.

References parse_config().

00371 {
00372    parse_config();
00373    return 0;
00374 }

static int unload_module ( void   )  [static]

Definition at line 376 of file codec_adpcm.c.

References adpcmtolin, ast_unregister_translator(), and lintoadpcm.

00377 {
00378    int res;
00379 
00380    res = ast_unregister_translator(&lintoadpcm);
00381    res |= ast_unregister_translator(&adpcmtolin);
00382 
00383    return res;
00384 }


Variable Documentation

struct ast_translator adpcmtolin [static]

Definition at line 329 of file codec_adpcm.c.

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

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

Definition at line 65 of file codec_adpcm.c.

struct ast_translator lintoadpcm [static]

Definition at line 341 of file codec_adpcm.c.

Referenced by load_module(), and unload_module().

int stpsz[49] [static]

Definition at line 71 of file codec_adpcm.c.


Generated on Fri Aug 24 02:24:31 2007 for Asterisk - the Open Source PBX by  doxygen 1.5.1