* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <inttypes.h>
#include <math.h>
#include <stdint.h>
static int metasound_read_bitstream(AVCodecContext *avctx, TwinVQContext *tctx,
const uint8_t *buf, int buf_size)
{
- TwinVQFrameData *bits = &tctx->bits;
+ TwinVQFrameData *bits;
const TwinVQModeTab *mtab = tctx->mtab;
int channels = tctx->avctx->channels;
int sub;
GetBitContext gb;
int i, j, k;
- if (buf_size * 8 < avctx->bit_rate * mtab->size / avctx->sample_rate) {
- av_log(avctx, AV_LOG_ERROR,
- "Frame too small (%d bytes). Truncated file?\n", buf_size);
- return AVERROR(EINVAL);
- }
-
init_get_bits(&gb, buf, buf_size * 8);
- bits->window_type = get_bits(&gb, TWINVQ_WINDOW_TYPE_BITS);
+ for (tctx->cur_frame = 0; tctx->cur_frame < tctx->frames_per_packet;
+ tctx->cur_frame++) {
+ bits = tctx->bits + tctx->cur_frame;
- if (bits->window_type > 8) {
- av_log(avctx, AV_LOG_ERROR, "Invalid window type, broken sample?\n");
- return AVERROR_INVALIDDATA;
- }
+ bits->window_type = get_bits(&gb, TWINVQ_WINDOW_TYPE_BITS);
- bits->ftype = ff_twinvq_wtype_to_ftype_table[tctx->bits.window_type];
+ if (bits->window_type > 8) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid window type, broken sample?\n");
+ return AVERROR_INVALIDDATA;
+ }
- sub = mtab->fmode[bits->ftype].sub;
+ bits->ftype = ff_twinvq_wtype_to_ftype_table[tctx->bits[tctx->cur_frame].window_type];
- if (bits->ftype != TWINVQ_FT_SHORT)
- get_bits(&gb, 2);
+ sub = mtab->fmode[bits->ftype].sub;
- read_cb_data(tctx, &gb, bits->main_coeffs, bits->ftype);
+ if (bits->ftype != TWINVQ_FT_SHORT && !tctx->is_6kbps)
+ get_bits(&gb, 2);
- for (i = 0; i < channels; i++)
- for (j = 0; j < sub; j++)
- for (k = 0; k < mtab->fmode[bits->ftype].bark_n_coef; k++)
- bits->bark1[i][j][k] =
- get_bits(&gb, mtab->fmode[bits->ftype].bark_n_bit);
+ read_cb_data(tctx, &gb, bits->main_coeffs, bits->ftype);
- for (i = 0; i < channels; i++)
- for (j = 0; j < sub; j++)
- bits->bark_use_hist[i][j] = get_bits1(&gb);
+ for (i = 0; i < channels; i++)
+ for (j = 0; j < sub; j++)
+ for (k = 0; k < mtab->fmode[bits->ftype].bark_n_coef; k++)
+ bits->bark1[i][j][k] =
+ get_bits(&gb, mtab->fmode[bits->ftype].bark_n_bit);
- if (bits->ftype == TWINVQ_FT_LONG) {
for (i = 0; i < channels; i++)
- bits->gain_bits[i] = get_bits(&gb, TWINVQ_GAIN_BITS);
- } else {
- for (i = 0; i < channels; i++) {
- bits->gain_bits[i] = get_bits(&gb, TWINVQ_GAIN_BITS);
for (j = 0; j < sub; j++)
- bits->sub_gain_bits[i * sub + j] =
- get_bits(&gb, TWINVQ_SUB_GAIN_BITS);
+ bits->bark_use_hist[i][j] = get_bits1(&gb);
+
+ if (bits->ftype == TWINVQ_FT_LONG) {
+ for (i = 0; i < channels; i++)
+ bits->gain_bits[i] = get_bits(&gb, TWINVQ_GAIN_BITS);
+ } else {
+ for (i = 0; i < channels; i++) {
+ bits->gain_bits[i] = get_bits(&gb, TWINVQ_GAIN_BITS);
+ for (j = 0; j < sub; j++)
+ bits->sub_gain_bits[i * sub + j] =
+ get_bits(&gb, TWINVQ_SUB_GAIN_BITS);
+ }
}
- }
- for (i = 0; i < channels; i++) {
- bits->lpc_hist_idx[i] = get_bits(&gb, mtab->lsp_bit0);
- bits->lpc_idx1[i] = get_bits(&gb, mtab->lsp_bit1);
+ for (i = 0; i < channels; i++) {
+ bits->lpc_hist_idx[i] = get_bits(&gb, mtab->lsp_bit0);
+ bits->lpc_idx1[i] = get_bits(&gb, mtab->lsp_bit1);
- for (j = 0; j < mtab->lsp_split; j++)
- bits->lpc_idx2[i][j] = get_bits(&gb, mtab->lsp_bit2);
- }
+ for (j = 0; j < mtab->lsp_split; j++)
+ bits->lpc_idx2[i][j] = get_bits(&gb, mtab->lsp_bit2);
+ }
- if (bits->ftype == TWINVQ_FT_LONG) {
- read_cb_data(tctx, &gb, bits->ppc_coeffs, 3);
- for (i = 0; i < channels; i++) {
- bits->p_coef[i] = get_bits(&gb, mtab->ppc_period_bit);
- bits->g_coef[i] = get_bits(&gb, mtab->pgain_bit);
+ if (bits->ftype == TWINVQ_FT_LONG) {
+ read_cb_data(tctx, &gb, bits->ppc_coeffs, 3);
+ for (i = 0; i < channels; i++) {
+ bits->p_coef[i] = get_bits(&gb, mtab->ppc_period_bit);
+ bits->g_coef[i] = get_bits(&gb, mtab->pgain_bit);
+ }
}
+
+ // subframes are aligned to nibbles
+ if (get_bits_count(&gb) & 3)
+ skip_bits(&gb, 4 - (get_bits_count(&gb) & 3));
}
return 0;
for (;;) {
if (!props->tag) {
- av_log(avctx, AV_LOG_ERROR, "Could not find tag %08X\n", tag);
+ av_log(avctx, AV_LOG_ERROR, "Could not find tag %08"PRIX32"\n", tag);
return AVERROR_INVALIDDATA;
}
if (props->tag == tag) {
ibps = avctx->bit_rate / (1000 * avctx->channels);
switch ((avctx->channels << 16) + (isampf << 8) + ibps) {
+ case (1 << 16) + ( 8 << 8) + 6:
+ tctx->mtab = &ff_metasound_mode0806;
+ break;
+ case (2 << 16) + ( 8 << 8) + 6:
+ tctx->mtab = &ff_metasound_mode0806s;
+ break;
case (1 << 16) + ( 8 << 8) + 8:
tctx->mtab = &ff_metasound_mode0808;
break;
+ case (2 << 16) + ( 8 << 8) + 8:
+ tctx->mtab = &ff_metasound_mode0808s;
+ break;
+ case (1 << 16) + (11 << 8) + 10:
+ tctx->mtab = &ff_metasound_mode1110;
+ break;
+ case (2 << 16) + (11 << 8) + 10:
+ tctx->mtab = &ff_metasound_mode1110s;
+ break;
case (1 << 16) + (16 << 8) + 16:
tctx->mtab = &ff_metasound_mode1616;
break;
+ case (2 << 16) + (16 << 8) + 16:
+ tctx->mtab = &ff_metasound_mode1616s;
+ break;
+ case (1 << 16) + (22 << 8) + 24:
+ tctx->mtab = &ff_metasound_mode2224;
+ break;
+ case (2 << 16) + (22 << 8) + 24:
+ tctx->mtab = &ff_metasound_mode2224s;
+ break;
case (1 << 16) + (44 << 8) + 32:
tctx->mtab = &ff_metasound_mode4432;
break;
+ case (2 << 16) + (44 << 8) + 32:
+ tctx->mtab = &ff_metasound_mode4432s;
+ break;
+ case (1 << 16) + (44 << 8) + 40:
+ tctx->mtab = &ff_metasound_mode4440;
+ break;
+ case (2 << 16) + (44 << 8) + 40:
+ tctx->mtab = &ff_metasound_mode4440s;
+ break;
+ case (1 << 16) + (44 << 8) + 48:
+ tctx->mtab = &ff_metasound_mode4448;
+ break;
case (2 << 16) + (44 << 8) + 48:
tctx->mtab = &ff_metasound_mode4448s;
break;
default:
av_log(avctx, AV_LOG_ERROR,
"This version does not support %d kHz - %d kbit/s/ch mode.\n",
- isampf, isampf);
+ isampf, ibps);
return AVERROR(ENOSYS);
}
tctx->read_bitstream = metasound_read_bitstream;
tctx->dec_bark_env = dec_bark_env;
tctx->decode_ppc = decode_ppc;
+ tctx->frame_size = avctx->bit_rate * tctx->mtab->size
+ / avctx->sample_rate;
+ tctx->is_6kbps = ibps == 6;
return ff_twinvq_decode_init(avctx);
}
.init = metasound_decode_init,
.close = ff_twinvq_decode_close,
.decode = ff_twinvq_decode_frame,
- .capabilities = CODEC_CAP_DR1,
+ .capabilities = AV_CODEC_CAP_DR1,
.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
AV_SAMPLE_FMT_NONE },
};