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 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_frame * | lintoadpcm_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_info * | ast_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] |
codec_adpcm.c - translate between signed linear and Dialogic ADPCM
Definition in file codec_adpcm.c.
| #define BUFFER_SAMPLES 8096 |
Definition at line 44 of file codec_adpcm.c.
| 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.
| 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 }
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.
struct ast_module_info* ast_module_info = &__mod_info [static] |
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.
1.6.2