2 * DSP Group TrueSpeech compatible decoder
3 * Copyright (c) 2005 Konstantin Shishkov
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "truespeech_data.h"
28 * TrueSpeech decoder context
32 int16_t vector
[8]; //< input vector: 5/5/4/4/4/3/3/3
33 int offset1
[2]; //< 8-bit value, used in one copying offset
34 int offset2
[4]; //< 7-bit value, encodes offsets for copying and for two-point filter
35 int pulseoff
[4]; //< 4-bit offset of pulse values block
36 int pulsepos
[4]; //< 27-bit variable, encodes 7 pulse positions
37 int pulseval
[4]; //< 7x2-bit pulse values
38 int flag
; //< 1-bit flag, shows how to choose filters
40 int filtbuf
[146]; // some big vector used for storing filters
41 int prevfilt
[8]; // filter from previous frame
42 int16_t tmp1
[8]; // coefficients for adding to out
43 int16_t tmp2
[8]; // coefficients for adding to out
44 int16_t tmp3
[8]; // coefficients for adding to out
45 int16_t cvector
[8]; // correlated input vector
46 int filtval
; // gain value for one function
47 int16_t newvec
[60]; // tmp vector
48 int16_t filters
[32]; // filters for every subframe
51 static int truespeech_decode_init(AVCodecContext
* avctx
)
53 // TSContext *c = avctx->priv_data;
58 static void truespeech_read_frame(TSContext
*dec
, uint8_t *input
)
68 dec
->vector
[0] = ts_codebook
[0][(t
>> 1) & 0x1F];
69 dec
->vector
[1] = ts_codebook
[1][(t
>> 6) & 0x1F];
70 dec
->vector
[2] = ts_codebook
[2][(t
>> 11) & 0xF];
71 dec
->vector
[3] = ts_codebook
[3][(t
>> 15) & 0xF];
72 dec
->vector
[4] = ts_codebook
[4][(t
>> 19) & 0xF];
73 dec
->vector
[5] = ts_codebook
[5][(t
>> 23) & 0x7];
74 dec
->vector
[6] = ts_codebook
[6][(t
>> 26) & 0x7];
75 dec
->vector
[7] = ts_codebook
[7][(t
>> 29) & 0x7];
81 dec
->offset2
[0] = (t
>> 0) & 0x7F;
82 dec
->offset2
[1] = (t
>> 7) & 0x7F;
83 dec
->offset2
[2] = (t
>> 14) & 0x7F;
84 dec
->offset2
[3] = (t
>> 21) & 0x7F;
86 dec
->offset1
[0] = ((t
>> 28) & 0xF) << 4;
92 dec
->pulseval
[0] = (t
>> 0) & 0x3FFF;
93 dec
->pulseval
[1] = (t
>> 14) & 0x3FFF;
95 dec
->offset1
[1] = (t
>> 28) & 0x0F;
101 dec
->pulseval
[2] = (t
>> 0) & 0x3FFF;
102 dec
->pulseval
[3] = (t
>> 14) & 0x3FFF;
104 dec
->offset1
[1] |= ((t
>> 28) & 0x0F) << 4;
110 dec
->pulsepos
[0] = (t
>> 4) & 0x7FFFFFF;
112 dec
->pulseoff
[0] = (t
>> 0) & 0xF;
114 dec
->offset1
[0] |= (t
>> 31) & 1;
120 dec
->pulsepos
[1] = (t
>> 4) & 0x7FFFFFF;
122 dec
->pulseoff
[1] = (t
>> 0) & 0xF;
124 dec
->offset1
[0] |= ((t
>> 31) & 1) << 1;
130 dec
->pulsepos
[2] = (t
>> 4) & 0x7FFFFFF;
132 dec
->pulseoff
[2] = (t
>> 0) & 0xF;
134 dec
->offset1
[0] |= ((t
>> 31) & 1) << 2;
140 dec
->pulsepos
[3] = (t
>> 4) & 0x7FFFFFF;
142 dec
->pulseoff
[3] = (t
>> 0) & 0xF;
144 dec
->offset1
[0] |= ((t
>> 31) & 1) << 3;
148 static void truespeech_correlate_filter(TSContext
*dec
)
153 for(i
= 0; i
< 8; i
++){
155 memcpy(tmp
, dec
->cvector
, i
* 2);
156 for(j
= 0; j
< i
; j
++)
157 dec
->cvector
[j
] = ((tmp
[i
- j
- 1] * dec
->vector
[i
]) +
158 (dec
->cvector
[j
] << 15) + 0x4000) >> 15;
160 dec
->cvector
[i
] = (8 - dec
->vector
[i
]) >> 3;
162 for(i
= 0; i
< 8; i
++)
163 dec
->cvector
[i
] = (dec
->cvector
[i
] * ts_230
[i
]) >> 15;
165 dec
->filtval
= dec
->vector
[0];
168 static void truespeech_filters_merge(TSContext
*dec
)
173 for(i
= 0; i
< 8; i
++){
174 dec
->filters
[i
+ 0] = dec
->prevfilt
[i
];
175 dec
->filters
[i
+ 8] = dec
->prevfilt
[i
];
178 for(i
= 0; i
< 8; i
++){
179 dec
->filters
[i
+ 0]=(dec
->cvector
[i
] * 21846 + dec
->prevfilt
[i
] * 10923 + 16384) >> 15;
180 dec
->filters
[i
+ 8]=(dec
->cvector
[i
] * 10923 + dec
->prevfilt
[i
] * 21846 + 16384) >> 15;
183 for(i
= 0; i
< 8; i
++){
184 dec
->filters
[i
+ 16] = dec
->cvector
[i
];
185 dec
->filters
[i
+ 24] = dec
->cvector
[i
];
189 static void truespeech_apply_twopoint_filter(TSContext
*dec
, int quart
)
191 int16_t tmp
[146 + 60], *ptr0
, *ptr1
, *filter
;
194 t
= dec
->offset2
[quart
];
196 memset(dec
->newvec
, 0, 60 * 2);
199 for(i
= 0; i
< 146; i
++)
200 tmp
[i
] = dec
->filtbuf
[i
];
201 off
= (t
/ 25) + dec
->offset1
[quart
>> 1] + 18;
202 ptr0
= tmp
+ 145 - off
;
204 filter
= (int16_t*)ts_240
+ (t
% 25) * 2;
205 for(i
= 0; i
< 60; i
++){
206 t
= (ptr0
[0] * filter
[0] + ptr0
[1] * filter
[1] + 0x2000) >> 14;
213 static void truespeech_place_pulses(TSContext
*dec
, int16_t *out
, int quart
)
217 int16_t *ptr1
, *ptr2
;
220 memset(out
, 0, 60 * 2);
221 for(i
= 0; i
< 7; i
++) {
222 t
= dec
->pulseval
[quart
] & 3;
223 dec
->pulseval
[quart
] >>= 2;
224 tmp
[6 - i
] = ts_562
[dec
->pulseoff
[quart
] * 4 + t
];
227 coef
= dec
->pulsepos
[quart
] >> 15;
228 ptr1
= (int16_t*)ts_140
+ 30;
230 for(i
= 0, j
= 3; (i
< 30) && (j
> 0); i
++){
240 coef
= dec
->pulsepos
[quart
] & 0x7FFF;
241 ptr1
= (int16_t*)ts_140
;
242 for(i
= 30, j
= 4; (i
< 60) && (j
> 0); i
++){
255 static void truespeech_update_filters(TSContext
*dec
, int16_t *out
, int quart
)
259 for(i
= 0; i
< 86; i
++)
260 dec
->filtbuf
[i
] = dec
->filtbuf
[i
+ 60];
261 for(i
= 0; i
< 60; i
++){
262 dec
->filtbuf
[i
+ 86] = out
[i
] + dec
->newvec
[i
] - (dec
->newvec
[i
] >> 3);
263 out
[i
] += dec
->newvec
[i
];
267 static void truespeech_synth(TSContext
*dec
, int16_t *out
, int quart
)
271 int16_t *ptr0
, *ptr1
;
274 ptr1
= dec
->filters
+ quart
* 8;
275 for(i
= 0; i
< 60; i
++){
277 for(k
= 0; k
< 8; k
++)
278 sum
+= ptr0
[k
] * ptr1
[k
];
279 sum
= (sum
+ (out
[i
] << 12) + 0x800) >> 12;
280 out
[i
] = clip(sum
, -0x7FFE, 0x7FFE);
281 for(k
= 7; k
> 0; k
--)
282 ptr0
[k
] = ptr0
[k
- 1];
286 for(i
= 0; i
< 8; i
++)
287 t
[i
] = (ts_5E2
[i
] * ptr1
[i
]) >> 15;
290 for(i
= 0; i
< 60; i
++){
292 for(k
= 0; k
< 8; k
++)
293 sum
+= ptr0
[k
] * t
[k
];
294 for(k
= 7; k
> 0; k
--)
295 ptr0
[k
] = ptr0
[k
- 1];
297 out
[i
] = ((out
[i
] << 12) - sum
) >> 12;
300 for(i
= 0; i
< 8; i
++)
301 t
[i
] = (ts_5F2
[i
] * ptr1
[i
]) >> 15;
304 for(i
= 0; i
< 60; i
++){
305 int sum
= out
[i
] << 12;
306 for(k
= 0; k
< 8; k
++)
307 sum
+= ptr0
[k
] * t
[k
];
308 for(k
= 7; k
> 0; k
--)
309 ptr0
[k
] = ptr0
[k
- 1];
310 ptr0
[0] = clip((sum
+ 0x800) >> 12, -0x7FFE, 0x7FFE);
312 sum
= ((ptr0
[1] * (dec
->filtval
- (dec
->filtval
>> 2))) >> 4) + sum
;
313 sum
= sum
- (sum
>> 3);
314 out
[i
] = clip((sum
+ 0x800) >> 12, -0x7FFE, 0x7FFE);
318 static void truespeech_save_prevvec(TSContext
*c
)
322 for(i
= 0; i
< 8; i
++)
323 c
->prevfilt
[i
] = c
->cvector
[i
];
326 static int truespeech_decode_frame(AVCodecContext
*avctx
,
327 void *data
, int *data_size
,
328 uint8_t *buf
, int buf_size
)
330 TSContext
*c
= avctx
->priv_data
;
333 short *samples
= data
;
335 int16_t out_buf
[240];
340 while (consumed
< buf_size
) {
341 truespeech_read_frame(c
, buf
+ consumed
);
344 truespeech_correlate_filter(c
);
345 truespeech_filters_merge(c
);
347 memset(out_buf
, 0, 240 * 2);
348 for(i
= 0; i
< 4; i
++) {
349 truespeech_apply_twopoint_filter(c
, i
);
350 truespeech_place_pulses(c
, out_buf
+ i
* 60, i
);
351 truespeech_update_filters(c
, out_buf
+ i
* 60, i
);
352 truespeech_synth(c
, out_buf
+ i
* 60, i
);
355 truespeech_save_prevvec(c
);
357 /* finally output decoded frame */
358 for(i
= 0; i
< 240; i
++)
359 *samples
++ = out_buf
[i
];
363 *data_size
= consumed
* 15;
368 AVCodec truespeech_decoder
= {
373 truespeech_decode_init
,
376 truespeech_decode_frame
,