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: 150729 $")
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 #include "asterisk/slin.h"
00048 #include "ex_adpcm.h"
00049
00050
00051
00052
00053
00054 static int indsft[8] = { -1, -1, -1, -1, 2, 4, 6, 8 };
00055
00056
00057
00058
00059
00060 static int stpsz[49] = {
00061 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, 60, 66, 73,
00062 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, 279,
00063 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963,
00064 1060, 1166, 1282, 1411, 1552
00065 };
00066
00067
00068
00069
00070
00071 struct adpcm_state {
00072 int ssindex;
00073 int signal;
00074 int zero_count;
00075 int next_flag;
00076 };
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089 static inline short decode(int encoded, struct adpcm_state *state)
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
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 }
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162 static inline int adpcm(short csig, struct adpcm_state *state)
00163 {
00164 int diff;
00165 int step;
00166 int encoded;
00167
00168
00169
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
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
00206
00207
00208 decode(encoded, state);
00209
00210 return encoded;
00211 }
00212
00213
00214
00215
00216 struct adpcm_encoder_pvt {
00217 struct adpcm_state state;
00218 int16_t inbuf[BUFFER_SAMPLES];
00219 };
00220
00221
00222 struct adpcm_decoder_pvt {
00223 struct adpcm_state state;
00224 };
00225
00226
00227 static int adpcmtolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
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 }
00242
00243
00244 static int lintoadpcm_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
00245 {
00246 struct adpcm_encoder_pvt *tmp = pvt->pvt;
00247
00248 memcpy(&tmp->inbuf[pvt->samples], f->data.ptr, f->datalen);
00249 pvt->samples += f->samples;
00250 return 0;
00251 }
00252
00253
00254 static struct ast_frame *lintoadpcm_frameout(struct ast_trans_pvt *pvt)
00255 {
00256 struct adpcm_encoder_pvt *tmp = pvt->pvt;
00257 struct ast_frame *f;
00258 int i;
00259 int samples = pvt->samples;
00260
00261 if (samples < 2)
00262 return NULL;
00263
00264 pvt->samples &= ~1;
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
00276
00277
00278
00279 if (samples & 1) {
00280 tmp->inbuf[0] = tmp->inbuf[samples - 1];
00281 pvt->samples = 1;
00282 }
00283 return f;
00284 }
00285
00286
00287 static struct ast_translator adpcmtolin = {
00288 .name = "adpcmtolin",
00289 .srcfmt = AST_FORMAT_ADPCM,
00290 .dstfmt = AST_FORMAT_SLINEAR,
00291 .framein = adpcmtolin_framein,
00292 .sample = adpcm_sample,
00293 .desc_size = sizeof(struct adpcm_decoder_pvt),
00294 .buffer_samples = BUFFER_SAMPLES,
00295 .buf_size = BUFFER_SAMPLES * 2,
00296 .plc_samples = 160,
00297 };
00298
00299 static struct ast_translator lintoadpcm = {
00300 .name = "lintoadpcm",
00301 .srcfmt = AST_FORMAT_SLINEAR,
00302 .dstfmt = AST_FORMAT_ADPCM,
00303 .framein = lintoadpcm_framein,
00304 .frameout = lintoadpcm_frameout,
00305 .sample = slin8_sample,
00306 .desc_size = sizeof (struct adpcm_encoder_pvt),
00307 .buffer_samples = BUFFER_SAMPLES,
00308 .buf_size = BUFFER_SAMPLES/ 2,
00309 };
00310
00311 static int parse_config(int 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 }
00327
00328
00329 static int reload(void)
00330 {
00331 if (parse_config(1))
00332 return AST_MODULE_LOAD_DECLINE;
00333 return AST_MODULE_LOAD_SUCCESS;
00334 }
00335
00336 static int unload_module(void)
00337 {
00338 int res;
00339
00340 res = ast_unregister_translator(&lintoadpcm);
00341 res |= ast_unregister_translator(&adpcmtolin);
00342
00343 return res;
00344 }
00345
00346 static int load_module(void)
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 }
00361
00362 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Adaptive Differential PCM Coder/Decoder",
00363 .load = load_module,
00364 .unload = unload_module,
00365 .reload = reload,
00366 );