00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "avcodec.h"
00022
00023 #include "truespeech_data.h"
00032 typedef struct {
00033
00034 int16_t vector[8];
00035 int offset1[2];
00036 int offset2[4];
00037 int pulseoff[4];
00038 int pulsepos[4];
00039 int pulseval[4];
00040 int flag;
00041
00042 int filtbuf[146];
00043 int prevfilt[8];
00044 int16_t tmp1[8];
00045 int16_t tmp2[8];
00046 int16_t tmp3[8];
00047 int16_t cvector[8];
00048 int filtval;
00049 int16_t newvec[60];
00050 int16_t filters[32];
00051 } TSContext;
00052
00053 static int truespeech_decode_init(AVCodecContext * avctx)
00054 {
00055
00056
00057 return 0;
00058 }
00059
00060 static void truespeech_read_frame(TSContext *dec, const uint8_t *input)
00061 {
00062 uint32_t t;
00063
00064
00065 t = AV_RL32(input);
00066 input += 4;
00067
00068 dec->flag = t & 1;
00069
00070 dec->vector[0] = ts_codebook[0][(t >> 1) & 0x1F];
00071 dec->vector[1] = ts_codebook[1][(t >> 6) & 0x1F];
00072 dec->vector[2] = ts_codebook[2][(t >> 11) & 0xF];
00073 dec->vector[3] = ts_codebook[3][(t >> 15) & 0xF];
00074 dec->vector[4] = ts_codebook[4][(t >> 19) & 0xF];
00075 dec->vector[5] = ts_codebook[5][(t >> 23) & 0x7];
00076 dec->vector[6] = ts_codebook[6][(t >> 26) & 0x7];
00077 dec->vector[7] = ts_codebook[7][(t >> 29) & 0x7];
00078
00079
00080 t = AV_RL32(input);
00081 input += 4;
00082
00083 dec->offset2[0] = (t >> 0) & 0x7F;
00084 dec->offset2[1] = (t >> 7) & 0x7F;
00085 dec->offset2[2] = (t >> 14) & 0x7F;
00086 dec->offset2[3] = (t >> 21) & 0x7F;
00087
00088 dec->offset1[0] = ((t >> 28) & 0xF) << 4;
00089
00090
00091 t = AV_RL32(input);
00092 input += 4;
00093
00094 dec->pulseval[0] = (t >> 0) & 0x3FFF;
00095 dec->pulseval[1] = (t >> 14) & 0x3FFF;
00096
00097 dec->offset1[1] = (t >> 28) & 0x0F;
00098
00099
00100 t = AV_RL32(input);
00101 input += 4;
00102
00103 dec->pulseval[2] = (t >> 0) & 0x3FFF;
00104 dec->pulseval[3] = (t >> 14) & 0x3FFF;
00105
00106 dec->offset1[1] |= ((t >> 28) & 0x0F) << 4;
00107
00108
00109 t = AV_RL32(input);
00110 input += 4;
00111
00112 dec->pulsepos[0] = (t >> 4) & 0x7FFFFFF;
00113
00114 dec->pulseoff[0] = (t >> 0) & 0xF;
00115
00116 dec->offset1[0] |= (t >> 31) & 1;
00117
00118
00119 t = AV_RL32(input);
00120 input += 4;
00121
00122 dec->pulsepos[1] = (t >> 4) & 0x7FFFFFF;
00123
00124 dec->pulseoff[1] = (t >> 0) & 0xF;
00125
00126 dec->offset1[0] |= ((t >> 31) & 1) << 1;
00127
00128
00129 t = AV_RL32(input);
00130 input += 4;
00131
00132 dec->pulsepos[2] = (t >> 4) & 0x7FFFFFF;
00133
00134 dec->pulseoff[2] = (t >> 0) & 0xF;
00135
00136 dec->offset1[0] |= ((t >> 31) & 1) << 2;
00137
00138
00139 t = AV_RL32(input);
00140 input += 4;
00141
00142 dec->pulsepos[3] = (t >> 4) & 0x7FFFFFF;
00143
00144 dec->pulseoff[3] = (t >> 0) & 0xF;
00145
00146 dec->offset1[0] |= ((t >> 31) & 1) << 3;
00147
00148 }
00149
00150 static void truespeech_correlate_filter(TSContext *dec)
00151 {
00152 int16_t tmp[8];
00153 int i, j;
00154
00155 for(i = 0; i < 8; i++){
00156 if(i > 0){
00157 memcpy(tmp, dec->cvector, i * 2);
00158 for(j = 0; j < i; j++)
00159 dec->cvector[j] = ((tmp[i - j - 1] * dec->vector[i]) +
00160 (dec->cvector[j] << 15) + 0x4000) >> 15;
00161 }
00162 dec->cvector[i] = (8 - dec->vector[i]) >> 3;
00163 }
00164 for(i = 0; i < 8; i++)
00165 dec->cvector[i] = (dec->cvector[i] * ts_230[i]) >> 15;
00166
00167 dec->filtval = dec->vector[0];
00168 }
00169
00170 static void truespeech_filters_merge(TSContext *dec)
00171 {
00172 int i;
00173
00174 if(!dec->flag){
00175 for(i = 0; i < 8; i++){
00176 dec->filters[i + 0] = dec->prevfilt[i];
00177 dec->filters[i + 8] = dec->prevfilt[i];
00178 }
00179 }else{
00180 for(i = 0; i < 8; i++){
00181 dec->filters[i + 0]=(dec->cvector[i] * 21846 + dec->prevfilt[i] * 10923 + 16384) >> 15;
00182 dec->filters[i + 8]=(dec->cvector[i] * 10923 + dec->prevfilt[i] * 21846 + 16384) >> 15;
00183 }
00184 }
00185 for(i = 0; i < 8; i++){
00186 dec->filters[i + 16] = dec->cvector[i];
00187 dec->filters[i + 24] = dec->cvector[i];
00188 }
00189 }
00190
00191 static void truespeech_apply_twopoint_filter(TSContext *dec, int quart)
00192 {
00193 int16_t tmp[146 + 60], *ptr0, *ptr1;
00194 const int16_t *filter;
00195 int i, t, off;
00196
00197 t = dec->offset2[quart];
00198 if(t == 127){
00199 memset(dec->newvec, 0, 60 * 2);
00200 return;
00201 }
00202 for(i = 0; i < 146; i++)
00203 tmp[i] = dec->filtbuf[i];
00204 off = (t / 25) + dec->offset1[quart >> 1] + 18;
00205 ptr0 = tmp + 145 - off;
00206 ptr1 = tmp + 146;
00207 filter = (const int16_t*)ts_240 + (t % 25) * 2;
00208 for(i = 0; i < 60; i++){
00209 t = (ptr0[0] * filter[0] + ptr0[1] * filter[1] + 0x2000) >> 14;
00210 ptr0++;
00211 dec->newvec[i] = t;
00212 ptr1[i] = t;
00213 }
00214 }
00215
00216 static void truespeech_place_pulses(TSContext *dec, int16_t *out, int quart)
00217 {
00218 int16_t tmp[7];
00219 int i, j, t;
00220 const int16_t *ptr1;
00221 int16_t *ptr2;
00222 int coef;
00223
00224 memset(out, 0, 60 * 2);
00225 for(i = 0; i < 7; i++) {
00226 t = dec->pulseval[quart] & 3;
00227 dec->pulseval[quart] >>= 2;
00228 tmp[6 - i] = ts_562[dec->pulseoff[quart] * 4 + t];
00229 }
00230
00231 coef = dec->pulsepos[quart] >> 15;
00232 ptr1 = (const int16_t*)ts_140 + 30;
00233 ptr2 = tmp;
00234 for(i = 0, j = 3; (i < 30) && (j > 0); i++){
00235 t = *ptr1++;
00236 if(coef >= t)
00237 coef -= t;
00238 else{
00239 out[i] = *ptr2++;
00240 ptr1 += 30;
00241 j--;
00242 }
00243 }
00244 coef = dec->pulsepos[quart] & 0x7FFF;
00245 ptr1 = (const int16_t*)ts_140;
00246 for(i = 30, j = 4; (i < 60) && (j > 0); i++){
00247 t = *ptr1++;
00248 if(coef >= t)
00249 coef -= t;
00250 else{
00251 out[i] = *ptr2++;
00252 ptr1 += 30;
00253 j--;
00254 }
00255 }
00256
00257 }
00258
00259 static void truespeech_update_filters(TSContext *dec, int16_t *out, int quart)
00260 {
00261 int i;
00262
00263 for(i = 0; i < 86; i++)
00264 dec->filtbuf[i] = dec->filtbuf[i + 60];
00265 for(i = 0; i < 60; i++){
00266 dec->filtbuf[i + 86] = out[i] + dec->newvec[i] - (dec->newvec[i] >> 3);
00267 out[i] += dec->newvec[i];
00268 }
00269 }
00270
00271 static void truespeech_synth(TSContext *dec, int16_t *out, int quart)
00272 {
00273 int i,k;
00274 int t[8];
00275 int16_t *ptr0, *ptr1;
00276
00277 ptr0 = dec->tmp1;
00278 ptr1 = dec->filters + quart * 8;
00279 for(i = 0; i < 60; i++){
00280 int sum = 0;
00281 for(k = 0; k < 8; k++)
00282 sum += ptr0[k] * ptr1[k];
00283 sum = (sum + (out[i] << 12) + 0x800) >> 12;
00284 out[i] = av_clip(sum, -0x7FFE, 0x7FFE);
00285 for(k = 7; k > 0; k--)
00286 ptr0[k] = ptr0[k - 1];
00287 ptr0[0] = out[i];
00288 }
00289
00290 for(i = 0; i < 8; i++)
00291 t[i] = (ts_5E2[i] * ptr1[i]) >> 15;
00292
00293 ptr0 = dec->tmp2;
00294 for(i = 0; i < 60; i++){
00295 int sum = 0;
00296 for(k = 0; k < 8; k++)
00297 sum += ptr0[k] * t[k];
00298 for(k = 7; k > 0; k--)
00299 ptr0[k] = ptr0[k - 1];
00300 ptr0[0] = out[i];
00301 out[i] = ((out[i] << 12) - sum) >> 12;
00302 }
00303
00304 for(i = 0; i < 8; i++)
00305 t[i] = (ts_5F2[i] * ptr1[i]) >> 15;
00306
00307 ptr0 = dec->tmp3;
00308 for(i = 0; i < 60; i++){
00309 int sum = out[i] << 12;
00310 for(k = 0; k < 8; k++)
00311 sum += ptr0[k] * t[k];
00312 for(k = 7; k > 0; k--)
00313 ptr0[k] = ptr0[k - 1];
00314 ptr0[0] = av_clip((sum + 0x800) >> 12, -0x7FFE, 0x7FFE);
00315
00316 sum = ((ptr0[1] * (dec->filtval - (dec->filtval >> 2))) >> 4) + sum;
00317 sum = sum - (sum >> 3);
00318 out[i] = av_clip((sum + 0x800) >> 12, -0x7FFE, 0x7FFE);
00319 }
00320 }
00321
00322 static void truespeech_save_prevvec(TSContext *c)
00323 {
00324 int i;
00325
00326 for(i = 0; i < 8; i++)
00327 c->prevfilt[i] = c->cvector[i];
00328 }
00329
00330 static int truespeech_decode_frame(AVCodecContext *avctx,
00331 void *data, int *data_size,
00332 const uint8_t *buf, int buf_size)
00333 {
00334 TSContext *c = avctx->priv_data;
00335
00336 int i, j;
00337 short *samples = data;
00338 int consumed = 0;
00339 int16_t out_buf[240];
00340 int iterations;
00341
00342 if (!buf_size)
00343 return 0;
00344
00345 iterations = FFMIN(buf_size / 32, *data_size / 480);
00346 for(j = 0; j < iterations; j++) {
00347 truespeech_read_frame(c, buf + consumed);
00348 consumed += 32;
00349
00350 truespeech_correlate_filter(c);
00351 truespeech_filters_merge(c);
00352
00353 memset(out_buf, 0, 240 * 2);
00354 for(i = 0; i < 4; i++) {
00355 truespeech_apply_twopoint_filter(c, i);
00356 truespeech_place_pulses(c, out_buf + i * 60, i);
00357 truespeech_update_filters(c, out_buf + i * 60, i);
00358 truespeech_synth(c, out_buf + i * 60, i);
00359 }
00360
00361 truespeech_save_prevvec(c);
00362
00363
00364 for(i = 0; i < 240; i++)
00365 *samples++ = out_buf[i];
00366
00367 }
00368
00369 *data_size = consumed * 15;
00370
00371 return consumed;
00372 }
00373
00374 AVCodec truespeech_decoder = {
00375 "truespeech",
00376 CODEC_TYPE_AUDIO,
00377 CODEC_ID_TRUESPEECH,
00378 sizeof(TSContext),
00379 truespeech_decode_init,
00380 NULL,
00381 NULL,
00382 truespeech_decode_frame,
00383 };