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
00031
00032
00033
00034 #include "asterisk.h"
00035
00036 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 328209 $")
00037
00038 #include "asterisk/lock.h"
00039 #include "asterisk/linkedlists.h"
00040 #include "asterisk/module.h"
00041 #include "asterisk/config.h"
00042 #include "asterisk/translate.h"
00043 #include "asterisk/utils.h"
00044
00045
00046
00047
00048 #define BUFFER_SAMPLES 8096
00049
00050
00051 #include "asterisk/slin.h"
00052 #include "ex_adpcm.h"
00053
00054
00055
00056
00057
00058 static int indsft[8] = { -1, -1, -1, -1, 2, 4, 6, 8 };
00059
00060
00061
00062
00063
00064 static int stpsz[49] = {
00065 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, 60, 66, 73,
00066 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, 279,
00067 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963,
00068 1060, 1166, 1282, 1411, 1552
00069 };
00070
00071
00072
00073
00074
00075 struct adpcm_state {
00076 int ssindex;
00077 int signal;
00078 int zero_count;
00079 int next_flag;
00080 };
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 static inline short decode(int encoded, struct adpcm_state *state)
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
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 }
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 static inline int adpcm(short csig, struct adpcm_state *state)
00167 {
00168 int diff;
00169 int step;
00170 int encoded;
00171
00172
00173
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
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
00210
00211
00212 decode(encoded, state);
00213
00214 return encoded;
00215 }
00216
00217
00218
00219
00220 struct adpcm_encoder_pvt {
00221 struct adpcm_state state;
00222 int16_t inbuf[BUFFER_SAMPLES];
00223 };
00224
00225
00226 struct adpcm_decoder_pvt {
00227 struct adpcm_state state;
00228 };
00229
00230
00231 static int adpcmtolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
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 }
00246
00247
00248 static int lintoadpcm_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
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 }
00256
00257
00258 static struct ast_frame *lintoadpcm_frameout(struct ast_trans_pvt *pvt)
00259 {
00260 struct adpcm_encoder_pvt *tmp = pvt->pvt;
00261 struct ast_frame *f;
00262 int i;
00263 int samples = pvt->samples;
00264
00265 if (samples < 2)
00266 return NULL;
00267
00268 pvt->samples &= ~1;
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
00280
00281
00282
00283 if (samples & 1) {
00284 tmp->inbuf[0] = tmp->inbuf[samples - 1];
00285 pvt->samples = 1;
00286 }
00287 return f;
00288 }
00289
00290
00291 static struct ast_translator adpcmtolin = {
00292 .name = "adpcmtolin",
00293 .srcfmt = AST_FORMAT_ADPCM,
00294 .dstfmt = AST_FORMAT_SLINEAR,
00295 .framein = adpcmtolin_framein,
00296 .sample = adpcm_sample,
00297 .desc_size = sizeof(struct adpcm_decoder_pvt),
00298 .buffer_samples = BUFFER_SAMPLES,
00299 .buf_size = BUFFER_SAMPLES * 2,
00300 };
00301
00302 static struct ast_translator lintoadpcm = {
00303 .name = "lintoadpcm",
00304 .srcfmt = AST_FORMAT_SLINEAR,
00305 .dstfmt = AST_FORMAT_ADPCM,
00306 .framein = lintoadpcm_framein,
00307 .frameout = lintoadpcm_frameout,
00308 .sample = slin8_sample,
00309 .desc_size = sizeof (struct adpcm_encoder_pvt),
00310 .buffer_samples = BUFFER_SAMPLES,
00311 .buf_size = BUFFER_SAMPLES/ 2,
00312 };
00313
00314
00315 static int reload(void)
00316 {
00317 return AST_MODULE_LOAD_SUCCESS;
00318 }
00319
00320 static int unload_module(void)
00321 {
00322 int res;
00323
00324 res = ast_unregister_translator(&lintoadpcm);
00325 res |= ast_unregister_translator(&adpcmtolin);
00326
00327 return res;
00328 }
00329
00330 static int load_module(void)
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 }
00343
00344 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Adaptive Differential PCM Coder/Decoder",
00345 .load = load_module,
00346 .unload = unload_module,
00347 .reload = reload,
00348 );