PageRenderTime 52ms CodeModel.GetById 12ms app.highlight 36ms RepoModel.GetById 1ms app.codeStats 0ms

/libavcodec/truespeech.c

http://github.com/FFmpeg/FFmpeg
C | 365 lines | 282 code | 53 blank | 30 comment | 38 complexity | 1b60df6c226933b782ae5f2c8e65ddf9 MD5 | raw 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
 22#include "libavutil/channel_layout.h"
 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 */
 38typedef struct TSContext {
 39    BswapDSPContext bdsp;
 40    /* input data */
 41    DECLARE_ALIGNED(16, uint8_t, buffer)[32];
 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
 61static av_cold int truespeech_decode_init(AVCodecContext * avctx)
 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
 70    avctx->channel_layout = AV_CH_LAYOUT_MONO;
 71    avctx->sample_fmt     = AV_SAMPLE_FMT_S16;
 72
 73    ff_bswapdsp_init(&c->bdsp);
 74
 75    return 0;
 76}
 77
 78static 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
126static void truespeech_correlate_filter(TSContext *dec)
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
145static void truespeech_filters_merge(TSContext *dec)
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
166static 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
192static 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
235static 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
246static 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
297static void truespeech_save_prevvec(TSContext *c)
298{
299    int i;
300
301    for(i = 0; i < 8; i++)
302        c->prevfilt[i] = c->cvector[i];
303}
304
305static 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
337        truespeech_correlate_filter(c);
338        truespeech_filters_merge(c);
339
340        for(i = 0; i < 4; i++) {
341            truespeech_apply_twopoint_filter(c, 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
348        truespeech_save_prevvec(c);
349    }
350
351    *got_frame_ptr = 1;
352
353    return buf_size;
354}
355
356AVCodec ff_truespeech_decoder = {
357    .name           = "truespeech",
358    .long_name      = NULL_IF_CONFIG_SMALL("DSP Group TrueSpeech"),
359    .type           = AVMEDIA_TYPE_AUDIO,
360    .id             = AV_CODEC_ID_TRUESPEECH,
361    .priv_data_size = sizeof(TSContext),
362    .init           = truespeech_decode_init,
363    .decode         = truespeech_decode_frame,
364    .capabilities   = AV_CODEC_CAP_DR1,
365};