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: 267492 $")
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 };
00297
00298 static struct ast_translator lintoadpcm = {
00299 .name = "lintoadpcm",
00300 .srcfmt = AST_FORMAT_SLINEAR,
00301 .dstfmt = AST_FORMAT_ADPCM,
00302 .framein = lintoadpcm_framein,
00303 .frameout = lintoadpcm_frameout,
00304 .sample = slin8_sample,
00305 .desc_size = sizeof (struct adpcm_encoder_pvt),
00306 .buffer_samples = BUFFER_SAMPLES,
00307 .buf_size = BUFFER_SAMPLES/ 2,
00308 };
00309
00310
00311 static int reload(void)
00312 {
00313 return AST_MODULE_LOAD_SUCCESS;
00314 }
00315
00316 static int unload_module(void)
00317 {
00318 int res;
00319
00320 res = ast_unregister_translator(&lintoadpcm);
00321 res |= ast_unregister_translator(&adpcmtolin);
00322
00323 return res;
00324 }
00325
00326 static int load_module(void)
00327 {
00328 int res;
00329
00330 res = ast_register_translator(&adpcmtolin);
00331 if (!res)
00332 res = ast_register_translator(&lintoadpcm);
00333 else
00334 ast_unregister_translator(&adpcmtolin);
00335 if (res)
00336 return AST_MODULE_LOAD_FAILURE;
00337 return AST_MODULE_LOAD_SUCCESS;
00338 }
00339
00340 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Adaptive Differential PCM Coder/Decoder",
00341 .load = load_module,
00342 .unload = unload_module,
00343 .reload = reload,
00344 );