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 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, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, }
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 48 of file codec_adpcm.c.


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 361 of file codec_adpcm.c.

static void __unreg_module ( void   )  [static]

Definition at line 361 of file codec_adpcm.c.

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

Definition at line 166 of file codec_adpcm.c.

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

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

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 231 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, adpcm_decoder_pvt::state, and tmp().

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

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

Definition at line 93 of file codec_adpcm.c.

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

Referenced by adpcm(), adpcmtolin_framein(), and main().

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

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 248 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, ast_trans_pvt::samples, and tmp().

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

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

convert inbuf and store into frame

Definition at line 258 of file codec_adpcm.c.

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

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

static int load_module ( void   )  [static]

Definition at line 342 of file codec_adpcm.c.

References AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_register_translator, and unload_module.

00343 {
00344    int res = 0;
00345 
00346    res = ast_register_translator(&adpcmtolin);
00347    res |= ast_register_translator(&lintoadpcm);
00348 
00349    if (res) {
00350       unload_module();
00351       return AST_MODULE_LOAD_FAILURE;
00352    }
00353 
00354    return AST_MODULE_LOAD_SUCCESS;
00355 }

static int unload_module ( void   )  [static]

Definition at line 332 of file codec_adpcm.c.

References ast_unregister_translator().

00333 {
00334    int res;
00335 
00336    res = ast_unregister_translator(&lintoadpcm);
00337    res |= ast_unregister_translator(&adpcmtolin);
00338 
00339    return res;
00340 }


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, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, } [static]

Definition at line 361 of file codec_adpcm.c.

struct ast_translator adpcmtolin [static]

Definition at line 291 of file codec_adpcm.c.

Definition at line 361 of file codec_adpcm.c.

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

Definition at line 58 of file codec_adpcm.c.

struct ast_translator lintoadpcm [static]

Definition at line 311 of file codec_adpcm.c.

int stpsz[49] [static]

Definition at line 64 of file codec_adpcm.c.


Generated on Thu Apr 16 06:30:14 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6