FFmpeg
truespeech.c
Go to the documentation of this file.
1 /*
2  * DSP Group TrueSpeech compatible decoder
3  * Copyright (c) 2005 Konstantin Shishkov
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
23 #include "libavutil/intreadwrite.h"
24 #include "avcodec.h"
25 #include "bswapdsp.h"
26 #include "get_bits.h"
27 #include "internal.h"
28 
29 #include "truespeech_data.h"
30 /**
31  * @file
32  * TrueSpeech decoder.
33  */
34 
35 /**
36  * TrueSpeech decoder context
37  */
38 typedef struct TSContext {
40  /* input data */
42  int16_t vector[8]; ///< input vector: 5/5/4/4/4/3/3/3
43  int offset1[2]; ///< 8-bit value, used in one copying offset
44  int offset2[4]; ///< 7-bit value, encodes offsets for copying and for two-point filter
45  int pulseoff[4]; ///< 4-bit offset of pulse values block
46  int pulsepos[4]; ///< 27-bit variable, encodes 7 pulse positions
47  int pulseval[4]; ///< 7x2-bit pulse values
48  int flag; ///< 1-bit flag, shows how to choose filters
49  /* temporary data */
50  int filtbuf[146]; // some big vector used for storing filters
51  int prevfilt[8]; // filter from previous frame
52  int16_t tmp1[8]; // coefficients for adding to out
53  int16_t tmp2[8]; // coefficients for adding to out
54  int16_t tmp3[8]; // coefficients for adding to out
55  int16_t cvector[8]; // correlated input vector
56  int filtval; // gain value for one function
57  int16_t newvec[60]; // tmp vector
58  int16_t filters[32]; // filters for every subframe
59 } TSContext;
60 
62 {
63  TSContext *c = avctx->priv_data;
64 
65  if (avctx->channels != 1) {
66  avpriv_request_sample(avctx, "Channel count %d", avctx->channels);
67  return AVERROR_PATCHWELCOME;
68  }
69 
72 
74 
75  return 0;
76 }
77 
78 static void truespeech_read_frame(TSContext *dec, const uint8_t *input)
79 {
80  GetBitContext gb;
81 
82  dec->bdsp.bswap_buf((uint32_t *) dec->buffer, (const uint32_t *) input, 8);
83  init_get_bits(&gb, dec->buffer, 32 * 8);
84 
85  dec->vector[7] = ts_codebook[7][get_bits(&gb, 3)];
86  dec->vector[6] = ts_codebook[6][get_bits(&gb, 3)];
87  dec->vector[5] = ts_codebook[5][get_bits(&gb, 3)];
88  dec->vector[4] = ts_codebook[4][get_bits(&gb, 4)];
89  dec->vector[3] = ts_codebook[3][get_bits(&gb, 4)];
90  dec->vector[2] = ts_codebook[2][get_bits(&gb, 4)];
91  dec->vector[1] = ts_codebook[1][get_bits(&gb, 5)];
92  dec->vector[0] = ts_codebook[0][get_bits(&gb, 5)];
93  dec->flag = get_bits1(&gb);
94 
95  dec->offset1[0] = get_bits(&gb, 4) << 4;
96  dec->offset2[3] = get_bits(&gb, 7);
97  dec->offset2[2] = get_bits(&gb, 7);
98  dec->offset2[1] = get_bits(&gb, 7);
99  dec->offset2[0] = get_bits(&gb, 7);
100 
101  dec->offset1[1] = get_bits(&gb, 4);
102  dec->pulseval[1] = get_bits(&gb, 14);
103  dec->pulseval[0] = get_bits(&gb, 14);
104 
105  dec->offset1[1] |= get_bits(&gb, 4) << 4;
106  dec->pulseval[3] = get_bits(&gb, 14);
107  dec->pulseval[2] = get_bits(&gb, 14);
108 
109  dec->offset1[0] |= get_bits1(&gb);
110  dec->pulsepos[0] = get_bits_long(&gb, 27);
111  dec->pulseoff[0] = get_bits(&gb, 4);
112 
113  dec->offset1[0] |= get_bits1(&gb) << 1;
114  dec->pulsepos[1] = get_bits_long(&gb, 27);
115  dec->pulseoff[1] = get_bits(&gb, 4);
116 
117  dec->offset1[0] |= get_bits1(&gb) << 2;
118  dec->pulsepos[2] = get_bits_long(&gb, 27);
119  dec->pulseoff[2] = get_bits(&gb, 4);
120 
121  dec->offset1[0] |= get_bits1(&gb) << 3;
122  dec->pulsepos[3] = get_bits_long(&gb, 27);
123  dec->pulseoff[3] = get_bits(&gb, 4);
124 }
125 
127 {
128  int16_t tmp[8];
129  int i, j;
130 
131  for(i = 0; i < 8; i++){
132  if(i > 0){
133  memcpy(tmp, dec->cvector, i * sizeof(*tmp));
134  for(j = 0; j < i; j++)
135  dec->cvector[j] += (tmp[i - j - 1] * dec->vector[i] + 0x4000) >> 15;
136  }
137  dec->cvector[i] = (8 - dec->vector[i]) >> 3;
138  }
139  for(i = 0; i < 8; i++)
140  dec->cvector[i] = (dec->cvector[i] * ts_decay_994_1000[i]) >> 15;
141 
142  dec->filtval = dec->vector[0];
143 }
144 
146 {
147  int i;
148 
149  if(!dec->flag){
150  for(i = 0; i < 8; i++){
151  dec->filters[i + 0] = dec->prevfilt[i];
152  dec->filters[i + 8] = dec->prevfilt[i];
153  }
154  }else{
155  for(i = 0; i < 8; i++){
156  dec->filters[i + 0]=(dec->cvector[i] * 21846 + dec->prevfilt[i] * 10923 + 16384) >> 15;
157  dec->filters[i + 8]=(dec->cvector[i] * 10923 + dec->prevfilt[i] * 21846 + 16384) >> 15;
158  }
159  }
160  for(i = 0; i < 8; i++){
161  dec->filters[i + 16] = dec->cvector[i];
162  dec->filters[i + 24] = dec->cvector[i];
163  }
164 }
165 
166 static void truespeech_apply_twopoint_filter(TSContext *dec, int quart)
167 {
168  int16_t tmp[146 + 60], *ptr0, *ptr1;
169  const int16_t *filter;
170  int i, t, off;
171 
172  t = dec->offset2[quart];
173  if(t == 127){
174  memset(dec->newvec, 0, 60 * sizeof(*dec->newvec));
175  return;
176  }
177  for(i = 0; i < 146; i++)
178  tmp[i] = dec->filtbuf[i];
179  off = (t / 25) + dec->offset1[quart >> 1] + 18;
180  off = av_clip(off, 0, 145);
181  ptr0 = tmp + 145 - off;
182  ptr1 = tmp + 146;
183  filter = ts_order2_coeffs + (t % 25) * 2;
184  for(i = 0; i < 60; i++){
185  t = (ptr0[0] * filter[0] + ptr0[1] * filter[1] + 0x2000) >> 14;
186  ptr0++;
187  dec->newvec[i] = t;
188  ptr1[i] = t;
189  }
190 }
191 
192 static void truespeech_place_pulses(TSContext *dec, int16_t *out, int quart)
193 {
194  int16_t tmp[7];
195  int i, j, t;
196  const int16_t *ptr1;
197  int16_t *ptr2;
198  int coef;
199 
200  memset(out, 0, 60 * sizeof(*out));
201  for(i = 0; i < 7; i++) {
202  t = dec->pulseval[quart] & 3;
203  dec->pulseval[quart] >>= 2;
204  tmp[6 - i] = ts_pulse_scales[dec->pulseoff[quart] * 4 + t];
205  }
206 
207  coef = dec->pulsepos[quart] >> 15;
208  ptr1 = ts_pulse_values + 30;
209  ptr2 = tmp;
210  for(i = 0, j = 3; (i < 30) && (j > 0); i++){
211  t = *ptr1++;
212  if(coef >= t)
213  coef -= t;
214  else{
215  out[i] = *ptr2++;
216  ptr1 += 30;
217  j--;
218  }
219  }
220  coef = dec->pulsepos[quart] & 0x7FFF;
221  ptr1 = ts_pulse_values;
222  for(i = 30, j = 4; (i < 60) && (j > 0); i++){
223  t = *ptr1++;
224  if(coef >= t)
225  coef -= t;
226  else{
227  out[i] = *ptr2++;
228  ptr1 += 30;
229  j--;
230  }
231  }
232 
233 }
234 
235 static void truespeech_update_filters(TSContext *dec, int16_t *out, int quart)
236 {
237  int i;
238 
239  memmove(dec->filtbuf, &dec->filtbuf[60], 86 * sizeof(*dec->filtbuf));
240  for(i = 0; i < 60; i++){
241  dec->filtbuf[i + 86] = out[i] + dec->newvec[i] - (dec->newvec[i] >> 3);
242  out[i] += dec->newvec[i];
243  }
244 }
245 
246 static void truespeech_synth(TSContext *dec, int16_t *out, int quart)
247 {
248  int i,k;
249  int t[8];
250  int16_t *ptr0, *ptr1;
251 
252  ptr0 = dec->tmp1;
253  ptr1 = dec->filters + quart * 8;
254  for(i = 0; i < 60; i++){
255  int sum = 0;
256  for(k = 0; k < 8; k++)
257  sum += ptr0[k] * (unsigned)ptr1[k];
258  sum = out[i] + ((sum + 0x800) >> 12);
259  out[i] = av_clip(sum, -0x7FFE, 0x7FFE);
260  for(k = 7; k > 0; k--)
261  ptr0[k] = ptr0[k - 1];
262  ptr0[0] = out[i];
263  }
264 
265  for(i = 0; i < 8; i++)
266  t[i] = (ts_decay_35_64[i] * ptr1[i]) >> 15;
267 
268  ptr0 = dec->tmp2;
269  for(i = 0; i < 60; i++){
270  int sum = 0;
271  for(k = 0; k < 8; k++)
272  sum += ptr0[k] * t[k];
273  for(k = 7; k > 0; k--)
274  ptr0[k] = ptr0[k - 1];
275  ptr0[0] = out[i];
276  out[i] += (- sum) >> 12;
277  }
278 
279  for(i = 0; i < 8; i++)
280  t[i] = (ts_decay_3_4[i] * ptr1[i]) >> 15;
281 
282  ptr0 = dec->tmp3;
283  for(i = 0; i < 60; i++){
284  int sum = out[i] * (1 << 12);
285  for(k = 0; k < 8; k++)
286  sum += ptr0[k] * t[k];
287  for(k = 7; k > 0; k--)
288  ptr0[k] = ptr0[k - 1];
289  ptr0[0] = av_clip((sum + 0x800) >> 12, -0x7FFE, 0x7FFE);
290 
291  sum = ((ptr0[1] * (dec->filtval - (dec->filtval >> 2))) >> 4) + sum;
292  sum = sum - (sum >> 3);
293  out[i] = av_clip((sum + 0x800) >> 12, -0x7FFE, 0x7FFE);
294  }
295 }
296 
298 {
299  int i;
300 
301  for(i = 0; i < 8; i++)
302  c->prevfilt[i] = c->cvector[i];
303 }
304 
305 static int truespeech_decode_frame(AVCodecContext *avctx, void *data,
306  int *got_frame_ptr, AVPacket *avpkt)
307 {
308  AVFrame *frame = data;
309  const uint8_t *buf = avpkt->data;
310  int buf_size = avpkt->size;
311  TSContext *c = avctx->priv_data;
312 
313  int i, j;
314  int16_t *samples;
315  int iterations, ret;
316 
317  iterations = buf_size / 32;
318 
319  if (!iterations) {
320  av_log(avctx, AV_LOG_ERROR,
321  "Too small input buffer (%d bytes), need at least 32 bytes\n", buf_size);
322  return -1;
323  }
324 
325  /* get output buffer */
326  frame->nb_samples = iterations * 240;
327  if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
328  return ret;
329  samples = (int16_t *)frame->data[0];
330 
331  memset(samples, 0, iterations * 240 * sizeof(*samples));
332 
333  for(j = 0; j < iterations; j++) {
334  truespeech_read_frame(c, buf);
335  buf += 32;
336 
339 
340  for(i = 0; i < 4; i++) {
342  truespeech_place_pulses (c, samples, i);
343  truespeech_update_filters(c, samples, i);
344  truespeech_synth (c, samples, i);
345  samples += 60;
346  }
347 
349  }
350 
351  *got_frame_ptr = 1;
352 
353  return buf_size;
354 }
355 
357  .name = "truespeech",
358  .long_name = NULL_IF_CONFIG_SMALL("DSP Group TrueSpeech"),
359  .type = AVMEDIA_TYPE_AUDIO,
361  .priv_data_size = sizeof(TSContext),
364  .capabilities = AV_CODEC_CAP_DR1,
365 };
int pulseval[4]
7x2-bit pulse values
Definition: truespeech.c:47
static const int16_t ts_decay_994_1000[8]
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
static void truespeech_update_filters(TSContext *dec, int16_t *out, int quart)
Definition: truespeech.c:235
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
static int truespeech_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt)
Definition: truespeech.c:305
static void truespeech_correlate_filter(TSContext *dec)
Definition: truespeech.c:126
AVCodec ff_truespeech_decoder
Definition: truespeech.c:356
static void truespeech_apply_twopoint_filter(TSContext *dec, int quart)
Definition: truespeech.c:166
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:379
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
#define avpriv_request_sample(...)
int16_t filters[32]
Definition: truespeech.c:58
int size
Definition: avcodec.h:1481
static void truespeech_filters_merge(TSContext *dec)
Definition: truespeech.c:145
int filtval
Definition: truespeech.c:56
AVCodec.
Definition: avcodec.h:3492
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:71
static void truespeech_read_frame(TSContext *dec, const uint8_t *input)
Definition: truespeech.c:78
int16_t tmp1[8]
Definition: truespeech.c:52
BswapDSPContext bdsp
Definition: truespeech.c:39
enum AVSampleFormat sample_fmt
audio sample format
Definition: avcodec.h:2236
uint8_t
#define av_cold
Definition: attributes.h:82
void(* bswap_buf)(uint32_t *dst, const uint32_t *src, int w)
Definition: bswapdsp.h:25
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
static av_cold int truespeech_decode_init(AVCodecContext *avctx)
Definition: truespeech.c:61
#define DECLARE_ALIGNED(n, t, v)
Declare a variable that is aligned in memory.
Definition: mem.h:112
uint8_t * data
Definition: avcodec.h:1480
bitstream reader API header.
static const int16_t *const ts_codebook[8]
static const int16_t ts_order2_coeffs[25 *2]
#define av_log(a,...)
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce then the filter should push the output frames on the output link immediately As an exception to the previous rule if the input frame is enough to produce several output frames then the filter needs output only at least one per link The additional frames can be left buffered in the filter
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
const char * name
Name of the codec implementation.
Definition: avcodec.h:3499
static const int16_t ts_pulse_values[120]
uint64_t channel_layout
Audio channel layout.
Definition: avcodec.h:2279
int pulsepos[4]
27-bit variable, encodes 7 pulse positions
Definition: truespeech.c:46
int16_t tmp3[8]
Definition: truespeech.c:54
int16_t vector[8]
input vector: 5/5/4/4/4/3/3/3
Definition: truespeech.c:42
audio channel layout utility functions
int16_t tmp2[8]
Definition: truespeech.c:53
int16_t cvector[8]
Definition: truespeech.c:55
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
TrueSpeech decoder context.
Definition: truespeech.c:38
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
int offset2[4]
7-bit value, encodes offsets for copying and for two-point filter
Definition: truespeech.c:44
int prevfilt[8]
Definition: truespeech.c:51
Libavcodec external API header.
static const int16_t ts_decay_3_4[8]
main external API structure.
Definition: avcodec.h:1568
int offset1[2]
8-bit value, used in one copying offset
Definition: truespeech.c:43
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1968
int16_t newvec[60]
Definition: truespeech.c:57
void * buf
Definition: avisynth_c.h:766
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:498
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:659
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
static unsigned int get_bits_long(GetBitContext *s, int n)
Read 0-32 bits.
Definition: get_bits.h:546
static void truespeech_synth(TSContext *dec, int16_t *out, int quart)
Definition: truespeech.c:246
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:309
int filtbuf[146]
Definition: truespeech.c:50
int pulseoff[4]
4-bit offset of pulse values block
Definition: truespeech.c:45
common internal api header.
signed 16 bits
Definition: samplefmt.h:61
static const int16_t ts_decay_35_64[8]
int flag
1-bit flag, shows how to choose filters
Definition: truespeech.c:48
av_cold void ff_bswapdsp_init(BswapDSPContext *c)
Definition: bswapdsp.c:49
void * priv_data
Definition: avcodec.h:1595
int channels
number of audio channels
Definition: avcodec.h:2229
static void truespeech_place_pulses(TSContext *dec, int16_t *out, int quart)
Definition: truespeech.c:192
FILE * out
Definition: movenc.c:54
Filter the word “frame” indicates either a video frame or a group of audio samples
static const int16_t ts_pulse_scales[64]
#define AV_CH_LAYOUT_MONO
This structure stores compressed data.
Definition: avcodec.h:1457
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:361
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: avcodec.h:984
static void truespeech_save_prevvec(TSContext *c)
Definition: truespeech.c:297
GLuint buffer
Definition: opengl_enc.c:101
uint8_t buffer[32]
Definition: truespeech.c:41
static uint8_t tmp[11]
Definition: aes_ctr.c:26