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"
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 | |
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_frame * | lintoadpcm_frameout (struct ast_trans_pvt *pvt) |
convert inbuf and store into frame | |
static int | load_module (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] |
codec_adpcm.c - translate between signed linear and Dialogic ADPCM
Definition in file codec_adpcm.c.
#define BUFFER_SAMPLES 8096 |
Definition at line 48 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.
Referenced by lintoadpcm_frameout().
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, and adpcm_decoder_pvt::state.
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 }
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 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(), and adpcmtolin_framein().
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, and ast_trans_pvt::samples.
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, ast_trans_pvt::outbuf, ast_trans_pvt::pvt, ast_trans_pvt::samples, ast_frame::samples, and adpcm_encoder_pvt::state.
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 330 of file codec_adpcm.c.
References AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_register_translator, and ast_unregister_translator().
00331 { 00332 int res; 00333 00334 res = ast_register_translator(&adpcmtolin); 00335 if (!res) 00336 res = ast_register_translator(&lintoadpcm); 00337 else 00338 ast_unregister_translator(&adpcmtolin); 00339 if (res) 00340 return AST_MODULE_LOAD_FAILURE; 00341 return AST_MODULE_LOAD_SUCCESS; 00342 }
static int reload | ( | void | ) | [static] |
standard module glue
Definition at line 315 of file codec_adpcm.c.
References AST_MODULE_LOAD_SUCCESS.
00316 { 00317 return AST_MODULE_LOAD_SUCCESS; 00318 }
static int unload_module | ( | void | ) | [static] |
Definition at line 320 of file codec_adpcm.c.
References ast_unregister_translator().
00321 { 00322 int res; 00323 00324 res = ast_unregister_translator(&lintoadpcm); 00325 res |= ast_unregister_translator(&adpcmtolin); 00326 00327 return res; 00328 }
struct ast_translator adpcmtolin [static] |
Definition at line 291 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 302 of file codec_adpcm.c.
int stpsz[49] [static] |
Definition at line 64 of file codec_adpcm.c.