1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Voxware MetaSound decoder 3cabdff1aSopenharmony_ci * Copyright (c) 2013 Konstantin Shishkov 4cabdff1aSopenharmony_ci * based on TwinVQ decoder 5cabdff1aSopenharmony_ci * Copyright (c) 2009 Vitor Sessak 6cabdff1aSopenharmony_ci * 7cabdff1aSopenharmony_ci * This file is part of FFmpeg. 8cabdff1aSopenharmony_ci * 9cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 10cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 11cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 12cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 13cabdff1aSopenharmony_ci * 14cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 15cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 16cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17cabdff1aSopenharmony_ci * Lesser General Public License for more details. 18cabdff1aSopenharmony_ci * 19cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 20cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 21cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22cabdff1aSopenharmony_ci */ 23cabdff1aSopenharmony_ci 24cabdff1aSopenharmony_ci#include <inttypes.h> 25cabdff1aSopenharmony_ci#include <math.h> 26cabdff1aSopenharmony_ci#include <stdint.h> 27cabdff1aSopenharmony_ci 28cabdff1aSopenharmony_ci#include "libavutil/channel_layout.h" 29cabdff1aSopenharmony_ci#include "libavutil/float_dsp.h" 30cabdff1aSopenharmony_ci 31cabdff1aSopenharmony_ci#define BITSTREAM_READER_LE 32cabdff1aSopenharmony_ci#include "avcodec.h" 33cabdff1aSopenharmony_ci#include "codec_internal.h" 34cabdff1aSopenharmony_ci#include "fft.h" 35cabdff1aSopenharmony_ci#include "get_bits.h" 36cabdff1aSopenharmony_ci#include "lsp.h" 37cabdff1aSopenharmony_ci#include "sinewin.h" 38cabdff1aSopenharmony_ci 39cabdff1aSopenharmony_ci#include "twinvq.h" 40cabdff1aSopenharmony_ci#include "metasound_data.h" 41cabdff1aSopenharmony_ci 42cabdff1aSopenharmony_cistatic void add_peak(float period, int width, const float *shape, 43cabdff1aSopenharmony_ci float ppc_gain, float *speech, int len) 44cabdff1aSopenharmony_ci{ 45cabdff1aSopenharmony_ci int i, j, center; 46cabdff1aSopenharmony_ci const float *shape_end = shape + len; 47cabdff1aSopenharmony_ci 48cabdff1aSopenharmony_ci // First peak centered around zero 49cabdff1aSopenharmony_ci for (i = 0; i < width / 2; i++) 50cabdff1aSopenharmony_ci speech[i] += ppc_gain * *shape++; 51cabdff1aSopenharmony_ci 52cabdff1aSopenharmony_ci for (i = 1; i < ROUNDED_DIV(len, width); i++) { 53cabdff1aSopenharmony_ci center = (int)(i * period + 0.5); 54cabdff1aSopenharmony_ci for (j = -width / 2; j < (width + 1) / 2; j++) 55cabdff1aSopenharmony_ci speech[j + center] += ppc_gain * *shape++; 56cabdff1aSopenharmony_ci } 57cabdff1aSopenharmony_ci 58cabdff1aSopenharmony_ci // For the last block, be careful not to go beyond the end of the buffer 59cabdff1aSopenharmony_ci center = (int)(i * period + 0.5); 60cabdff1aSopenharmony_ci for (j = -width / 2; j < (width + 1) / 2 && shape < shape_end; j++) 61cabdff1aSopenharmony_ci speech[j + center] += ppc_gain * *shape++; 62cabdff1aSopenharmony_ci} 63cabdff1aSopenharmony_ci 64cabdff1aSopenharmony_cistatic void decode_ppc(TwinVQContext *tctx, int period_coef, int g_coef, 65cabdff1aSopenharmony_ci const float *shape, float *speech) 66cabdff1aSopenharmony_ci{ 67cabdff1aSopenharmony_ci const TwinVQModeTab *mtab = tctx->mtab; 68cabdff1aSopenharmony_ci int channels = tctx->avctx->ch_layout.nb_channels; 69cabdff1aSopenharmony_ci int isampf = tctx->avctx->sample_rate / 1000; 70cabdff1aSopenharmony_ci int ibps = tctx->avctx->bit_rate / (1000 * channels); 71cabdff1aSopenharmony_ci int width; 72cabdff1aSopenharmony_ci 73cabdff1aSopenharmony_ci float ratio = (float)mtab->size / isampf; 74cabdff1aSopenharmony_ci float min_period, max_period, period_range, period; 75cabdff1aSopenharmony_ci float some_mult; 76cabdff1aSopenharmony_ci 77cabdff1aSopenharmony_ci float pgain_base, pgain_step, ppc_gain; 78cabdff1aSopenharmony_ci 79cabdff1aSopenharmony_ci if (channels == 1) { 80cabdff1aSopenharmony_ci min_period = log2(ratio * 0.2); 81cabdff1aSopenharmony_ci max_period = min_period + log2(6); 82cabdff1aSopenharmony_ci } else { 83cabdff1aSopenharmony_ci min_period = (int)(ratio * 0.2 * 400 + 0.5) / 400.0; 84cabdff1aSopenharmony_ci max_period = (int)(ratio * 0.2 * 400 * 6 + 0.5) / 400.0; 85cabdff1aSopenharmony_ci } 86cabdff1aSopenharmony_ci period_range = max_period - min_period; 87cabdff1aSopenharmony_ci period = min_period + period_coef * period_range / 88cabdff1aSopenharmony_ci ((1 << mtab->ppc_period_bit) - 1); 89cabdff1aSopenharmony_ci if (channels == 1) 90cabdff1aSopenharmony_ci period = powf(2.0, period); 91cabdff1aSopenharmony_ci else 92cabdff1aSopenharmony_ci period = (int)(period * 400 + 0.5) / 400.0; 93cabdff1aSopenharmony_ci 94cabdff1aSopenharmony_ci switch (isampf) { 95cabdff1aSopenharmony_ci case 8: some_mult = 2.0; break; 96cabdff1aSopenharmony_ci case 11: some_mult = 3.0; break; 97cabdff1aSopenharmony_ci case 16: some_mult = 3.0; break; 98cabdff1aSopenharmony_ci case 22: some_mult = ibps == 32 ? 2.0 : 4.0; break; 99cabdff1aSopenharmony_ci case 44: some_mult = 8.0; break; 100cabdff1aSopenharmony_ci default: some_mult = 4.0; 101cabdff1aSopenharmony_ci } 102cabdff1aSopenharmony_ci 103cabdff1aSopenharmony_ci width = (int)(some_mult / (mtab->size / period) * mtab->ppc_shape_len); 104cabdff1aSopenharmony_ci if (isampf == 22 && ibps == 32) 105cabdff1aSopenharmony_ci width = (int)((2.0 / period + 1) * width + 0.5); 106cabdff1aSopenharmony_ci 107cabdff1aSopenharmony_ci pgain_base = channels == 2 ? 25000.0 : 20000.0; 108cabdff1aSopenharmony_ci pgain_step = pgain_base / ((1 << mtab->pgain_bit) - 1); 109cabdff1aSopenharmony_ci ppc_gain = 1.0 / 8192 * 110cabdff1aSopenharmony_ci twinvq_mulawinv(pgain_step * g_coef + pgain_step / 2, 111cabdff1aSopenharmony_ci pgain_base, TWINVQ_PGAIN_MU); 112cabdff1aSopenharmony_ci 113cabdff1aSopenharmony_ci add_peak(period, width, shape, ppc_gain, speech, mtab->ppc_shape_len); 114cabdff1aSopenharmony_ci} 115cabdff1aSopenharmony_ci 116cabdff1aSopenharmony_cistatic void dec_bark_env(TwinVQContext *tctx, const uint8_t *in, int use_hist, 117cabdff1aSopenharmony_ci int ch, float *out, float gain, 118cabdff1aSopenharmony_ci enum TwinVQFrameType ftype) 119cabdff1aSopenharmony_ci{ 120cabdff1aSopenharmony_ci const TwinVQModeTab *mtab = tctx->mtab; 121cabdff1aSopenharmony_ci int i, j; 122cabdff1aSopenharmony_ci float *hist = tctx->bark_hist[ftype][ch]; 123cabdff1aSopenharmony_ci float val = ((const float []) { 0.4, 0.35, 0.28 })[ftype]; 124cabdff1aSopenharmony_ci int bark_n_coef = mtab->fmode[ftype].bark_n_coef; 125cabdff1aSopenharmony_ci int fw_cb_len = mtab->fmode[ftype].bark_env_size / bark_n_coef; 126cabdff1aSopenharmony_ci int idx = 0; 127cabdff1aSopenharmony_ci int channels = tctx->avctx->ch_layout.nb_channels; 128cabdff1aSopenharmony_ci 129cabdff1aSopenharmony_ci if (channels == 1) 130cabdff1aSopenharmony_ci val = 0.5; 131cabdff1aSopenharmony_ci for (i = 0; i < fw_cb_len; i++) 132cabdff1aSopenharmony_ci for (j = 0; j < bark_n_coef; j++, idx++) { 133cabdff1aSopenharmony_ci float tmp2 = mtab->fmode[ftype].bark_cb[fw_cb_len * in[j] + i] * 134cabdff1aSopenharmony_ci (1.0 / 2048); 135cabdff1aSopenharmony_ci float st; 136cabdff1aSopenharmony_ci 137cabdff1aSopenharmony_ci if (channels == 1) 138cabdff1aSopenharmony_ci st = use_hist ? 139cabdff1aSopenharmony_ci tmp2 + val * hist[idx] + 1.0 : tmp2 + 1.0; 140cabdff1aSopenharmony_ci else 141cabdff1aSopenharmony_ci st = use_hist ? (1.0 - val) * tmp2 + val * hist[idx] + 1.0 142cabdff1aSopenharmony_ci : tmp2 + 1.0; 143cabdff1aSopenharmony_ci 144cabdff1aSopenharmony_ci hist[idx] = tmp2; 145cabdff1aSopenharmony_ci if (st < 0.1) 146cabdff1aSopenharmony_ci st = 0.1; 147cabdff1aSopenharmony_ci 148cabdff1aSopenharmony_ci twinvq_memset_float(out, st * gain, 149cabdff1aSopenharmony_ci mtab->fmode[ftype].bark_tab[idx]); 150cabdff1aSopenharmony_ci out += mtab->fmode[ftype].bark_tab[idx]; 151cabdff1aSopenharmony_ci } 152cabdff1aSopenharmony_ci} 153cabdff1aSopenharmony_ci 154cabdff1aSopenharmony_cistatic void read_cb_data(TwinVQContext *tctx, GetBitContext *gb, 155cabdff1aSopenharmony_ci uint8_t *dst, enum TwinVQFrameType ftype) 156cabdff1aSopenharmony_ci{ 157cabdff1aSopenharmony_ci int i; 158cabdff1aSopenharmony_ci 159cabdff1aSopenharmony_ci for (i = 0; i < tctx->n_div[ftype]; i++) { 160cabdff1aSopenharmony_ci int bs_second_part = (i >= tctx->bits_main_spec_change[ftype]); 161cabdff1aSopenharmony_ci 162cabdff1aSopenharmony_ci *dst++ = get_bits(gb, tctx->bits_main_spec[0][ftype][bs_second_part]); 163cabdff1aSopenharmony_ci *dst++ = get_bits(gb, tctx->bits_main_spec[1][ftype][bs_second_part]); 164cabdff1aSopenharmony_ci } 165cabdff1aSopenharmony_ci} 166cabdff1aSopenharmony_ci 167cabdff1aSopenharmony_cistatic int metasound_read_bitstream(AVCodecContext *avctx, TwinVQContext *tctx, 168cabdff1aSopenharmony_ci const uint8_t *buf, int buf_size) 169cabdff1aSopenharmony_ci{ 170cabdff1aSopenharmony_ci TwinVQFrameData *bits; 171cabdff1aSopenharmony_ci const TwinVQModeTab *mtab = tctx->mtab; 172cabdff1aSopenharmony_ci int channels = tctx->avctx->ch_layout.nb_channels; 173cabdff1aSopenharmony_ci int sub; 174cabdff1aSopenharmony_ci GetBitContext gb; 175cabdff1aSopenharmony_ci int i, j, k, ret; 176cabdff1aSopenharmony_ci 177cabdff1aSopenharmony_ci if ((ret = init_get_bits8(&gb, buf, buf_size)) < 0) 178cabdff1aSopenharmony_ci return ret; 179cabdff1aSopenharmony_ci 180cabdff1aSopenharmony_ci for (tctx->cur_frame = 0; tctx->cur_frame < tctx->frames_per_packet; 181cabdff1aSopenharmony_ci tctx->cur_frame++) { 182cabdff1aSopenharmony_ci bits = tctx->bits + tctx->cur_frame; 183cabdff1aSopenharmony_ci 184cabdff1aSopenharmony_ci bits->window_type = get_bits(&gb, TWINVQ_WINDOW_TYPE_BITS); 185cabdff1aSopenharmony_ci 186cabdff1aSopenharmony_ci if (bits->window_type > 8) { 187cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Invalid window type, broken sample?\n"); 188cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 189cabdff1aSopenharmony_ci } 190cabdff1aSopenharmony_ci 191cabdff1aSopenharmony_ci bits->ftype = ff_twinvq_wtype_to_ftype_table[tctx->bits[tctx->cur_frame].window_type]; 192cabdff1aSopenharmony_ci 193cabdff1aSopenharmony_ci sub = mtab->fmode[bits->ftype].sub; 194cabdff1aSopenharmony_ci 195cabdff1aSopenharmony_ci if (bits->ftype != TWINVQ_FT_SHORT && !tctx->is_6kbps) 196cabdff1aSopenharmony_ci get_bits(&gb, 2); 197cabdff1aSopenharmony_ci 198cabdff1aSopenharmony_ci read_cb_data(tctx, &gb, bits->main_coeffs, bits->ftype); 199cabdff1aSopenharmony_ci 200cabdff1aSopenharmony_ci for (i = 0; i < channels; i++) 201cabdff1aSopenharmony_ci for (j = 0; j < sub; j++) 202cabdff1aSopenharmony_ci for (k = 0; k < mtab->fmode[bits->ftype].bark_n_coef; k++) 203cabdff1aSopenharmony_ci bits->bark1[i][j][k] = 204cabdff1aSopenharmony_ci get_bits(&gb, mtab->fmode[bits->ftype].bark_n_bit); 205cabdff1aSopenharmony_ci 206cabdff1aSopenharmony_ci for (i = 0; i < channels; i++) 207cabdff1aSopenharmony_ci for (j = 0; j < sub; j++) 208cabdff1aSopenharmony_ci bits->bark_use_hist[i][j] = get_bits1(&gb); 209cabdff1aSopenharmony_ci 210cabdff1aSopenharmony_ci if (bits->ftype == TWINVQ_FT_LONG) { 211cabdff1aSopenharmony_ci for (i = 0; i < channels; i++) 212cabdff1aSopenharmony_ci bits->gain_bits[i] = get_bits(&gb, TWINVQ_GAIN_BITS); 213cabdff1aSopenharmony_ci } else { 214cabdff1aSopenharmony_ci for (i = 0; i < channels; i++) { 215cabdff1aSopenharmony_ci bits->gain_bits[i] = get_bits(&gb, TWINVQ_GAIN_BITS); 216cabdff1aSopenharmony_ci for (j = 0; j < sub; j++) 217cabdff1aSopenharmony_ci bits->sub_gain_bits[i * sub + j] = 218cabdff1aSopenharmony_ci get_bits(&gb, TWINVQ_SUB_GAIN_BITS); 219cabdff1aSopenharmony_ci } 220cabdff1aSopenharmony_ci } 221cabdff1aSopenharmony_ci 222cabdff1aSopenharmony_ci for (i = 0; i < channels; i++) { 223cabdff1aSopenharmony_ci bits->lpc_hist_idx[i] = get_bits(&gb, mtab->lsp_bit0); 224cabdff1aSopenharmony_ci bits->lpc_idx1[i] = get_bits(&gb, mtab->lsp_bit1); 225cabdff1aSopenharmony_ci 226cabdff1aSopenharmony_ci for (j = 0; j < mtab->lsp_split; j++) 227cabdff1aSopenharmony_ci bits->lpc_idx2[i][j] = get_bits(&gb, mtab->lsp_bit2); 228cabdff1aSopenharmony_ci } 229cabdff1aSopenharmony_ci 230cabdff1aSopenharmony_ci if (bits->ftype == TWINVQ_FT_LONG) { 231cabdff1aSopenharmony_ci read_cb_data(tctx, &gb, bits->ppc_coeffs, 3); 232cabdff1aSopenharmony_ci for (i = 0; i < channels; i++) { 233cabdff1aSopenharmony_ci bits->p_coef[i] = get_bits(&gb, mtab->ppc_period_bit); 234cabdff1aSopenharmony_ci bits->g_coef[i] = get_bits(&gb, mtab->pgain_bit); 235cabdff1aSopenharmony_ci } 236cabdff1aSopenharmony_ci } 237cabdff1aSopenharmony_ci 238cabdff1aSopenharmony_ci // subframes are aligned to nibbles 239cabdff1aSopenharmony_ci if (get_bits_count(&gb) & 3) 240cabdff1aSopenharmony_ci skip_bits(&gb, 4 - (get_bits_count(&gb) & 3)); 241cabdff1aSopenharmony_ci } 242cabdff1aSopenharmony_ci 243cabdff1aSopenharmony_ci return (get_bits_count(&gb) + 7) / 8; 244cabdff1aSopenharmony_ci} 245cabdff1aSopenharmony_ci 246cabdff1aSopenharmony_citypedef struct MetasoundProps { 247cabdff1aSopenharmony_ci uint32_t tag; 248cabdff1aSopenharmony_ci int bit_rate; 249cabdff1aSopenharmony_ci int channels; 250cabdff1aSopenharmony_ci int sample_rate; 251cabdff1aSopenharmony_ci} MetasoundProps; 252cabdff1aSopenharmony_ci 253cabdff1aSopenharmony_cistatic const MetasoundProps codec_props[] = { 254cabdff1aSopenharmony_ci { MKTAG('V','X','0','3'), 6, 1, 8000 }, 255cabdff1aSopenharmony_ci { MKTAG('V','X','0','4'), 12, 2, 8000 }, 256cabdff1aSopenharmony_ci 257cabdff1aSopenharmony_ci { MKTAG('V','O','X','i'), 8, 1, 8000 }, 258cabdff1aSopenharmony_ci { MKTAG('V','O','X','j'), 10, 1, 11025 }, 259cabdff1aSopenharmony_ci { MKTAG('V','O','X','k'), 16, 1, 16000 }, 260cabdff1aSopenharmony_ci { MKTAG('V','O','X','L'), 24, 1, 22050 }, 261cabdff1aSopenharmony_ci { MKTAG('V','O','X','q'), 32, 1, 44100 }, 262cabdff1aSopenharmony_ci { MKTAG('V','O','X','r'), 40, 1, 44100 }, 263cabdff1aSopenharmony_ci { MKTAG('V','O','X','s'), 48, 1, 44100 }, 264cabdff1aSopenharmony_ci { MKTAG('V','O','X','t'), 16, 2, 8000 }, 265cabdff1aSopenharmony_ci { MKTAG('V','O','X','u'), 20, 2, 11025 }, 266cabdff1aSopenharmony_ci { MKTAG('V','O','X','v'), 32, 2, 16000 }, 267cabdff1aSopenharmony_ci { MKTAG('V','O','X','w'), 48, 2, 22050 }, 268cabdff1aSopenharmony_ci { MKTAG('V','O','X','x'), 64, 2, 44100 }, 269cabdff1aSopenharmony_ci { MKTAG('V','O','X','y'), 80, 2, 44100 }, 270cabdff1aSopenharmony_ci { MKTAG('V','O','X','z'), 96, 2, 44100 }, 271cabdff1aSopenharmony_ci 272cabdff1aSopenharmony_ci { 0, 0, 0, 0 } 273cabdff1aSopenharmony_ci}; 274cabdff1aSopenharmony_ci 275cabdff1aSopenharmony_cistatic av_cold int metasound_decode_init(AVCodecContext *avctx) 276cabdff1aSopenharmony_ci{ 277cabdff1aSopenharmony_ci int isampf, ibps; 278cabdff1aSopenharmony_ci TwinVQContext *tctx = avctx->priv_data; 279cabdff1aSopenharmony_ci uint32_t tag; 280cabdff1aSopenharmony_ci const MetasoundProps *props = codec_props; 281cabdff1aSopenharmony_ci int channels; 282cabdff1aSopenharmony_ci 283cabdff1aSopenharmony_ci if (!avctx->extradata || avctx->extradata_size < 16) { 284cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Missing or incomplete extradata\n"); 285cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 286cabdff1aSopenharmony_ci } 287cabdff1aSopenharmony_ci 288cabdff1aSopenharmony_ci tag = AV_RL32(avctx->extradata + 12); 289cabdff1aSopenharmony_ci 290cabdff1aSopenharmony_ci for (;;) { 291cabdff1aSopenharmony_ci if (!props->tag) { 292cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Could not find tag %08"PRIX32"\n", tag); 293cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 294cabdff1aSopenharmony_ci } 295cabdff1aSopenharmony_ci if (props->tag == tag) { 296cabdff1aSopenharmony_ci avctx->sample_rate = props->sample_rate; 297cabdff1aSopenharmony_ci channels = props->channels; 298cabdff1aSopenharmony_ci avctx->bit_rate = props->bit_rate * 1000; 299cabdff1aSopenharmony_ci isampf = avctx->sample_rate / 1000; 300cabdff1aSopenharmony_ci break; 301cabdff1aSopenharmony_ci } 302cabdff1aSopenharmony_ci props++; 303cabdff1aSopenharmony_ci } 304cabdff1aSopenharmony_ci 305cabdff1aSopenharmony_ci if (channels <= 0 || channels > TWINVQ_CHANNELS_MAX) { 306cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Unsupported number of channels: %i\n", 307cabdff1aSopenharmony_ci channels); 308cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 309cabdff1aSopenharmony_ci } 310cabdff1aSopenharmony_ci av_channel_layout_uninit(&avctx->ch_layout); 311cabdff1aSopenharmony_ci av_channel_layout_default(&avctx->ch_layout, channels); 312cabdff1aSopenharmony_ci 313cabdff1aSopenharmony_ci ibps = avctx->bit_rate / (1000 * channels); 314cabdff1aSopenharmony_ci 315cabdff1aSopenharmony_ci switch ((channels << 16) + (isampf << 8) + ibps) { 316cabdff1aSopenharmony_ci case (1 << 16) + ( 8 << 8) + 6: 317cabdff1aSopenharmony_ci tctx->mtab = &ff_metasound_mode0806; 318cabdff1aSopenharmony_ci break; 319cabdff1aSopenharmony_ci case (2 << 16) + ( 8 << 8) + 6: 320cabdff1aSopenharmony_ci tctx->mtab = &ff_metasound_mode0806s; 321cabdff1aSopenharmony_ci break; 322cabdff1aSopenharmony_ci case (1 << 16) + ( 8 << 8) + 8: 323cabdff1aSopenharmony_ci tctx->mtab = &ff_metasound_mode0808; 324cabdff1aSopenharmony_ci break; 325cabdff1aSopenharmony_ci case (2 << 16) + ( 8 << 8) + 8: 326cabdff1aSopenharmony_ci tctx->mtab = &ff_metasound_mode0808s; 327cabdff1aSopenharmony_ci break; 328cabdff1aSopenharmony_ci case (1 << 16) + (11 << 8) + 10: 329cabdff1aSopenharmony_ci tctx->mtab = &ff_metasound_mode1110; 330cabdff1aSopenharmony_ci break; 331cabdff1aSopenharmony_ci case (2 << 16) + (11 << 8) + 10: 332cabdff1aSopenharmony_ci tctx->mtab = &ff_metasound_mode1110s; 333cabdff1aSopenharmony_ci break; 334cabdff1aSopenharmony_ci case (1 << 16) + (16 << 8) + 16: 335cabdff1aSopenharmony_ci tctx->mtab = &ff_metasound_mode1616; 336cabdff1aSopenharmony_ci break; 337cabdff1aSopenharmony_ci case (2 << 16) + (16 << 8) + 16: 338cabdff1aSopenharmony_ci tctx->mtab = &ff_metasound_mode1616s; 339cabdff1aSopenharmony_ci break; 340cabdff1aSopenharmony_ci case (1 << 16) + (22 << 8) + 24: 341cabdff1aSopenharmony_ci tctx->mtab = &ff_metasound_mode2224; 342cabdff1aSopenharmony_ci break; 343cabdff1aSopenharmony_ci case (2 << 16) + (22 << 8) + 24: 344cabdff1aSopenharmony_ci tctx->mtab = &ff_metasound_mode2224s; 345cabdff1aSopenharmony_ci break; 346cabdff1aSopenharmony_ci case (1 << 16) + (44 << 8) + 32: 347cabdff1aSopenharmony_ci case (2 << 16) + (44 << 8) + 32: 348cabdff1aSopenharmony_ci tctx->mtab = &ff_metasound_mode4432; 349cabdff1aSopenharmony_ci break; 350cabdff1aSopenharmony_ci case (1 << 16) + (44 << 8) + 40: 351cabdff1aSopenharmony_ci case (2 << 16) + (44 << 8) + 40: 352cabdff1aSopenharmony_ci tctx->mtab = &ff_metasound_mode4440; 353cabdff1aSopenharmony_ci break; 354cabdff1aSopenharmony_ci case (1 << 16) + (44 << 8) + 48: 355cabdff1aSopenharmony_ci case (2 << 16) + (44 << 8) + 48: 356cabdff1aSopenharmony_ci tctx->mtab = &ff_metasound_mode4448; 357cabdff1aSopenharmony_ci break; 358cabdff1aSopenharmony_ci default: 359cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, 360cabdff1aSopenharmony_ci "This version does not support %d kHz - %d kbit/s/ch mode.\n", 361cabdff1aSopenharmony_ci isampf, ibps); 362cabdff1aSopenharmony_ci return AVERROR(ENOSYS); 363cabdff1aSopenharmony_ci } 364cabdff1aSopenharmony_ci 365cabdff1aSopenharmony_ci tctx->codec = TWINVQ_CODEC_METASOUND; 366cabdff1aSopenharmony_ci tctx->read_bitstream = metasound_read_bitstream; 367cabdff1aSopenharmony_ci tctx->dec_bark_env = dec_bark_env; 368cabdff1aSopenharmony_ci tctx->decode_ppc = decode_ppc; 369cabdff1aSopenharmony_ci tctx->frame_size = avctx->bit_rate * tctx->mtab->size 370cabdff1aSopenharmony_ci / avctx->sample_rate; 371cabdff1aSopenharmony_ci tctx->is_6kbps = ibps == 6; 372cabdff1aSopenharmony_ci 373cabdff1aSopenharmony_ci return ff_twinvq_decode_init(avctx); 374cabdff1aSopenharmony_ci} 375cabdff1aSopenharmony_ci 376cabdff1aSopenharmony_ciconst FFCodec ff_metasound_decoder = { 377cabdff1aSopenharmony_ci .p.name = "metasound", 378cabdff1aSopenharmony_ci .p.long_name = NULL_IF_CONFIG_SMALL("Voxware MetaSound"), 379cabdff1aSopenharmony_ci .p.type = AVMEDIA_TYPE_AUDIO, 380cabdff1aSopenharmony_ci .p.id = AV_CODEC_ID_METASOUND, 381cabdff1aSopenharmony_ci .priv_data_size = sizeof(TwinVQContext), 382cabdff1aSopenharmony_ci .init = metasound_decode_init, 383cabdff1aSopenharmony_ci .close = ff_twinvq_decode_close, 384cabdff1aSopenharmony_ci FF_CODEC_DECODE_CB(ff_twinvq_decode_frame), 385cabdff1aSopenharmony_ci .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, 386cabdff1aSopenharmony_ci .p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, 387cabdff1aSopenharmony_ci AV_SAMPLE_FMT_NONE }, 388cabdff1aSopenharmony_ci .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, 389cabdff1aSopenharmony_ci}; 390