00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "asterisk.h"
00031
00032 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 125386 $")
00033
00034 #include "asterisk/lock.h"
00035 #include "asterisk/linkedlists.h"
00036 #include "asterisk/module.h"
00037 #include "asterisk/config.h"
00038 #include "asterisk/translate.h"
00039 #include "asterisk/utils.h"
00040
00041
00042
00043
00044 #define BUFFER_SAMPLES 8096
00045
00046
00047
00048 #include "slin_adpcm_ex.h"
00049 #include "adpcm_slin_ex.h"
00050
00051
00052
00053
00054
00055 static int indsft[8] = { -1, -1, -1, -1, 2, 4, 6, 8 };
00056
00057
00058
00059
00060
00061 static int stpsz[49] = {
00062 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, 60, 66, 73,
00063 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, 279,
00064 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963,
00065 1060, 1166, 1282, 1411, 1552
00066 };
00067
00068
00069
00070
00071
00072 struct adpcm_state {
00073 int ssindex;
00074 int signal;
00075 int zero_count;
00076 int next_flag;
00077 };
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 static inline short decode(int encoded, struct adpcm_state *state)
00091 {
00092 int diff;
00093 int step;
00094 int sign;
00095
00096 step = stpsz[state->ssindex];
00097
00098 sign = encoded & 0x08;
00099 encoded &= 0x07;
00100 #ifdef NOT_BLI
00101 diff = (((encoded << 1) + 1) * step) >> 3;
00102 #else
00103 diff = step >> 3;
00104 if (encoded & 4)
00105 diff += step;
00106 if (encoded & 2)
00107 diff += step >> 1;
00108 if (encoded & 1)
00109 diff += step >> 2;
00110 if ((encoded >> 1) & step & 0x1)
00111 diff++;
00112 #endif
00113 if (sign)
00114 diff = -diff;
00115
00116 if (state->next_flag & 0x1)
00117 state->signal -= 8;
00118 else if (state->next_flag & 0x2)
00119 state->signal += 8;
00120
00121 state->signal += diff;
00122
00123 if (state->signal > 2047)
00124 state->signal = 2047;
00125 else if (state->signal < -2047)
00126 state->signal = -2047;
00127
00128 state->next_flag = 0;
00129
00130 #ifdef AUTO_RETURN
00131 if (encoded)
00132 state->zero_count = 0;
00133 else if (++(state->zero_count) == 24) {
00134 state->zero_count = 0;
00135 if (state->signal > 0)
00136 state->next_flag = 0x1;
00137 else if (state->signal < 0)
00138 state->next_flag = 0x2;
00139 }
00140 #endif
00141
00142 state->ssindex += indsft[encoded];
00143 if (state->ssindex < 0)
00144 state->ssindex = 0;
00145 else if (state->ssindex > 48)
00146 state->ssindex = 48;
00147
00148 return state->signal << 4;
00149 }
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 static inline int adpcm(short csig, struct adpcm_state *state)
00164 {
00165 int diff;
00166 int step;
00167 int encoded;
00168
00169
00170
00171
00172 csig >>= 4;
00173
00174 step = stpsz[state->ssindex];
00175 diff = csig - state->signal;
00176
00177 #ifdef NOT_BLI
00178 if (diff < 0) {
00179 encoded = (-diff << 2) / step;
00180 if (encoded > 7)
00181 encoded = 7;
00182 encoded |= 0x08;
00183 } else {
00184 encoded = (diff << 2) / step;
00185 if (encoded > 7)
00186 encoded = 7;
00187 }
00188 #else
00189 if (diff < 0) {
00190 encoded = 8;
00191 diff = -diff;
00192 } else
00193 encoded = 0;
00194 if (diff >= step) {
00195 encoded |= 4;
00196 diff -= step;
00197 }
00198 step >>= 1;
00199 if (diff >= step) {
00200 encoded |= 2;
00201 diff -= step;
00202 }
00203 step >>= 1;
00204 if (diff >= step)
00205 encoded |= 1;
00206 #endif
00207
00208
00209 decode(encoded, state);
00210
00211 return encoded;
00212 }
00213
00214
00215
00216
00217 struct adpcm_encoder_pvt {
00218 struct adpcm_state state;
00219 int16_t inbuf[BUFFER_SAMPLES];
00220 };
00221
00222
00223 struct adpcm_decoder_pvt {
00224 struct adpcm_state state;
00225 };
00226
00227
00228 static int adpcmtolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
00229 {
00230 struct adpcm_decoder_pvt *tmp = pvt->pvt;
00231 int x = f->datalen;
00232 unsigned char *src = f->data.ptr;
00233 int16_t *dst = pvt->outbuf.i16 + pvt->samples;
00234
00235 while (x--) {
00236 *dst++ = decode((*src >> 4) & 0xf, &tmp->state);
00237 *dst++ = decode(*src++ & 0x0f, &tmp->state);
00238 }
00239 pvt->samples += f->samples;
00240 pvt->datalen += 2*f->samples;
00241 return 0;
00242 }
00243
00244
00245 static int lintoadpcm_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
00246 {
00247 struct adpcm_encoder_pvt *tmp = pvt->pvt;
00248
00249 memcpy(&tmp->inbuf[pvt->samples], f->data.ptr, f->datalen);
00250 pvt->samples += f->samples;
00251 return 0;
00252 }
00253
00254
00255 static struct ast_frame *lintoadpcm_frameout(struct ast_trans_pvt *pvt)
00256 {
00257 struct adpcm_encoder_pvt *tmp = pvt->pvt;
00258 struct ast_frame *f;
00259 int i;
00260 int samples = pvt->samples;
00261
00262 if (samples < 2)
00263 return NULL;
00264
00265 pvt->samples &= ~1;
00266
00267 for (i = 0; i < pvt->samples; i += 2) {
00268 pvt->outbuf.c[i/2] =
00269 (adpcm(tmp->inbuf[i ], &tmp->state) << 4) |
00270 (adpcm(tmp->inbuf[i+1], &tmp->state) );
00271 };
00272
00273 f = ast_trans_frameout(pvt, pvt->samples/2, 0);
00274
00275
00276
00277
00278
00279
00280 if (samples & 1) {
00281 tmp->inbuf[0] = tmp->inbuf[samples - 1];
00282 pvt->samples = 1;
00283 }
00284 return f;
00285 }
00286
00287
00288
00289 static struct ast_frame *adpcmtolin_sample(void)
00290 {
00291 static struct ast_frame f;
00292 f.frametype = AST_FRAME_VOICE;
00293 f.subclass = AST_FORMAT_ADPCM;
00294 f.datalen = sizeof(adpcm_slin_ex);
00295 f.samples = sizeof(adpcm_slin_ex) * 2;
00296 f.mallocd = 0;
00297 f.offset = 0;
00298 f.src = __PRETTY_FUNCTION__;
00299 f.data.ptr = adpcm_slin_ex;
00300 return &f;
00301 }
00302
00303
00304 static struct ast_frame *lintoadpcm_sample(void)
00305 {
00306 static struct ast_frame f;
00307 f.frametype = AST_FRAME_VOICE;
00308 f.subclass = AST_FORMAT_SLINEAR;
00309 f.datalen = sizeof(slin_adpcm_ex);
00310
00311 f.samples = sizeof(slin_adpcm_ex) / 2;
00312 f.mallocd = 0;
00313 f.offset = 0;
00314 f.src = __PRETTY_FUNCTION__;
00315 f.data.ptr = slin_adpcm_ex;
00316 return &f;
00317 }
00318
00319 static struct ast_translator adpcmtolin = {
00320 .name = "adpcmtolin",
00321 .srcfmt = AST_FORMAT_ADPCM,
00322 .dstfmt = AST_FORMAT_SLINEAR,
00323 .framein = adpcmtolin_framein,
00324 .sample = adpcmtolin_sample,
00325 .desc_size = sizeof(struct adpcm_decoder_pvt),
00326 .buffer_samples = BUFFER_SAMPLES,
00327 .buf_size = BUFFER_SAMPLES * 2,
00328 .plc_samples = 160,
00329 };
00330
00331 static struct ast_translator lintoadpcm = {
00332 .name = "lintoadpcm",
00333 .srcfmt = AST_FORMAT_SLINEAR,
00334 .dstfmt = AST_FORMAT_ADPCM,
00335 .framein = lintoadpcm_framein,
00336 .frameout = lintoadpcm_frameout,
00337 .sample = lintoadpcm_sample,
00338 .desc_size = sizeof (struct adpcm_encoder_pvt),
00339 .buffer_samples = BUFFER_SAMPLES,
00340 .buf_size = BUFFER_SAMPLES/ 2,
00341 };
00342
00343 static int parse_config(int reload)
00344 {
00345 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
00346 struct ast_config *cfg = ast_config_load("codecs.conf", config_flags);
00347 struct ast_variable *var;
00348 if (cfg == NULL)
00349 return 0;
00350 if (cfg == CONFIG_STATUS_FILEUNCHANGED)
00351 return 0;
00352 for (var = ast_variable_browse(cfg, "plc"); var ; var = var->next) {
00353 if (!strcasecmp(var->name, "genericplc")) {
00354 adpcmtolin.useplc = ast_true(var->value) ? 1 : 0;
00355 ast_verb(3, "codec_adpcm: %susing generic PLC\n", adpcmtolin.useplc ? "" : "not ");
00356 }
00357 }
00358 ast_config_destroy(cfg);
00359 return 0;
00360 }
00361
00362
00363 static int reload(void)
00364 {
00365 if (parse_config(1))
00366 return AST_MODULE_LOAD_DECLINE;
00367 return AST_MODULE_LOAD_SUCCESS;
00368 }
00369
00370 static int unload_module(void)
00371 {
00372 int res;
00373
00374 res = ast_unregister_translator(&lintoadpcm);
00375 res |= ast_unregister_translator(&adpcmtolin);
00376
00377 return res;
00378 }
00379
00380 static int load_module(void)
00381 {
00382 int res;
00383
00384 if (parse_config(0))
00385 return AST_MODULE_LOAD_DECLINE;
00386 res = ast_register_translator(&adpcmtolin);
00387 if (!res)
00388 res = ast_register_translator(&lintoadpcm);
00389 else
00390 ast_unregister_translator(&adpcmtolin);
00391 if (res)
00392 return AST_MODULE_LOAD_FAILURE;
00393 return AST_MODULE_LOAD_SUCCESS;
00394 }
00395
00396 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Adaptive Differential PCM Coder/Decoder",
00397 .load = load_module,
00398 .unload = unload_module,
00399 .reload = reload,
00400 );