| @@ -21,6 +21,8 @@ | |||
| #include "libavutil/intreadwrite.h" | |||
| #include "avcodec.h" | |||
| #include "dsputil.h" | |||
| #include "get_bits.h" | |||
| #include "truespeech_data.h" | |||
| /** | |||
| @@ -32,7 +34,9 @@ | |||
| * TrueSpeech decoder context | |||
| */ | |||
| typedef struct { | |||
| DSPContext dsp; | |||
| /* input data */ | |||
| uint8_t buffer[32]; | |||
| int16_t vector[8]; ///< input vector: 5/5/4/4/4/3/3/3 | |||
| int offset1[2]; ///< 8-bit value, used in one copying offset | |||
| int offset2[4]; ///< 7-bit value, encodes offsets for copying and for two-point filter | |||
| @@ -54,7 +58,7 @@ typedef struct { | |||
| static av_cold int truespeech_decode_init(AVCodecContext * avctx) | |||
| { | |||
| // TSContext *c = avctx->priv_data; | |||
| TSContext *c = avctx->priv_data; | |||
| if (avctx->channels != 1) { | |||
| av_log_ask_for_sample(avctx, "Unsupported channel count: %d\n", avctx->channels); | |||
| @@ -62,97 +66,58 @@ static av_cold int truespeech_decode_init(AVCodecContext * avctx) | |||
| } | |||
| avctx->sample_fmt = AV_SAMPLE_FMT_S16; | |||
| dsputil_init(&c->dsp, avctx); | |||
| return 0; | |||
| } | |||
| static void truespeech_read_frame(TSContext *dec, const uint8_t *input) | |||
| { | |||
| uint32_t t; | |||
| /* first dword */ | |||
| t = AV_RL32(input); | |||
| input += 4; | |||
| dec->flag = t & 1; | |||
| dec->vector[0] = ts_codebook[0][(t >> 1) & 0x1F]; | |||
| dec->vector[1] = ts_codebook[1][(t >> 6) & 0x1F]; | |||
| dec->vector[2] = ts_codebook[2][(t >> 11) & 0xF]; | |||
| dec->vector[3] = ts_codebook[3][(t >> 15) & 0xF]; | |||
| dec->vector[4] = ts_codebook[4][(t >> 19) & 0xF]; | |||
| dec->vector[5] = ts_codebook[5][(t >> 23) & 0x7]; | |||
| dec->vector[6] = ts_codebook[6][(t >> 26) & 0x7]; | |||
| dec->vector[7] = ts_codebook[7][(t >> 29) & 0x7]; | |||
| /* second dword */ | |||
| t = AV_RL32(input); | |||
| input += 4; | |||
| dec->offset2[0] = (t >> 0) & 0x7F; | |||
| dec->offset2[1] = (t >> 7) & 0x7F; | |||
| dec->offset2[2] = (t >> 14) & 0x7F; | |||
| dec->offset2[3] = (t >> 21) & 0x7F; | |||
| dec->offset1[0] = ((t >> 28) & 0xF) << 4; | |||
| /* third dword */ | |||
| t = AV_RL32(input); | |||
| input += 4; | |||
| dec->pulseval[0] = (t >> 0) & 0x3FFF; | |||
| dec->pulseval[1] = (t >> 14) & 0x3FFF; | |||
| dec->offset1[1] = (t >> 28) & 0x0F; | |||
| /* fourth dword */ | |||
| t = AV_RL32(input); | |||
| input += 4; | |||
| dec->pulseval[2] = (t >> 0) & 0x3FFF; | |||
| dec->pulseval[3] = (t >> 14) & 0x3FFF; | |||
| dec->offset1[1] |= ((t >> 28) & 0x0F) << 4; | |||
| /* fifth dword */ | |||
| t = AV_RL32(input); | |||
| input += 4; | |||
| dec->pulsepos[0] = (t >> 4) & 0x7FFFFFF; | |||
| dec->pulseoff[0] = (t >> 0) & 0xF; | |||
| dec->offset1[0] |= (t >> 31) & 1; | |||
| /* sixth dword */ | |||
| t = AV_RL32(input); | |||
| input += 4; | |||
| dec->pulsepos[1] = (t >> 4) & 0x7FFFFFF; | |||
| dec->pulseoff[1] = (t >> 0) & 0xF; | |||
| dec->offset1[0] |= ((t >> 31) & 1) << 1; | |||
| /* seventh dword */ | |||
| t = AV_RL32(input); | |||
| input += 4; | |||
| dec->pulsepos[2] = (t >> 4) & 0x7FFFFFF; | |||
| dec->pulseoff[2] = (t >> 0) & 0xF; | |||
| dec->offset1[0] |= ((t >> 31) & 1) << 2; | |||
| /* eighth dword */ | |||
| t = AV_RL32(input); | |||
| input += 4; | |||
| dec->pulsepos[3] = (t >> 4) & 0x7FFFFFF; | |||
| dec->pulseoff[3] = (t >> 0) & 0xF; | |||
| dec->offset1[0] |= ((t >> 31) & 1) << 3; | |||
| GetBitContext gb; | |||
| dec->dsp.bswap_buf((uint32_t *)dec->buffer, (const uint32_t *)input, 8); | |||
| init_get_bits(&gb, dec->buffer, 32 * 8); | |||
| dec->vector[7] = ts_codebook[7][get_bits(&gb, 3)]; | |||
| dec->vector[6] = ts_codebook[6][get_bits(&gb, 3)]; | |||
| dec->vector[5] = ts_codebook[5][get_bits(&gb, 3)]; | |||
| dec->vector[4] = ts_codebook[4][get_bits(&gb, 4)]; | |||
| dec->vector[3] = ts_codebook[3][get_bits(&gb, 4)]; | |||
| dec->vector[2] = ts_codebook[2][get_bits(&gb, 4)]; | |||
| dec->vector[1] = ts_codebook[1][get_bits(&gb, 5)]; | |||
| dec->vector[0] = ts_codebook[0][get_bits(&gb, 5)]; | |||
| dec->flag = get_bits1(&gb); | |||
| dec->offset1[0] = get_bits(&gb, 4) << 4; | |||
| dec->offset2[3] = get_bits(&gb, 7); | |||
| dec->offset2[2] = get_bits(&gb, 7); | |||
| dec->offset2[1] = get_bits(&gb, 7); | |||
| dec->offset2[0] = get_bits(&gb, 7); | |||
| dec->offset1[1] = get_bits(&gb, 4); | |||
| dec->pulseval[1] = get_bits(&gb, 14); | |||
| dec->pulseval[0] = get_bits(&gb, 14); | |||
| dec->offset1[1] |= get_bits(&gb, 4) << 4; | |||
| dec->pulseval[3] = get_bits(&gb, 14); | |||
| dec->pulseval[2] = get_bits(&gb, 14); | |||
| dec->offset1[0] |= get_bits1(&gb); | |||
| dec->pulsepos[0] = get_bits_long(&gb, 27); | |||
| dec->pulseoff[0] = get_bits(&gb, 4); | |||
| dec->offset1[0] |= get_bits1(&gb) << 1; | |||
| dec->pulsepos[1] = get_bits_long(&gb, 27); | |||
| dec->pulseoff[1] = get_bits(&gb, 4); | |||
| dec->offset1[0] |= get_bits1(&gb) << 2; | |||
| dec->pulsepos[2] = get_bits_long(&gb, 27); | |||
| dec->pulseoff[2] = get_bits(&gb, 4); | |||
| dec->offset1[0] |= get_bits1(&gb) << 3; | |||
| dec->pulsepos[3] = get_bits_long(&gb, 27); | |||
| dec->pulseoff[3] = get_bits(&gb, 4); | |||
| } | |||
| static void truespeech_correlate_filter(TSContext *dec) | |||