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 
73  ff_bswapdsp_init(&c->bdsp);
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] + ((int)(sum + 0x800U) >> 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++) {
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 };
AVCodec
AVCodec.
Definition: codec.h:190
bswapdsp.h
init
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
AVCodecContext::channel_layout
uint64_t channel_layout
Audio channel layout.
Definition: avcodec.h:1237
out
FILE * out
Definition: movenc.c:54
truespeech_decode_init
static av_cold int truespeech_decode_init(AVCodecContext *avctx)
Definition: truespeech.c:61
AV_CH_LAYOUT_MONO
#define AV_CH_LAYOUT_MONO
Definition: channel_layout.h:85
get_bits_long
static unsigned int get_bits_long(GetBitContext *s, int n)
Read 0-32 bits.
Definition: get_bits.h:546
TSContext::flag
int flag
1-bit flag, shows how to choose filters
Definition: truespeech.c:48
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:300
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:26
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:355
TSContext::filters
int16_t filters[32]
Definition: truespeech.c:58
data
const char data[16]
Definition: mxf.c:91
TSContext::pulseoff
int pulseoff[4]
4-bit offset of pulse values block
Definition: truespeech.c:45
TSContext::tmp1
int16_t tmp1[8]
Definition: truespeech.c:52
filter
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
Definition: filter_design.txt:228
TSContext::filtval
int filtval
Definition: truespeech.c:56
init_get_bits
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:659
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:379
GetBitContext
Definition: get_bits.h:61
TSContext::offset2
int offset2[4]
7-bit value, encodes offsets for copying and for two-point filter
Definition: truespeech.c:44
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
av_cold
#define av_cold
Definition: attributes.h:90
decode
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:71
TSContext::pulsepos
int pulsepos[4]
27-bit variable, encodes 7 pulse positions
Definition: truespeech.c:46
intreadwrite.h
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
BswapDSPContext::bswap_buf
void(* bswap_buf)(uint32_t *dst, const uint32_t *src, int w)
Definition: bswapdsp.h:25
TSContext::tmp2
int16_t tmp2[8]
Definition: truespeech.c:53
get_bits.h
truespeech_read_frame
static void truespeech_read_frame(TSContext *dec, const uint8_t *input)
Definition: truespeech.c:78
truespeech_update_filters
static void truespeech_update_filters(TSContext *dec, int16_t *out, int quart)
Definition: truespeech.c:235
ff_bswapdsp_init
av_cold void ff_bswapdsp_init(BswapDSPContext *c)
Definition: bswapdsp.c:49
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
ts_decay_35_64
static const int16_t ts_decay_35_64[8]
Definition: truespeech_data.h:154
get_bits1
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:498
ts_decay_3_4
static const int16_t ts_decay_3_4[8]
Definition: truespeech_data.h:156
ts_pulse_scales
static const int16_t ts_pulse_scales[64]
Definition: truespeech_data.h:134
truespeech_place_pulses
static void truespeech_place_pulses(TSContext *dec, int16_t *out, int quart)
Definition: truespeech.c:192
c
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
truespeech_data.h
TSContext::offset1
int offset1[2]
8-bit value, used in one copying offset
Definition: truespeech.c:43
ff_get_buffer
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1854
AV_CODEC_CAP_DR1
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:50
AVPacket::size
int size
Definition: packet.h:356
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:188
AVCodecContext::sample_fmt
enum AVSampleFormat sample_fmt
audio sample format
Definition: avcodec.h:1194
ff_truespeech_decoder
AVCodec ff_truespeech_decoder
Definition: truespeech.c:356
TSContext::prevfilt
int prevfilt[8]
Definition: truespeech.c:51
TSContext::tmp3
int16_t tmp3[8]
Definition: truespeech.c:54
TSContext::vector
int16_t vector[8]
input vector: 5/5/4/4/4/3/3/3
Definition: truespeech.c:42
input
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
Definition: filter_design.txt:172
AVCodecContext::channels
int channels
number of audio channels
Definition: avcodec.h:1187
DECLARE_ALIGNED
#define DECLARE_ALIGNED(n, t, v)
Definition: mem.h:112
ts_decay_994_1000
static const int16_t ts_decay_994_1000[8]
Definition: truespeech_data.h:97
ts_order2_coeffs
static const int16_t ts_order2_coeffs[25 *2]
Definition: truespeech_data.h:101
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
uint8_t
uint8_t
Definition: audio_convert.c:194
TSContext
TrueSpeech decoder context.
Definition: truespeech.c:38
AV_SAMPLE_FMT_S16
@ AV_SAMPLE_FMT_S16
signed 16 bits
Definition: samplefmt.h:61
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:197
truespeech_filters_merge
static void truespeech_filters_merge(TSContext *dec)
Definition: truespeech.c:145
ts_codebook
static const int16_t *const ts_codebook[8]
Definition: truespeech_data.h:69
avcodec.h
ret
ret
Definition: filter_design.txt:187
frame
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
Definition: filter_design.txt:264
TSContext::newvec
int16_t newvec[60]
Definition: truespeech.c:57
AVCodecContext
main external API structure.
Definition: avcodec.h:526
TSContext::cvector
int16_t cvector[8]
Definition: truespeech.c:55
truespeech_save_prevvec
static void truespeech_save_prevvec(TSContext *c)
Definition: truespeech.c:297
channel_layout.h
samples
Filter the word “frame” indicates either a video frame or a group of audio samples
Definition: filter_design.txt:8
AV_CODEC_ID_TRUESPEECH
@ AV_CODEC_ID_TRUESPEECH
Definition: codec_id.h:431
TSContext::bdsp
BswapDSPContext bdsp
Definition: truespeech.c:39
avpriv_request_sample
#define avpriv_request_sample(...)
Definition: tableprint_vlc.h:39
AVPacket
This structure stores compressed data.
Definition: packet.h:332
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:553
TSContext::pulseval
int pulseval[4]
7x2-bit pulse values
Definition: truespeech.c:47
TSContext::filtbuf
int filtbuf[146]
Definition: truespeech.c:50
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
BswapDSPContext
Definition: bswapdsp.h:24
truespeech_synth
static void truespeech_synth(TSContext *dec, int16_t *out, int quart)
Definition: truespeech.c:246
ts_pulse_values
static const int16_t ts_pulse_values[120]
Definition: truespeech_data.h:74
TSContext::buffer
uint8_t buffer[32]
Definition: truespeech.c:41
int
int
Definition: ffmpeg_filter.c:192
truespeech_decode_frame
static int truespeech_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt)
Definition: truespeech.c:305
truespeech_correlate_filter
static void truespeech_correlate_filter(TSContext *dec)
Definition: truespeech.c:126
truespeech_apply_twopoint_filter
static void truespeech_apply_twopoint_filter(TSContext *dec, int quart)
Definition: truespeech.c:166