From patchwork Mon Jan 25 12:11:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Gaullier X-Patchwork-Id: 25157 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 00BBA449B99 for ; Mon, 25 Jan 2021 14:11:47 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id CE548689D06; Mon, 25 Jan 2021 14:11:46 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from srv-infra-2.infra.inf.glb.tvvideoms.com (unknown [213.205.126.156]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id AA9556881E7 for ; Mon, 25 Jan 2021 14:11:40 +0200 (EET) Received: from cji.paris (unknown [172.16.3.159]) by srv-infra-2.infra.inf.glb.tvvideoms.com (Postfix) with ESMTP id 7C24A410DD; Mon, 25 Jan 2021 12:11:39 +0000 (UTC) From: Nicolas Gaullier To: ffmpeg-devel@ffmpeg.org Date: Mon, 25 Jan 2021 13:11:36 +0100 Message-Id: <20210125121137.1678-1-nicolas.gaullier@cji.paris> X-Mailer: git-send-email 2.27.0.windows.1 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 1/2] avcodec/dolby_e: Add a parser X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Nicolas Gaullier Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" --- Changelog | 1 + libavcodec/dolby_e.c | 254 +++++++++++++++++++++++++++---------------- libavcodec/dolby_e.h | 38 ++++++- libavcodec/parsers.c | 1 + libavcodec/version.h | 4 +- 5 files changed, 199 insertions(+), 99 deletions(-) diff --git a/Changelog b/Changelog index 797b44d4f3..20f6b79ab4 100644 --- a/Changelog +++ b/Changelog @@ -57,6 +57,7 @@ version : - tmidequalizer filter - estdif filter - epx filter +- Dolby E parser version 4.3: diff --git a/libavcodec/dolby_e.c b/libavcodec/dolby_e.c index 2b2f0a1640..6bb817ec5c 100644 --- a/libavcodec/dolby_e.c +++ b/libavcodec/dolby_e.c @@ -26,13 +26,15 @@ #include "internal.h" #include "get_bits.h" #include "put_bits.h" +#include "parser.h" #include "dolby_e.h" #include "fft.h" static int skip_input(DBEContext *s, int nb_words) { if (nb_words > s->input_size) { - av_log(s->avctx, AV_LOG_ERROR, "Packet too short\n"); + if (s->avctx) + av_log(s->avctx, AV_LOG_ERROR, "Packet too short\n"); return AVERROR_INVALIDDATA; } @@ -44,7 +46,7 @@ static int skip_input(DBEContext *s, int nb_words) static int parse_key(DBEContext *s) { if (s->key_present) { - uint8_t *key = s->input; + const uint8_t *key = s->input; int ret = skip_input(s, 1); if (ret < 0) return ret; @@ -55,7 +57,7 @@ static int parse_key(DBEContext *s) static int convert_input(DBEContext *s, int nb_words, int key) { - uint8_t *src = s->input; + const uint8_t *src = s->input; uint8_t *dst = s->buffer; PutBitContext pb; int i; @@ -63,7 +65,8 @@ static int convert_input(DBEContext *s, int nb_words, int key) av_assert0(nb_words <= 1024u); if (nb_words > s->input_size) { - av_log(s->avctx, AV_LOG_ERROR, "Packet too short\n"); + if (s->avctx) + av_log(s->avctx, AV_LOG_ERROR, "Packet too short\n"); return AVERROR_INVALIDDATA; } @@ -89,7 +92,7 @@ static int convert_input(DBEContext *s, int nb_words, int key) return init_get_bits(&s->gb, s->buffer, nb_words * s->word_bits); } -static int parse_metadata(DBEContext *s) +static int parse_metadata(DBEContext *s, DolbyEHeaderInfo *hdr) { int i, ret, key, mtd_size; @@ -101,7 +104,8 @@ static int parse_metadata(DBEContext *s) skip_bits(&s->gb, 4); mtd_size = get_bits(&s->gb, 10); if (!mtd_size) { - av_log(s->avctx, AV_LOG_ERROR, "Invalid metadata size\n"); + if (s->avctx) + av_log(s->avctx, AV_LOG_ERROR, "Invalid metadata size\n"); return AVERROR_INVALIDDATA; } @@ -109,49 +113,53 @@ static int parse_metadata(DBEContext *s) return ret; skip_bits(&s->gb, 14); - s->prog_conf = get_bits(&s->gb, 6); - if (s->prog_conf > MAX_PROG_CONF) { - av_log(s->avctx, AV_LOG_ERROR, "Invalid program configuration\n"); + hdr->prog_conf = get_bits(&s->gb, 6); + if (hdr->prog_conf > MAX_PROG_CONF) { + if (s->avctx) + av_log(s->avctx, AV_LOG_ERROR, "Invalid program configuration\n"); return AVERROR_INVALIDDATA; } - s->nb_channels = nb_channels_tab[s->prog_conf]; - s->nb_programs = nb_programs_tab[s->prog_conf]; + hdr->nb_channels = nb_channels_tab[hdr->prog_conf]; + hdr->nb_programs = nb_programs_tab[hdr->prog_conf]; - s->fr_code = get_bits(&s->gb, 4); - s->fr_code_orig = get_bits(&s->gb, 4); - if (!sample_rate_tab[s->fr_code] || - !sample_rate_tab[s->fr_code_orig]) { - av_log(s->avctx, AV_LOG_ERROR, "Invalid frame rate code\n"); + hdr->fr_code = get_bits(&s->gb, 4); + hdr->fr_code_orig = get_bits(&s->gb, 4); + if (!sample_rate_tab[hdr->fr_code] || + !sample_rate_tab[hdr->fr_code_orig]) { + if (s->avctx) + av_log(s->avctx, AV_LOG_ERROR, "Invalid frame rate code\n"); return AVERROR_INVALIDDATA; } skip_bits_long(&s->gb, 88); - for (i = 0; i < s->nb_channels; i++) - s->ch_size[i] = get_bits(&s->gb, 10); - s->mtd_ext_size = get_bits(&s->gb, 8); - s->meter_size = get_bits(&s->gb, 8); - - skip_bits_long(&s->gb, 10 * s->nb_programs); - for (i = 0; i < s->nb_channels; i++) { - s->rev_id[i] = get_bits(&s->gb, 4); + for (i = 0; i < hdr->nb_channels; i++) + hdr->ch_size[i] = get_bits(&s->gb, 10); + hdr->mtd_ext_size = get_bits(&s->gb, 8); + hdr->meter_size = get_bits(&s->gb, 8); + + skip_bits_long(&s->gb, 10 * hdr->nb_programs); + for (i = 0; i < hdr->nb_channels; i++) { + hdr->rev_id[i] = get_bits(&s->gb, 4); skip_bits1(&s->gb); - s->begin_gain[i] = get_bits(&s->gb, 10); - s->end_gain[i] = get_bits(&s->gb, 10); + hdr->begin_gain[i] = get_bits(&s->gb, 10); + hdr->end_gain[i] = get_bits(&s->gb, 10); } if (get_bits_left(&s->gb) < 0) { - av_log(s->avctx, AV_LOG_ERROR, "Read past end of metadata\n"); + if (s->avctx) + av_log(s->avctx, AV_LOG_ERROR, "Read past end of metadata\n"); return AVERROR_INVALIDDATA; } return skip_input(s, mtd_size + 1); } -static int parse_metadata_ext(DBEContext *s) +static int parse_metadata_ext(DBEDecodeContext *s1) { - if (s->mtd_ext_size) - return skip_input(s, s->key_present + s->mtd_ext_size + 1); + DBEContext *s = &s1->dectx; + if (s1->metadata.mtd_ext_size) + return skip_input(s, s->key_present + s1->metadata.mtd_ext_size + 1); return 0; } @@ -279,8 +287,9 @@ static void bit_allocate(int nb_exponent, int nb_code, int fr_code, } } -static int parse_bit_alloc(DBEContext *s, DBEChannel *c) +static int parse_bit_alloc(DBEDecodeContext *s1, DBEChannel *c) { + DBEContext *s = &s1->dectx; DBEGroup *p, *g; int bap_strategy[MAX_GROUPS], fg_spc[MAX_GROUPS]; int fg_ofs[MAX_GROUPS], msk_mod[MAX_GROUPS]; @@ -312,7 +321,7 @@ static int parse_bit_alloc(DBEContext *s, DBEChannel *c) for (i = 0, p = NULL, g = c->groups; i < c->nb_groups; i++, p = g, g++) { if (c->exp_strategy[i] || bap_strategy[i]) { - bit_allocate(g->nb_exponent, g->imdct_idx, s->fr_code, + bit_allocate(g->nb_exponent, g->imdct_idx, s1->metadata.fr_code, c->exponents + g->exp_ofs, c->bap + g->exp_ofs, fg_spc[i], fg_ofs[i], msk_mod[i], snr_ofs); } else { @@ -412,17 +421,18 @@ static int parse_mantissas(DBEContext *s, DBEChannel *c) return 0; } -static int parse_channel(DBEContext *s, int ch, int seg_id) +static int parse_channel(DBEDecodeContext *s1, int ch, int seg_id) { - DBEChannel *c = &s->channels[seg_id][ch]; + DBEContext *s = &s1->dectx; + DBEChannel *c = &s1->channels[seg_id][ch]; int i, ret; - if (s->rev_id[ch] > 1) { - avpriv_report_missing_feature(s->avctx, "Encoder revision %d", s->rev_id[ch]); + if (s1->metadata.rev_id[ch] > 1) { + avpriv_report_missing_feature(s->avctx, "Encoder revision %d", s1->metadata.rev_id[ch]); return AVERROR_PATCHWELCOME; } - if (ch == lfe_channel_tab[s->prog_conf]) { + if (ch == lfe_channel_tab[s1->metadata.prog_conf]) { c->gr_code = 3; c->bw_code = 29; } else { @@ -447,7 +457,7 @@ static int parse_channel(DBEContext *s, int ch, int seg_id) if ((ret = parse_exponents(s, c)) < 0) return ret; - if ((ret = parse_bit_alloc(s, c)) < 0) + if ((ret = parse_bit_alloc(s1, c)) < 0) return ret; if ((ret = parse_indices(s, c)) < 0) return ret; @@ -462,42 +472,44 @@ static int parse_channel(DBEContext *s, int ch, int seg_id) return 0; } -static int parse_audio(DBEContext *s, int start, int end, int seg_id) +static int parse_audio(DBEDecodeContext *s1, int start, int end, int seg_id) { + DBEContext *s = &s1->dectx; int ch, ret, key; if ((key = parse_key(s)) < 0) return key; for (ch = start; ch < end; ch++) { - if (!s->ch_size[ch]) { - s->channels[seg_id][ch].nb_groups = 0; + if (!s1->metadata.ch_size[ch]) { + s1->channels[seg_id][ch].nb_groups = 0; continue; } - if ((ret = convert_input(s, s->ch_size[ch], key)) < 0) + if ((ret = convert_input(s, s1->metadata.ch_size[ch], key)) < 0) return ret; - if ((ret = parse_channel(s, ch, seg_id)) < 0) { - if (s->avctx->err_recognition & AV_EF_EXPLODE) + if ((ret = parse_channel(s1, ch, seg_id)) < 0) { + if (s1->avctx->err_recognition & AV_EF_EXPLODE) return ret; - s->channels[seg_id][ch].nb_groups = 0; + s1->channels[seg_id][ch].nb_groups = 0; } - if ((ret = skip_input(s, s->ch_size[ch])) < 0) + if ((ret = skip_input(s, s1->metadata.ch_size[ch])) < 0) return ret; } return skip_input(s, 1); } -static int parse_meter(DBEContext *s) +static int parse_meter(DBEDecodeContext *s1) { - if (s->meter_size) - return skip_input(s, s->key_present + s->meter_size + 1); + DBEContext *s = &s1->dectx; + if (s1->metadata.meter_size) + return skip_input(s, s->key_present + s1->metadata.meter_size + 1); return 0; } -static void imdct_calc(DBEContext *s, DBEGroup *g, float *result, float *values) +static void imdct_calc(DBEDecodeContext *s1, DBEGroup *g, float *result, float *values) { - FFTContext *imdct = &s->imdct[g->imdct_idx]; + FFTContext *imdct = &s1->imdct[g->imdct_idx]; int n = 1 << imdct_bits_tab[g->imdct_idx]; int n2 = n >> 1; int i; @@ -521,7 +533,7 @@ static void imdct_calc(DBEContext *s, DBEGroup *g, float *result, float *values) } } -static void transform(DBEContext *s, DBEChannel *c, float *history, float *output) +static void transform(DBEDecodeContext *s1, DBEChannel *c, float *history, float *output) { LOCAL_ALIGNED_32(float, buffer, [2048]); LOCAL_ALIGNED_32(float, result, [1152]); @@ -534,8 +546,8 @@ static void transform(DBEContext *s, DBEChannel *c, float *history, float *outpu float *dst = result + g->dst_ofs; float *win = window + g->win_ofs; - imdct_calc(s, g, buffer, c->mantissas + g->mnt_ofs); - s->fdsp->vector_fmul_add(dst, src, win, dst, g->win_len); + imdct_calc(s1, g, buffer, c->mantissas + g->mnt_ofs); + s1->fdsp->vector_fmul_add(dst, src, win, dst, g->win_len); } for (i = 0; i < 256; i++) @@ -546,7 +558,7 @@ static void transform(DBEContext *s, DBEChannel *c, float *history, float *outpu history[i] = result[896 + i]; } -static void apply_gain(DBEContext *s, int begin, int end, float *output) +static void apply_gain(DBEDecodeContext *s, int begin, int end, float *output) { if (begin == 960 && end == 960) return; @@ -563,16 +575,16 @@ static void apply_gain(DBEContext *s, int begin, int end, float *output) } } -static int filter_frame(DBEContext *s, AVFrame *frame) +static int filter_frame(DBEDecodeContext *s, AVFrame *frame) { const uint8_t *reorder; int ch, ret; - if (s->nb_channels == 4) + if (s->metadata.nb_channels == 4) reorder = ch_reorder_4; - else if (s->nb_channels == 6) + else if (s->metadata.nb_channels == 6) reorder = ch_reorder_6; - else if (s->nb_programs == 1 && !(s->avctx->request_channel_layout & AV_CH_LAYOUT_NATIVE)) + else if (s->metadata.nb_programs == 1 && !(s->avctx->request_channel_layout & AV_CH_LAYOUT_NATIVE)) reorder = ch_reorder_8; else reorder = ch_reorder_n; @@ -581,26 +593,24 @@ static int filter_frame(DBEContext *s, AVFrame *frame) if ((ret = ff_get_buffer(s->avctx, frame, 0)) < 0) return ret; - for (ch = 0; ch < s->nb_channels; ch++) { + for (ch = 0; ch < s->metadata.nb_channels; ch++) { float *output = (float *)frame->extended_data[reorder[ch]]; transform(s, &s->channels[0][ch], s->history[ch], output); transform(s, &s->channels[1][ch], s->history[ch], output + FRAME_SAMPLES / 2); - apply_gain(s, s->begin_gain[ch], s->end_gain[ch], output); + apply_gain(s, s->metadata.begin_gain[ch], s->metadata.end_gain[ch], output); } return 0; } -static int dolby_e_decode_frame(AVCodecContext *avctx, void *data, - int *got_frame_ptr, AVPacket *avpkt) +static int dolby_e_sync(DBEContext *s, const uint8_t *buf, int buf_size) { - DBEContext *s = avctx->priv_data; - int i, j, hdr, ret; + int hdr; - if (avpkt->size < 3) + if (buf_size < 3) return AVERROR_INVALIDDATA; - hdr = AV_RB24(avpkt->data); + hdr = AV_RB24(buf); if ((hdr & 0xfffffe) == 0x7888e) { s->word_bits = 24; } else if ((hdr & 0xffffe0) == 0x788e0) { @@ -608,25 +618,78 @@ static int dolby_e_decode_frame(AVCodecContext *avctx, void *data, } else if ((hdr & 0xfffe00) == 0x78e00) { s->word_bits = 16; } else { - av_log(avctx, AV_LOG_ERROR, "Invalid frame header\n"); + if (s->avctx) + av_log(s->avctx, AV_LOG_ERROR, "Invalid frame header\n"); return AVERROR_INVALIDDATA; } s->word_bytes = s->word_bits + 7 >> 3; - s->input = avpkt->data + s->word_bytes; - s->input_size = avpkt->size / s->word_bytes - 1; + s->input = buf + s->word_bytes; + s->input_size = buf_size / s->word_bytes - 1; s->key_present = hdr >> 24 - s->word_bits & 1; - if ((ret = parse_metadata(s)) < 0) + return 0; +} + +static int dolby_e_parse(AVCodecParserContext *s2, AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + DBEParseContext *s1 = s2->priv_data; + DBEContext *s = &s1->dectx; + int ret; + + if ((ret = dolby_e_sync(s, buf, buf_size)) < 0) + goto end; + + if ((ret = parse_metadata(s, &s1->metadata)) < 0) + goto end; + + s2->duration = FRAME_SAMPLES; + switch (s1->metadata.nb_channels) { + case 4: + avctx->channel_layout = AV_CH_LAYOUT_4POINT0; + break; + case 6: + avctx->channel_layout = AV_CH_LAYOUT_5POINT1; + break; + case 8: + avctx->channel_layout = AV_CH_LAYOUT_7POINT1; + break; + } + + avctx->channels = s1->metadata.nb_channels; + avctx->sample_rate = sample_rate_tab[s1->metadata.fr_code]; + avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; + +end: + /* always return the full packet. this parser isn't doing any splitting or + combining, only packet analysis */ + *poutbuf = buf; + *poutbuf_size = buf_size; + return buf_size; +} + +static int dolby_e_decode_frame(AVCodecContext *avctx, void *data, + int *got_frame_ptr, AVPacket *avpkt) +{ + DBEDecodeContext *s1 = avctx->priv_data; + DBEContext *s = &s1->dectx; + int i, j, ret; + + if ((ret = dolby_e_sync(s, avpkt->data, avpkt->size)) < 0) return ret; - if (s->nb_programs > 1 && !s->multi_prog_warned) { + if ((ret = parse_metadata(s, &s1->metadata)) < 0) + return ret; + + if (s1->metadata.nb_programs > 1 && !s1->metadata.multi_prog_warned) { av_log(avctx, AV_LOG_WARNING, "Stream has %d programs (configuration %d), " - "channels will be output in native order.\n", s->nb_programs, s->prog_conf); - s->multi_prog_warned = 1; + "channels will be output in native order.\n", s1->metadata.nb_programs, s1->metadata.prog_conf); + s1->metadata.multi_prog_warned = 1; } - switch (s->nb_channels) { + switch (s1->metadata.nb_channels) { case 4: avctx->channel_layout = AV_CH_LAYOUT_4POINT0; break; @@ -638,25 +701,25 @@ static int dolby_e_decode_frame(AVCodecContext *avctx, void *data, break; } - avctx->channels = s->nb_channels; - avctx->sample_rate = sample_rate_tab[s->fr_code]; + avctx->channels = s1->metadata.nb_channels; + avctx->sample_rate = sample_rate_tab[s1->metadata.fr_code]; avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; - i = s->nb_channels / 2; - j = s->nb_channels; - if ((ret = parse_audio(s, 0, i, 0)) < 0) + i = s1->metadata.nb_channels / 2; + j = s1->metadata.nb_channels; + if ((ret = parse_audio(s1, 0, i, 0)) < 0) return ret; - if ((ret = parse_audio(s, i, j, 0)) < 0) + if ((ret = parse_audio(s1, i, j, 0)) < 0) return ret; - if ((ret = parse_metadata_ext(s)) < 0) + if ((ret = parse_metadata_ext(s1)) < 0) return ret; - if ((ret = parse_audio(s, 0, i, 1)) < 0) + if ((ret = parse_audio(s1, 0, i, 1)) < 0) return ret; - if ((ret = parse_audio(s, i, j, 1)) < 0) + if ((ret = parse_audio(s1, i, j, 1)) < 0) return ret; - if ((ret = parse_meter(s)) < 0) + if ((ret = parse_meter(s1)) < 0) return ret; - if ((ret = filter_frame(s, data)) < 0) + if ((ret = filter_frame(s1, data)) < 0) return ret; *got_frame_ptr = 1; @@ -665,14 +728,14 @@ static int dolby_e_decode_frame(AVCodecContext *avctx, void *data, static av_cold void dolby_e_flush(AVCodecContext *avctx) { - DBEContext *s = avctx->priv_data; + DBEDecodeContext *s = avctx->priv_data; memset(s->history, 0, sizeof(s->history)); } static av_cold int dolby_e_close(AVCodecContext *avctx) { - DBEContext *s = avctx->priv_data; + DBEDecodeContext *s = avctx->priv_data; int i; for (i = 0; i < 3; i++) @@ -772,7 +835,7 @@ static av_cold void init_tables(void) static av_cold int dolby_e_init(AVCodecContext *avctx) { static AVOnce init_once = AV_ONCE_INIT; - DBEContext *s = avctx->priv_data; + DBEDecodeContext *s = avctx->priv_data; int i; if (ff_thread_once(&init_once, init_tables)) @@ -785,17 +848,24 @@ static av_cold int dolby_e_init(AVCodecContext *avctx) if (!(s->fdsp = avpriv_float_dsp_alloc(0))) return AVERROR(ENOMEM); - s->multi_prog_warned = !!(avctx->request_channel_layout & AV_CH_LAYOUT_NATIVE); - s->avctx = avctx; + s->metadata.multi_prog_warned = !!(avctx->request_channel_layout & AV_CH_LAYOUT_NATIVE); + s->dectx.avctx = s->avctx = avctx; return 0; } +AVCodecParser ff_dolby_e_parser = { + .codec_ids = { AV_CODEC_ID_DOLBY_E }, + .priv_data_size = sizeof(DBEParseContext), + .parser_parse = dolby_e_parse, + .parser_close = ff_parse_close, +}; + AVCodec ff_dolby_e_decoder = { .name = "dolby_e", .long_name = NULL_IF_CONFIG_SMALL("Dolby E"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_DOLBY_E, - .priv_data_size = sizeof(DBEContext), + .priv_data_size = sizeof(DBEDecodeContext), .init = dolby_e_init, .decode = dolby_e_decode_frame, .close = dolby_e_close, diff --git a/libavcodec/dolby_e.h b/libavcodec/dolby_e.h index 68223a62ef..2c012e93d1 100644 --- a/libavcodec/dolby_e.h +++ b/libavcodec/dolby_e.h @@ -75,16 +75,27 @@ typedef struct DBEChannel { } DBEChannel; typedef struct DBEContext { - AVCodecContext *avctx; + void *avctx; GetBitContext gb; - uint8_t *input; + const uint8_t *input; int input_size; int word_bits; int word_bytes; int key_present; + uint8_t buffer[1024 * 3 + AV_INPUT_BUFFER_PADDING_SIZE]; +} DBEContext; + +/** + * @struct DolbyEHeaderInfo + * Coded Dolby E header values up to end_gain element, plus derived values. + */ +typedef struct DolbyEHeaderInfo { + /** @name Coded elements + * @{ + */ int prog_conf; int nb_channels; int nb_programs; @@ -99,8 +110,27 @@ typedef struct DBEContext { int rev_id[MAX_CHANNELS]; int begin_gain[MAX_CHANNELS]; int end_gain[MAX_CHANNELS]; + /** @} */ + /** @name Derived values + * @{ + */ int multi_prog_warned; + /** @} */ +} DolbyEHeaderInfo; + +typedef struct DBEParseContext { + ParseContext pc; + DBEContext dectx; + + DolbyEHeaderInfo metadata; +} DBEParseContext; + +typedef struct DBEDecodeContext { + AVCodecContext *avctx; + DBEContext dectx; + + DolbyEHeaderInfo metadata; DBEChannel channels[MAX_SEGMENTS][MAX_CHANNELS]; @@ -108,9 +138,7 @@ typedef struct DBEContext { FFTContext imdct[3]; AVFloatDSPContext *fdsp; - - uint8_t buffer[1024 * 3 + AV_INPUT_BUFFER_PADDING_SIZE]; -} DBEContext; +} DBEDecodeContext; static const uint8_t nb_programs_tab[MAX_PROG_CONF + 1] = { 2, 3, 2, 3, 4, 5, 4, 5, 6, 7, 8, 1, 2, 3, 3, 4, 5, 6, 1, 2, 3, 4, 1, 1 diff --git a/libavcodec/parsers.c b/libavcodec/parsers.c index 83271d95a3..3156b86b03 100644 --- a/libavcodec/parsers.c +++ b/libavcodec/parsers.c @@ -36,6 +36,7 @@ extern AVCodecParser ff_cook_parser; extern AVCodecParser ff_dca_parser; extern AVCodecParser ff_dirac_parser; extern AVCodecParser ff_dnxhd_parser; +extern AVCodecParser ff_dolby_e_parser; extern AVCodecParser ff_dpx_parser; extern AVCodecParser ff_dvaudio_parser; extern AVCodecParser ff_dvbsub_parser; diff --git a/libavcodec/version.h b/libavcodec/version.h index 9f80caa9e0..807062af7f 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,8 +28,8 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 58 -#define LIBAVCODEC_VERSION_MINOR 117 -#define LIBAVCODEC_VERSION_MICRO 101 +#define LIBAVCODEC_VERSION_MINOR 118 +#define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ From patchwork Mon Jan 25 12:11:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Gaullier X-Patchwork-Id: 25158 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 1F762449B99 for ; Mon, 25 Jan 2021 14:11:50 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 05633689CFF; Mon, 25 Jan 2021 14:11:50 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from srv-infra-2.infra.inf.glb.tvvideoms.com (unknown [213.205.126.156]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 61080680911 for ; Mon, 25 Jan 2021 14:11:41 +0200 (EET) Received: from cji.paris (unknown [172.16.3.159]) by srv-infra-2.infra.inf.glb.tvvideoms.com (Postfix) with ESMTP id 0A70A41175; Mon, 25 Jan 2021 12:11:39 +0000 (UTC) From: Nicolas Gaullier To: ffmpeg-devel@ffmpeg.org Date: Mon, 25 Jan 2021 13:11:37 +0100 Message-Id: <20210125121137.1678-2-nicolas.gaullier@cji.paris> X-Mailer: git-send-email 2.27.0.windows.1 In-Reply-To: <20210125121137.1678-1-nicolas.gaullier@cji.paris> References: <20210125121137.1678-1-nicolas.gaullier@cji.paris> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 2/2] avcodec/dolby_e: Split decoder/parser files X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Nicolas Gaullier Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" --- libavcodec/Makefile | 1 + libavcodec/dolby_e.c | 149 +------ libavcodec/dolby_e.h | 598 +------------------------- libavcodec/dolby_e_parser.c | 227 ++++++++++ libavcodec/dolby_e_parser.h | 41 ++ libavcodec/dolby_e_parser_internal.h | 46 ++ libavcodec/dolby_edec.h | 607 +++++++++++++++++++++++++++ 7 files changed, 932 insertions(+), 737 deletions(-) create mode 100644 libavcodec/dolby_e_parser.c create mode 100644 libavcodec/dolby_e_parser.h create mode 100644 libavcodec/dolby_e_parser_internal.h create mode 100644 libavcodec/dolby_edec.h diff --git a/libavcodec/Makefile b/libavcodec/Makefile index d48fecc5fc..633ebc37f8 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -40,6 +40,7 @@ OBJS = ac3_parser.o \ d3d11va.o \ decode.o \ dirac.o \ + dolby_e_parser.o \ dv_profile.o \ encode.o \ imgconvert.o \ diff --git a/libavcodec/dolby_e.c b/libavcodec/dolby_e.c index 6bb817ec5c..74388f43d1 100644 --- a/libavcodec/dolby_e.c +++ b/libavcodec/dolby_e.c @@ -28,13 +28,14 @@ #include "put_bits.h" #include "parser.h" #include "dolby_e.h" +#include "dolby_edec.h" +#include "dolby_e_parser_internal.h" #include "fft.h" static int skip_input(DBEContext *s, int nb_words) { if (nb_words > s->input_size) { - if (s->avctx) - av_log(s->avctx, AV_LOG_ERROR, "Packet too short\n"); + av_log(s->avctx, AV_LOG_ERROR, "Packet too short\n"); return AVERROR_INVALIDDATA; } @@ -65,8 +66,7 @@ static int convert_input(DBEContext *s, int nb_words, int key) av_assert0(nb_words <= 1024u); if (nb_words > s->input_size) { - if (s->avctx) - av_log(s->avctx, AV_LOG_ERROR, "Packet too short\n"); + av_log(s->avctx, AV_LOG_ERROR, "Packet too short\n"); return AVERROR_INVALIDDATA; } @@ -92,69 +92,6 @@ static int convert_input(DBEContext *s, int nb_words, int key) return init_get_bits(&s->gb, s->buffer, nb_words * s->word_bits); } -static int parse_metadata(DBEContext *s, DolbyEHeaderInfo *hdr) -{ - int i, ret, key, mtd_size; - - if ((key = parse_key(s)) < 0) - return key; - if ((ret = convert_input(s, 1, key)) < 0) - return ret; - - skip_bits(&s->gb, 4); - mtd_size = get_bits(&s->gb, 10); - if (!mtd_size) { - if (s->avctx) - av_log(s->avctx, AV_LOG_ERROR, "Invalid metadata size\n"); - return AVERROR_INVALIDDATA; - } - - if ((ret = convert_input(s, mtd_size, key)) < 0) - return ret; - - skip_bits(&s->gb, 14); - hdr->prog_conf = get_bits(&s->gb, 6); - if (hdr->prog_conf > MAX_PROG_CONF) { - if (s->avctx) - av_log(s->avctx, AV_LOG_ERROR, "Invalid program configuration\n"); - return AVERROR_INVALIDDATA; - } - - hdr->nb_channels = nb_channels_tab[hdr->prog_conf]; - hdr->nb_programs = nb_programs_tab[hdr->prog_conf]; - - hdr->fr_code = get_bits(&s->gb, 4); - hdr->fr_code_orig = get_bits(&s->gb, 4); - if (!sample_rate_tab[hdr->fr_code] || - !sample_rate_tab[hdr->fr_code_orig]) { - if (s->avctx) - av_log(s->avctx, AV_LOG_ERROR, "Invalid frame rate code\n"); - return AVERROR_INVALIDDATA; - } - - skip_bits_long(&s->gb, 88); - for (i = 0; i < hdr->nb_channels; i++) - hdr->ch_size[i] = get_bits(&s->gb, 10); - hdr->mtd_ext_size = get_bits(&s->gb, 8); - hdr->meter_size = get_bits(&s->gb, 8); - - skip_bits_long(&s->gb, 10 * hdr->nb_programs); - for (i = 0; i < hdr->nb_channels; i++) { - hdr->rev_id[i] = get_bits(&s->gb, 4); - skip_bits1(&s->gb); - hdr->begin_gain[i] = get_bits(&s->gb, 10); - hdr->end_gain[i] = get_bits(&s->gb, 10); - } - - if (get_bits_left(&s->gb) < 0) { - if (s->avctx) - av_log(s->avctx, AV_LOG_ERROR, "Read past end of metadata\n"); - return AVERROR_INVALIDDATA; - } - - return skip_input(s, mtd_size + 1); -} - static int parse_metadata_ext(DBEDecodeContext *s1) { DBEContext *s = &s1->dectx; @@ -603,73 +540,6 @@ static int filter_frame(DBEDecodeContext *s, AVFrame *frame) return 0; } -static int dolby_e_sync(DBEContext *s, const uint8_t *buf, int buf_size) -{ - int hdr; - - if (buf_size < 3) - return AVERROR_INVALIDDATA; - - hdr = AV_RB24(buf); - if ((hdr & 0xfffffe) == 0x7888e) { - s->word_bits = 24; - } else if ((hdr & 0xffffe0) == 0x788e0) { - s->word_bits = 20; - } else if ((hdr & 0xfffe00) == 0x78e00) { - s->word_bits = 16; - } else { - if (s->avctx) - av_log(s->avctx, AV_LOG_ERROR, "Invalid frame header\n"); - return AVERROR_INVALIDDATA; - } - - s->word_bytes = s->word_bits + 7 >> 3; - s->input = buf + s->word_bytes; - s->input_size = buf_size / s->word_bytes - 1; - s->key_present = hdr >> 24 - s->word_bits & 1; - - return 0; -} - -static int dolby_e_parse(AVCodecParserContext *s2, AVCodecContext *avctx, - const uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size) -{ - DBEParseContext *s1 = s2->priv_data; - DBEContext *s = &s1->dectx; - int ret; - - if ((ret = dolby_e_sync(s, buf, buf_size)) < 0) - goto end; - - if ((ret = parse_metadata(s, &s1->metadata)) < 0) - goto end; - - s2->duration = FRAME_SAMPLES; - switch (s1->metadata.nb_channels) { - case 4: - avctx->channel_layout = AV_CH_LAYOUT_4POINT0; - break; - case 6: - avctx->channel_layout = AV_CH_LAYOUT_5POINT1; - break; - case 8: - avctx->channel_layout = AV_CH_LAYOUT_7POINT1; - break; - } - - avctx->channels = s1->metadata.nb_channels; - avctx->sample_rate = sample_rate_tab[s1->metadata.fr_code]; - avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; - -end: - /* always return the full packet. this parser isn't doing any splitting or - combining, only packet analysis */ - *poutbuf = buf; - *poutbuf_size = buf_size; - return buf_size; -} - static int dolby_e_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { @@ -677,10 +547,10 @@ static int dolby_e_decode_frame(AVCodecContext *avctx, void *data, DBEContext *s = &s1->dectx; int i, j, ret; - if ((ret = dolby_e_sync(s, avpkt->data, avpkt->size)) < 0) + if ((ret = ff_dolby_e_parse_init(s, avpkt->data, avpkt->size)) < 0) return ret; - if ((ret = parse_metadata(s, &s1->metadata)) < 0) + if ((ret = ff_dolby_e_parse_header(s, &s1->metadata)) < 0) return ret; if (s1->metadata.nb_programs > 1 && !s1->metadata.multi_prog_warned) { @@ -853,13 +723,6 @@ static av_cold int dolby_e_init(AVCodecContext *avctx) return 0; } -AVCodecParser ff_dolby_e_parser = { - .codec_ids = { AV_CODEC_ID_DOLBY_E }, - .priv_data_size = sizeof(DBEParseContext), - .parser_parse = dolby_e_parse, - .parser_close = ff_parse_close, -}; - AVCodec ff_dolby_e_decoder = { .name = "dolby_e", .long_name = NULL_IF_CONFIG_SMALL("Dolby E"), diff --git a/libavcodec/dolby_e.h b/libavcodec/dolby_e.h index 2c012e93d1..855d978bc2 100644 --- a/libavcodec/dolby_e.h +++ b/libavcodec/dolby_e.h @@ -21,59 +21,18 @@ #ifndef AVCODEC_DOLBY_E_H #define AVCODEC_DOLBY_E_H -#include "libavutil/float_dsp.h" -#include "libavutil/libm.h" -#include "libavutil/mem_internal.h" - -#include "internal.h" #include "get_bits.h" -#include "kbdwin.h" -#include "fft.h" #define FRAME_SAMPLES 1792 #define MAX_PROG_CONF 23 #define MAX_PROGRAMS 8 #define MAX_CHANNELS 8 -#define MAX_SEGMENTS 2 - -#define MAX_GROUPS 8 -#define MAX_EXPONENTS 304 -#define MAX_MANTISSAS 1024 - -#define MAX_MSTR_EXP 2 -#define MAX_BIAS_EXP 50 - -typedef struct DBEGroup { - uint8_t nb_exponent; - uint8_t nb_bias_exp[MAX_MSTR_EXP]; - uint16_t exp_ofs; - uint16_t mnt_ofs; - const uint8_t *nb_mantissa; - uint8_t imdct_idx; - uint8_t imdct_phs; - uint16_t win_len; - uint16_t dst_ofs; - uint16_t win_ofs; - uint16_t src_ofs; -} DBEGroup; - -typedef struct DBEChannel { - int gr_code; - int bw_code; - - int nb_groups; - int nb_mstr_exp; - DBEGroup groups[MAX_GROUPS]; - - int exp_strategy[MAX_GROUPS]; - int exponents[MAX_EXPONENTS]; - int bap[MAX_EXPONENTS]; - int idx[MAX_EXPONENTS]; - - DECLARE_ALIGNED(32, float, mantissas)[MAX_MANTISSAS]; -} DBEChannel; +/** + * @struct DBEContext + * Dolby E reading context used by decoder and parser. + */ typedef struct DBEContext { void *avctx; GetBitContext gb; @@ -119,557 +78,8 @@ typedef struct DolbyEHeaderInfo { /** @} */ } DolbyEHeaderInfo; -typedef struct DBEParseContext { - ParseContext pc; - DBEContext dectx; - - DolbyEHeaderInfo metadata; -} DBEParseContext; - -typedef struct DBEDecodeContext { - AVCodecContext *avctx; - DBEContext dectx; - - DolbyEHeaderInfo metadata; - - DBEChannel channels[MAX_SEGMENTS][MAX_CHANNELS]; - - DECLARE_ALIGNED(32, float, history)[MAX_CHANNELS][256]; - - FFTContext imdct[3]; - AVFloatDSPContext *fdsp; -} DBEDecodeContext; - -static const uint8_t nb_programs_tab[MAX_PROG_CONF + 1] = { - 2, 3, 2, 3, 4, 5, 4, 5, 6, 7, 8, 1, 2, 3, 3, 4, 5, 6, 1, 2, 3, 4, 1, 1 -}; - -static const uint8_t nb_channels_tab[MAX_PROG_CONF + 1] = { - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 6, 6, 6, 6, 6, 6, 6, 4, 4, 4, 4, 8, 8 -}; - -static const int8_t lfe_channel_tab[MAX_PROG_CONF + 1] = { - 5, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5, 5 -}; - -static const uint8_t ch_reorder_4[4] = { 0, 2, 1, 3 }; -static const uint8_t ch_reorder_6[6] = { 0, 2, 4, 1, 3, 5 }; -static const uint8_t ch_reorder_8[8] = { 0, 2, 6, 4, 1, 3, 7, 5 }; -static const uint8_t ch_reorder_n[8] = { 0, 2, 4, 6, 1, 3, 5, 7 }; - static const uint16_t sample_rate_tab[16] = { 0, 42965, 43008, 44800, 53706, 53760 }; -static const uint8_t nb_groups_tab[4] = { 1, 8, 7, 1 }; - -static const uint8_t nb_mstr_exp_tab[4] = { 2, 2, 2, 1 }; - -static const uint8_t nb_mantissa_38[38] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, - 7, 8, 9, 10, 11, 12, -}; - -static const uint8_t nb_mantissa_44[44] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, - 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 6, 7, 7, - 8, 9, 10, 11, 12, 13, 15, 16, 18, 20, 22, 25, -}; - -static const uint8_t nb_mantissa_50[50] = { - 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, - 3, 4, 4, 5, 5, 6, 6, 7, 8, 9, 9, 10, 12, 13, 14, 16, - 18, 19, 22, 24, 27, 29, 32, 36, 40, 44, 49, 54, 60, 66, 74, 82, - 90, 100, -}; - -static const uint8_t imdct_bits_tab[3] = { 8, 9, 11 }; - -static const DBEGroup grp_tab_0[1] = { - { 50, { 27, 23 }, 0, 0, nb_mantissa_50, 2, 0, 1152, 0, 1408, 0 }, -}; - -static const DBEGroup grp_tab_1[8] = { - { 38, { 12, 26 }, 0, 0, nb_mantissa_38, 0, 0, 192, 0, 256, 0 }, - { 38, { 12, 26 }, 38, 128, nb_mantissa_38, 0, 1, 256, 64, 448, 0 }, - { 38, { 12, 26 }, 76, 256, nb_mantissa_38, 0, 1, 256, 192, 704, 0 }, - { 38, { 12, 26 }, 114, 384, nb_mantissa_38, 0, 1, 256, 320, 0, 0 }, - { 38, { 12, 26 }, 152, 512, nb_mantissa_38, 0, 1, 256, 448, 0, 0 }, - { 38, { 12, 26 }, 190, 640, nb_mantissa_38, 0, 1, 256, 576, 0, 0 }, - { 38, { 12, 26 }, 228, 768, nb_mantissa_38, 0, 1, 256, 704, 0, 0 }, - { 38, { 12, 26 }, 266, 896, nb_mantissa_38, 0, 1, 256, 832, 0, 0 }, -}; - -static const DBEGroup grp_tab_2[7] = { - { 38, { 12, 26 }, 0, 0, nb_mantissa_38, 0, 0, 192, 0, 256, 0 }, - { 38, { 12, 26 }, 38, 128, nb_mantissa_38, 0, 1, 256, 64, 448, 0 }, - { 38, { 12, 26 }, 76, 256, nb_mantissa_38, 0, 1, 256, 192, 704, 0 }, - { 38, { 12, 26 }, 114, 384, nb_mantissa_38, 0, 1, 256, 320, 0, 0 }, - { 38, { 12, 26 }, 152, 512, nb_mantissa_38, 0, 1, 256, 448, 0, 0 }, - { 38, { 12, 26 }, 190, 640, nb_mantissa_38, 0, 1, 256, 576, 0, 0 }, - { 44, { 19, 25 }, 228, 768, nb_mantissa_44, 1, 1, 448, 704, 960, 64 }, -}; - -static const DBEGroup grp_tab_3[1] = { - { 21, { 21 }, 0, 0, nb_mantissa_50, 2, 0, 1152, 0, 1408, 0 }, -}; - -static const DBEGroup grp_tab_4[1] = { - { 50, { 27, 23 }, 0, 0, nb_mantissa_50, 2, 2, 1152, 0, 1408, 896 }, -}; - -static const DBEGroup grp_tab_5[8] = { - { 38, { 12, 26 }, 0, 0, nb_mantissa_38, 0, 1, 256, 64, 0, 0 }, - { 38, { 12, 26 }, 38, 128, nb_mantissa_38, 0, 1, 256, 192, 0, 0 }, - { 38, { 12, 26 }, 76, 256, nb_mantissa_38, 0, 1, 256, 320, 0, 0 }, - { 38, { 12, 26 }, 114, 384, nb_mantissa_38, 0, 1, 256, 448, 0, 0 }, - { 38, { 12, 26 }, 152, 512, nb_mantissa_38, 0, 1, 256, 576, 0, 0 }, - { 38, { 12, 26 }, 190, 640, nb_mantissa_38, 0, 1, 256, 704, 3008, 0 }, - { 38, { 12, 26 }, 228, 768, nb_mantissa_38, 0, 1, 256, 832, 2752, 0 }, - { 38, { 12, 26 }, 266, 896, nb_mantissa_38, 0, 2, 192, 960, 2560, 64 }, -}; - -static const DBEGroup grp_tab_6[7] = { - { 44, { 19, 25 }, 0, 0, nb_mantissa_44, 1, 1, 448, 0, 3264, 0 }, - { 38, { 12, 26 }, 44, 256, nb_mantissa_38, 0, 1, 256, 320, 0, 0 }, - { 38, { 12, 26 }, 82, 384, nb_mantissa_38, 0, 1, 256, 448, 0, 0 }, - { 38, { 12, 26 }, 120, 512, nb_mantissa_38, 0, 1, 256, 576, 0, 0 }, - { 38, { 12, 26 }, 158, 640, nb_mantissa_38, 0, 1, 256, 704, 3008, 0 }, - { 38, { 12, 26 }, 196, 768, nb_mantissa_38, 0, 1, 256, 832, 2752, 0 }, - { 38, { 12, 26 }, 234, 896, nb_mantissa_38, 0, 2, 192, 960, 2560, 64 }, -}; - -static const DBEGroup grp_tab_7[1] = { - { 21, { 21 }, 0, 0, nb_mantissa_50, 2, 2, 1152, 0, 1408, 896 }, -}; - -static const DBEGroup *const frm_ofs_tab[2][4] = { - { grp_tab_0, grp_tab_1, grp_tab_2, grp_tab_3 }, - { grp_tab_4, grp_tab_5, grp_tab_6, grp_tab_7 } -}; - -static const uint8_t mantissa_size1[16][4] = { - { 0, 0, 0, 0 }, { 2, 1, 1, 1 }, { 3, 2, 1, 1 }, { 4, 3, 2, 1 }, - { 5, 4, 3, 2 }, { 6, 5, 4, 3 }, { 7, 6, 5, 4 }, { 8, 7, 6, 5 }, - { 9, 8, 7, 6 }, { 10, 9, 8, 7 }, { 11, 10, 9, 8 }, { 12, 11, 10, 9 }, - { 13, 12, 11, 10 }, { 14, 13, 12, 11 }, { 15, 14, 13, 12 }, { 16, 15, 14, 13 }, -}; - -static const uint8_t mantissa_size2[16][4] = { - { 0, 0, 0, 0 }, { 2, 1, 2, 2 }, { 3, 2, 3, 3 }, { 4, 3, 4, 4 }, - { 5, 4, 5, 5 }, { 6, 5, 6, 6 }, { 7, 6, 7, 7 }, { 8, 7, 8, 8 }, - { 9, 8, 9, 9 }, { 10, 9, 10, 10 }, { 11, 10, 11, 11 }, { 12, 11, 12, 12 }, - { 13, 12, 13, 13 }, { 14, 13, 14, 14 }, { 15, 14, 15, 15 }, { 16, 15, 16, 16 }, -}; - -static const float start_window[192] = { - 0.00161569379826, 0.00185748233347, 0.00198562758548, 0.00207834078104, - 0.00215717748523, 0.00223067096393, 0.00230299213147, 0.00237651215396, - 0.00245275561606, 0.00253281402069, 0.00261754673613, 0.00270768786168, - 0.00280390761895, 0.00290684998656, 0.00301715751161, 0.00313548872798, - 0.00326253122934, 0.00339901215995, 0.00354570716636, 0.00370344845023, - 0.00387313232586, 0.00405572653911, 0.00425227750970, 0.00446391759265, - 0.00469187240551, 0.00493746822816, 0.00520213944619, 0.00548743597507, - 0.00579503056737, 0.00612672586953, 0.00648446105606, 0.00687031782873, - 0.00728652552677, 0.00773546505205, 0.00821967127415, 0.00874183354619, - 0.00930479393832, 0.00991154278653, 0.01056521116692, 0.01126905994567, - 0.01202646513050, 0.01284089936559, 0.01371590957417, 0.01465509096066, - 0.01566205783408, 0.01674041199523, 0.01789370972358, 0.01912542867865, - 0.02043893626265, 0.02183746113793, 0.02332406961796, 0.02490164852364, - 0.02657289580178, 0.02834031974193, 0.03020624702903, 0.03217283918354, - 0.03424211623810, 0.03641598586180, 0.03869627565015, 0.04108476601498, - 0.04358322107390, 0.04619341515939, 0.04891715301882, 0.05175628239149, - - 0.05471237327267, 0.05778734733755, 0.06098291402413, 0.06430101352084, - 0.06774345212186, 0.07131188644726, 0.07500780649199, 0.07883251748595, - 0.08278712056651, 0.08687249228061, 0.09108926295730, 0.09543779401074, - 0.09991815425851, 0.10453009536427, 0.10927302653894, 0.11414598865987, - 0.11914762799220, 0.12427616972097, 0.12952939152560, 0.13490459744934, - 0.14039859233595, 0.14600765712201, 0.15172752528722, 0.15755336077528, - 0.16347973770491, 0.16950062219342, 0.17560935661442, 0.18179864660619, - 0.18806055113821, 0.19438647593012, 0.20076717050010, 0.20719272909882, - 0.21365259576030, 0.22013557367283, 0.22662983904194, 0.23312295958328, - 0.23960191774666, 0.24605313873388, 0.25246252333253, 0.25881548554631, - 0.26509699495987, 0.27129162373316, 0.27738359807707, 0.28335685401987, - 0.28919509723179, 0.29488186663467, 0.30040060148455, 0.30573471157819, - 0.31086765019993, 0.31578298939317, 0.32046449711227, 0.32489621578468, - 0.32906254179156, 0.33294830535654, 0.33653885031840, 0.33982011325336, - 0.34277870140679, 0.34540196889300, 0.34767809062480, 0.34959613344194, - 0.35114612391958, 0.35231911235422, 0.35310723244504, 0.35350375621308, - - 0.35350314372945, 0.35310108725579, 0.35229454943591, 0.35108179521634, - 0.34946241721522, 0.34743735430290, 0.34500890320420, 0.34218072298001, - 0.33895783229541, 0.33534659943168, 0.33135472505060, 0.32699121776996, - 0.32226636266000, 0.31719168282019, 0.31177989424432, 0.30604485422875, - 0.30000150362379, 0.29366580327088, 0.28705466500775, 0.28018587766131, - 0.27307802848095, 0.26575042049535, 0.25822298630189, 0.25051619882000, - 0.24265097955783, 0.23464860495522, 0.22653061137548, 0.21831869932335, - 0.21003463746705, 0.20170016703857, 0.19333690717811, 0.18496626177620, - 0.17660932835062, 0.16828680947474, 0.16001892724986, 0.15182534128597, - 0.14372507062477, 0.13573642000364, 0.12787691082233, 0.12016321713317, - 0.11261110693234, 0.10523538898282, 0.09804986534955, 0.09106728977263, - 0.08429933194438, 0.07775654768810, 0.07144835495683, 0.06538301547324, - 0.05956762170687, 0.05400808871425, 0.04870915012107, 0.04367435714993, - 0.03890607899172, 0.03440550179663, 0.03017262174627, 0.02620622428513, - 0.02250383492507, 0.01906161305732, 0.01587412848221, 0.01293388032354, - 0.01023019677288, 0.00774641320626, 0.00545109736891, 0.00325868651263, -}; - -static const float short_window2[192] = { - 0.00018861094606, 0.00033433010202, 0.00050309624485, 0.00070306161748, - 0.00093995174533, 0.00121913067128, 0.00154606505568, 0.00192647806126, - 0.00236641248692, 0.00287225985240, 0.00345077377440, 0.00410907465023, - 0.00485464855241, 0.00569534163219, 0.00663935063508, 0.00769520981249, - 0.00887177436246, 0.01017820046395, 0.01162392194150, 0.01321862359335, - 0.01497221122468, 0.01689477844427, 0.01899657030441, 0.02128794388846, - 0.02377932597692, 0.02648116795039, 0.02940389811590, 0.03255787167130, - 0.03595331854986, 0.03960028941437, 0.04350860009563, 0.04768777479454, - 0.05214698838949, 0.05689500821121, 0.06194013566525, 0.06729014809766, - 0.07295224131210, 0.07893297315602, 0.08523820859989, 0.09187306673620, - 0.09884187012422, 0.10614809690222, 0.11379433608064, 0.12178224641797, - 0.13011251926531, 0.13878484574660, 0.14779788861830, 0.15714925912610, - 0.16683549914631, 0.17685206886673, 0.18719334022589, 0.19785259629099, - 0.20882203671372, 0.22009278936030, 0.23165492816694, 0.24349749722585, - 0.25560854105961, 0.26797514099368, 0.28058345748882, 0.29341877824732, - 0.30646557185942, 0.31970754671026, 0.33312771482295, 0.34670846027024, - - 0.36043161174692, 0.37427851885723, 0.38823013163645, 0.40226708279486, - 0.41636977214436, 0.43051845264462, 0.44469331748632, 0.45887458761470, - 0.47304259908636, 0.48717788964798, 0.50126128392546, 0.51527397661778, - 0.52919761310050, 0.54301436685998, 0.55670701320069, 0.57025899869448, - 0.58365450587230, 0.59687851269542, 0.60991684638414, 0.62275623122793, - 0.63538433005035, 0.64778977905593, 0.65996221584264, 0.67189230042379, - 0.68357172916486, 0.69499324160511, 0.70615062019861, 0.71703868307548, - 0.72765326998919, 0.73799122168099, 0.74805035295521, 0.75782941981995, - 0.76732808110520, 0.77654685502339, 0.78548707118622, 0.79415081863423, - 0.80254089047207, 0.81066072573188, 0.81851434910893, 0.82610630922734, - 0.83344161609862, 0.84052567843230, 0.84736424144524, 0.85396332579459, - 0.86032916822973, 0.86646816451999, 0.87238681516918, 0.87809167437532, - 0.88358930263537, 0.88888622333073, 0.89398888356256, 0.89890361943564, - 0.90363662591861, 0.90819393133744, 0.91258137648979, 0.91680459830070, - 0.92086901787718, 0.92477983276087, 0.92854201312583, 0.93216030163834, - 0.93563921662343, 0.93898305819384, 0.94219591693690, 0.94528168477979, - - 0.94823843319821, 0.95106834367330, 0.95377776558539, 0.95636718335775, - 0.95883679961479, 0.96118650212341, 0.96341583179195, 0.96552395212906, - 0.96750962060547, 0.96937116231768, 0.97110644638309, 0.97271286544154, - 0.97418731862798, 0.97552619834964, 0.97672538116257, 0.97778022299974, - 0.97868555895586, 0.97943570778357, 0.98002448120255, 0.98044519806866, - 0.98069070339493, 0.98075339216123, 0.98062523779637, 0.98029782516478, - 0.97976238784222, 0.97900984942031, 0.97803086854002, 0.97681588731895, - 0.97535518280755, 0.97363892108474, 0.97165721358452, 0.96940017523145, - 0.96685798395452, 0.96402094114589, 0.96087953263194, 0.95742448973047, - 0.95364684997699, 0.94953801711660, 0.94508981997396, 0.94029456983253, - 0.93514511597504, 0.92963489905951, 0.92375800202883, 0.91750919827624, - 0.91088399681406, 0.90387868421832, 0.89649036314692, 0.88871698725397, - 0.88055739234735, 0.87201132366062, 0.86307945913336, 0.85376342861693, - 0.84406582894455, 0.83399023482637, 0.82354120554757, 0.81272428745995, - 0.80154601230457, 0.79001389138101, 0.77813640562199, 0.76592299164227, - 0.75338402384395, 0.74053079267526, 0.72737547915460, 0.71393112578527, -}; - -static const float short_window3[64] = { - 0.00326887936450, 0.00550242900936, 0.00786846643791, 0.01045683453520, - 0.01330402120132, 0.01643221072863, 0.01985798040609, 0.02359509464766, - 0.02765559221954, 0.03205025893128, 0.03678884369614, 0.04188015679495, - 0.04733210987781, 0.05315172583924, 0.05934513287609, 0.06591755045290, - 0.07287327156378, 0.08021564389822, 0.08794705152307, 0.09606889811179, - 0.10458159240070, 0.11348453632940, 0.12277611617809, 0.13245369691511, - 0.14251361989876, 0.15295120402567, 0.16376075037904, 0.17493555039885, - 0.18646789757072, 0.19834910260891, 0.21056951208995, 0.22311853047787, - 0.23598464546683, 0.24915545655419, 0.26261770674500, 0.27635731727778, - 0.29035942525136, 0.30460842402318, 0.31908800624032, 0.33378120935681, - 0.34867046348260, 0.36373764140285, 0.37896411059909, 0.39433078709788, - 0.40981819096657, 0.42540650327031, 0.44107562429959, 0.45680523287270, - 0.47257484651351, 0.48836388230077, 0.50415171818214, 0.51991775454258, - 0.53564147581496, 0.55130251191887, 0.56688069931047, 0.58235614142007, - 0.59770926827271, 0.61292089506118, 0.62797227945823, 0.64284517745255, - 0.65752189749349, 0.67198535273209, 0.68621911114984, 0.70020744337099, -}; - -static const uint8_t dc_code_tab[5] = { 0, 0, 0, 1, 1 }; - -static const uint8_t ht_code_tab[5] = { 0, 0, 1, 2, 2 }; - -static const uint8_t band_ofs_tab[3][4] = { - { 12, 8, 4, 0 }, { 14, 10, 6, 0 }, { 12, 8, 4, 0 } -}; - -static const uint8_t band_low_tab[3] = { 9, 17, 24 }; - -static const uint16_t fast_gain_tab[8] = { - 128, 256, 384, 512, 640, 768, 896, 1024 -}; - -static const uint16_t slow_decay_tab[2][2] = { { 27, -1 }, { 32, 21 } }; - -static const uint16_t misc_decay_tab[3][2][2] = { - { { 354, -1 }, { 425, 425 } }, - { { 266, -1 }, { 320, -1 } }, - { { 213, -1 }, { 256, -1 } } -}; - -static const uint16_t fast_decay_tab[3][2][2][50] = { - {{{ - 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, - 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, - 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, - 142, 142, 142, 142, 142, 142, 142, 142, - }, { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - }}, {{ - 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, - }, { - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - }}}, {{{ - 266, 266, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, - }, { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, - }}, {{ - 319, 319, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, - }, { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, - }}}, {{{ - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - }, { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - }}, {{ - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - }, { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - }}} -}; - -static const uint16_t fast_gain_adj_tab[3][2][62] = { - {{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 4, 7, 11, 16, 29, 44, 59, - 76, 94, 116, 142, 179, 221, 252, 285, 312, 334, - }, { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2, 5, 8, 10, 15, 28, 42, 57, 75, 93, - 115, 140, 177, 219, 247, 280, 308, 330, 427, 533, - }}, {{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 5, 8, 12, 21, 35, 51, 69, 89, - 111, 138, 176, 220, 251, 284, 312, 334, - }, { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, - 5, 8, 11, 18, 33, 49, 65, 84, 106, 132, - 168, 214, 245, 279, 308, 329, 427, 533, - }}, {{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 4, 7, 10, 17, - 31, 47, 65, 84, 107, 134, 171, 215, 250, 283, - 312, 334, - }, { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3, 6, 9, 13, 27, 43, - 60, 79, 100, 126, 160, 207, 242, 276, 307, 329, - 427, 533, - }} -}; - -static const uint16_t slow_gain_tab[3][2][50] = { - {{ - 3072, 3072, 3072, 3072, 3072, 3072, 1063, 1063, 1063, 1063, - 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, - 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, - 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, - }, { - 3072, 3072, 3072, 3072, 3072, 3072, 850, 850, 850, 850, - 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, - 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, - 850, 850, 850, 850, 850, 850, 850, 850, - }}, {{ - 3072, 1212, 1212, 1212, 999, 999, 999, 999, 999, 999, - 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, - 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, - 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, - 999, 999, 999, 999, - }, { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, - }}, {{ - 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, - 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, - 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, - 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, - 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, - }, { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - }} -}; - -static const uint16_t hearing_thresh_tab[3][3][50] = { - {{ - 1403, 1141, 1000, 959, 948, 957, 946, 925, 899, 871, - 843, 815, 789, 766, 745, 727, 705, 687, 681, 686, - 701, 725, 768, 854, 940, 1018, 1075, 1103, 1111, 1106, - 1098, 1105, 1142, 1237, 1419, 1721, 2169, 2805, - }, { - 1401, 1130, 995, 957, 947, 955, 941, 918, 890, 861, - 831, 803, 777, 754, 734, 717, 698, 684, 682, 692, - 712, 743, 798, 894, 976, 1045, 1091, 1109, 1110, 1102, - 1098, 1116, 1174, 1300, 1526, 1884, 2401, 3072, - }, { - 1393, 1086, 974, 949, 957, 941, 913, 878, 843, 808, - 777, 750, 727, 708, 695, 686, 681, 689, 714, 752, - 811, 888, 971, 1044, 1087, 1108, 1110, 1102, 1098, 1115, - 1172, 1290, 1489, 1812, 2293, 2964, 3072, 3072, - }}, {{ - 1412, 1343, 1141, 1047, 1000, 974, 959, 951, 948, 947, - 957, 953, 946, 936, 925, 906, 878, 850, 822, 795, - 771, 745, 719, 700, 687, 681, 685, 701, 733, 784, - 885, 977, 1047, 1092, 1110, 1108, 1099, 1102, 1138, 1233, - 1413, 1711, 2157, 2797, - }, { - 1412, 1336, 1130, 1040, 995, 970, 957, 950, 947, 947, - 955, 950, 941, 930, 918, 897, 868, 838, 810, 783, - 759, 734, 710, 693, 684, 681, 690, 712, 752, 823, - 924, 1009, 1069, 1102, 1111, 1104, 1098, 1111, 1168, 1295, - 1518, 1873, 2388, 3072, - }, { - 1411, 1293, 1086, 1009, 974, 957, 949, 947, 957, 951, - 941, 928, 913, 896, 878, 852, 817, 785, 756, 732, - 713, 695, 683, 682, 689, 710, 746, 811, 906, 992, - 1061, 1099, 1111, 1106, 1098, 1107, 1155, 1266, 1471, 1799, - 2277, 2945, 3072, 3072, - }}, {{ - 1431, 1412, 1403, 1379, 1343, 1293, 1229, 1180, 1125, 1075, - 1040, 1014, 996, 979, 965, 957, 951, 948, 947, 957, - 951, 940, 924, 903, 877, 846, 815, 785, 753, 725, - 702, 686, 681, 689, 714, 760, 847, 947, 1028, 1083, - 1108, 1109, 1101, 1100, 1132, 1222, 1402, 1705, 2160, 2803, - }, { - 1431, 1412, 1401, 1375, 1336, 1278, 1215, 1168, 1115, 1066, - 1032, 1008, 991, 975, 962, 954, 950, 947, 947, 955, - 948, 935, 916, 894, 866, 835, 803, 772, 742, 715, - 695, 683, 683, 697, 729, 784, 887, 982, 1054, 1096, - 1111, 1106, 1098, 1107, 1159, 1281, 1505, 1865, 2391, 3072, - }, { - 1427, 1411, 1393, 1353, 1293, 1215, 1160, 1118, 1072, 1031, - 1003, 984, 971, 960, 952, 948, 947, 957, 952, 941, - 924, 902, 876, 847, 815, 781, 750, 723, 700, 685, - 681, 691, 719, 766, 858, 958, 1039, 1089, 1109, 1108, - 1099, 1102, 1141, 1245, 1442, 1766, 2250, 2930, 3072, 3072, - }} -}; - -static const int16_t lwc_gain_tab[11][7] = { - { -21, -197, -271, -466, 32767, 32767, 32767 }, - { -197, -29, -244, -271, -540, 32767, 32767 }, - { -271, -244, -29, -249, -271, -593, 32767 }, - { -466, -271, -249, -29, -251, -271, -632 }, - { -540, -271, -251, -29, -251, -271, -664 }, - { -593, -271, -251, -29, -252, -271, -690 }, - { -632, -271, -252, -29, -252, -271, -711 }, - { -664, -271, -252, -29, -252, -271, -730 }, - { -690, -271, -252, -29, -252, -271, -745 }, - { -711, -271, -252, -29, -253, -271, -759 }, - { -730, -271, -253, -29, -253, -271, -771 }, -}; - -static const int16_t lwc_adj_tab[7] = { - -192, -320, -448, -512, -448, -320, -192, -}; - -static const uint8_t log_add_tab[212] = { - 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 52, 51, 50, - 49, 48, 47, 47, 46, 45, 44, 44, 43, 42, 41, 41, 40, 39, 38, 38, - 37, 36, 36, 35, 35, 34, 33, 33, 32, 32, 31, 30, 30, 29, 29, 28, - 28, 27, 27, 26, 26, 25, 25, 24, 24, 23, 23, 22, 22, 21, 21, 21, - 20, 20, 19, 19, 19, 18, 18, 18, 17, 17, 17, 16, 16, 16, 15, 15, - 15, 14, 14, 14, 13, 13, 13, 13, 12, 12, 12, 12, 11, 11, 11, 11, - 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, - 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, - 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 0, 0, -}; - -static const uint8_t bap_tab[64] = { - 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, - 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, - 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, - 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 15, -}; - -static float mantissa_tab1[17][4]; -static float mantissa_tab2[17][4]; -static float mantissa_tab3[17][4]; -static float exponent_tab[50]; -static float gain_tab[1024]; - -DECLARE_ALIGNED(32, static float, window)[3712]; - #endif diff --git a/libavcodec/dolby_e_parser.c b/libavcodec/dolby_e_parser.c new file mode 100644 index 0000000000..31275be122 --- /dev/null +++ b/libavcodec/dolby_e_parser.c @@ -0,0 +1,227 @@ +/* + * Copyright (C) 2017 foo86 + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "parser.h" + +#if CONFIG_DOLBY_E_PARSER | CONFIG_DOLBY_E_DECODER + +#include "get_bits.h" +#include "put_bits.h" +#include "dolby_e_parser.h" +#include "dolby_e_parser_internal.h" + +static int skip_input(DBEContext *s, int nb_words) +{ + if (nb_words > s->input_size) { + return AVERROR_INVALIDDATA; + } + + s->input += nb_words * s->word_bytes; + s->input_size -= nb_words; + return 0; +} + +static int parse_key(DBEContext *s) +{ + if (s->key_present) { + const uint8_t *key = s->input; + int ret = skip_input(s, 1); + if (ret < 0) + return ret; + return AV_RB24(key) >> 24 - s->word_bits; + } + return 0; +} + +static int convert_input(DBEContext *s, int nb_words, int key) +{ + const uint8_t *src = s->input; + uint8_t *dst = s->buffer; + PutBitContext pb; + int i; + + av_assert0(nb_words <= 1024u); + + if (nb_words > s->input_size) { + return AVERROR_INVALIDDATA; + } + + switch (s->word_bits) { + case 16: + for (i = 0; i < nb_words; i++, src += 2, dst += 2) + AV_WB16(dst, AV_RB16(src) ^ key); + break; + case 20: + init_put_bits(&pb, s->buffer, sizeof(s->buffer)); + for (i = 0; i < nb_words; i++, src += 3) + put_bits(&pb, 20, AV_RB24(src) >> 4 ^ key); + flush_put_bits(&pb); + break; + case 24: + for (i = 0; i < nb_words; i++, src += 3, dst += 3) + AV_WB24(dst, AV_RB24(src) ^ key); + break; + default: + av_assert0(0); + } + + return init_get_bits(&s->gb, s->buffer, nb_words * s->word_bits); +} + +int ff_dolby_e_parse_init(DBEContext *s, const uint8_t *buf, int buf_size) +{ + int hdr; + + if (buf_size < 3) + return AVERROR_INVALIDDATA; + + hdr = AV_RB24(buf); + if ((hdr & 0xfffffe) == 0x7888e) { + s->word_bits = 24; + } else if ((hdr & 0xffffe0) == 0x788e0) { + s->word_bits = 20; + } else if ((hdr & 0xfffe00) == 0x78e00) { + s->word_bits = 16; + } else { + if (s->avctx) + av_log(s->avctx, AV_LOG_ERROR, "Invalid frame header\n"); + return AVERROR_INVALIDDATA; + } + + s->word_bytes = s->word_bits + 7 >> 3; + s->input = buf + s->word_bytes; + s->input_size = buf_size / s->word_bytes - 1; + s->key_present = hdr >> 24 - s->word_bits & 1; + + return 0; +} + +int ff_dolby_e_parse_header(DBEContext *s, DolbyEHeaderInfo *hdr) +{ + int i, ret, key, mtd_size; + + if ((key = parse_key(s)) < 0) + return key; + if ((ret = convert_input(s, 1, key)) < 0) + return ret; + + skip_bits(&s->gb, 4); + mtd_size = get_bits(&s->gb, 10); + if (!mtd_size) { + if (s->avctx) + av_log(s->avctx, AV_LOG_ERROR, "Invalid metadata size\n"); + return AVERROR_INVALIDDATA; + } + + if ((ret = convert_input(s, mtd_size, key)) < 0) + return ret; + + skip_bits(&s->gb, 14); + hdr->prog_conf = get_bits(&s->gb, 6); + if (hdr->prog_conf > MAX_PROG_CONF) { + if (s->avctx) + av_log(s->avctx, AV_LOG_ERROR, "Invalid program configuration\n"); + return AVERROR_INVALIDDATA; + } + + hdr->nb_channels = nb_channels_tab[hdr->prog_conf]; + hdr->nb_programs = nb_programs_tab[hdr->prog_conf]; + + hdr->fr_code = get_bits(&s->gb, 4); + hdr->fr_code_orig = get_bits(&s->gb, 4); + if (!sample_rate_tab[hdr->fr_code] || + !sample_rate_tab[hdr->fr_code_orig]) { + if (s->avctx) + av_log(s->avctx, AV_LOG_ERROR, "Invalid frame rate code\n"); + return AVERROR_INVALIDDATA; + } + + skip_bits_long(&s->gb, 88); + for (i = 0; i < hdr->nb_channels; i++) + hdr->ch_size[i] = get_bits(&s->gb, 10); + hdr->mtd_ext_size = get_bits(&s->gb, 8); + hdr->meter_size = get_bits(&s->gb, 8); + + skip_bits_long(&s->gb, 10 * hdr->nb_programs); + for (i = 0; i < hdr->nb_channels; i++) { + hdr->rev_id[i] = get_bits(&s->gb, 4); + skip_bits1(&s->gb); + hdr->begin_gain[i] = get_bits(&s->gb, 10); + hdr->end_gain[i] = get_bits(&s->gb, 10); + } + + if (get_bits_left(&s->gb) < 0) { + if (s->avctx) + av_log(s->avctx, AV_LOG_ERROR, "Read past end of metadata\n"); + return AVERROR_INVALIDDATA; + } + + return skip_input(s, mtd_size + 1); +} +#endif /* CONFIG_DOLBY_E_PARSER | CONFIG_DOLBY_E_DECODER */ + +#if CONFIG_DOLBY_E_PARSER + +static int dolby_e_parse(AVCodecParserContext *s2, AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + DBEParseContext *s1 = s2->priv_data; + DBEContext *s = &s1->dectx; + int ret; + + if ((ret = ff_dolby_e_parse_init(s, buf, buf_size)) < 0) + goto end; + + if ((ret = ff_dolby_e_parse_header(s, &s1->metadata)) < 0) + goto end; + + s2->duration = FRAME_SAMPLES; + switch (s1->metadata.nb_channels) { + case 4: + avctx->channel_layout = AV_CH_LAYOUT_4POINT0; + break; + case 6: + avctx->channel_layout = AV_CH_LAYOUT_5POINT1; + break; + case 8: + avctx->channel_layout = AV_CH_LAYOUT_7POINT1; + break; + } + + avctx->channels = s1->metadata.nb_channels; + avctx->sample_rate = sample_rate_tab[s1->metadata.fr_code]; + avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; + +end: + /* always return the full packet. this parser isn't doing any splitting or + combining, only packet analysis */ + *poutbuf = buf; + *poutbuf_size = buf_size; + return buf_size; +} + +AVCodecParser ff_dolby_e_parser = { + .codec_ids = { AV_CODEC_ID_DOLBY_E }, + .priv_data_size = sizeof(DBEParseContext), + .parser_parse = dolby_e_parse, + .parser_close = ff_parse_close, +}; +#endif /* CONFIG_DOLBY_E_PARSER */ \ No newline at end of file diff --git a/libavcodec/dolby_e_parser.h b/libavcodec/dolby_e_parser.h new file mode 100644 index 0000000000..2f9a2b2ebb --- /dev/null +++ b/libavcodec/dolby_e_parser.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2017 foo86 + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_DOLBY_E_PARSER_H +#define AVCODEC_DOLBY_E_PARSER_H + +#include "dolby_e.h" + +typedef struct DBEParseContext { + ParseContext pc; + DBEContext dectx; + + DolbyEHeaderInfo metadata; +} DBEParseContext; + +static const uint8_t nb_programs_tab[MAX_PROG_CONF + 1] = { + 2, 3, 2, 3, 4, 5, 4, 5, 6, 7, 8, 1, 2, 3, 3, 4, 5, 6, 1, 2, 3, 4, 1, 1 +}; + +static const uint8_t nb_channels_tab[MAX_PROG_CONF + 1] = { + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 6, 6, 6, 6, 6, 6, 6, 4, 4, 4, 4, 8, 8 +}; + +#endif diff --git a/libavcodec/dolby_e_parser_internal.h b/libavcodec/dolby_e_parser_internal.h new file mode 100644 index 0000000000..defd1f97d6 --- /dev/null +++ b/libavcodec/dolby_e_parser_internal.h @@ -0,0 +1,46 @@ +/* + * Dolby E parser internal code + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_DOLBY_E_PARSER_INTERNAL_H +#define AVCODEC_DOLBY_E_PARSER_INTERNAL_H + +#include "dolby_e.h" + +/** + * Initialize DBEContext. + * Set word_bits/word_bytes, input, input_size, key_present. + * @param[out] s DBEContext. + * @param[in] buf raw input buffer. + * @param[in] buf_size must be 3 bytes at least. + * @return Returns 0 on success, AVERROR_INVALIDDATA on error + */ +int ff_dolby_e_parse_init(DBEContext *s, const uint8_t *buf, int buf_size); + +/** + * Parse Dolby E metadata. + * Parse the header up to the end_gain element. + * @param[in] s DBEContext . + * @param[out] hdr Pointer to struct where header info is written. + * @return Returns 0 on success, AVERROR_INVALIDDATA on error + */ +int ff_dolby_e_parse_header(DBEContext *s, DolbyEHeaderInfo *hdr); + + +#endif /* AVCODEC_DOLBY_E_PARSER_INTERNAL_H */ diff --git a/libavcodec/dolby_edec.h b/libavcodec/dolby_edec.h new file mode 100644 index 0000000000..02760bb852 --- /dev/null +++ b/libavcodec/dolby_edec.h @@ -0,0 +1,607 @@ +/* + * Copyright (C) 2017 foo86 + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_DOLBY_EDEC_H +#define AVCODEC_DOLBY_EDEC_H + +#include "libavutil/float_dsp.h" +#include "libavutil/libm.h" +#include "libavutil/mem_internal.h" + +#include "internal.h" +#include "get_bits.h" +#include "kbdwin.h" +#include "fft.h" + +#define MAX_SEGMENTS 2 + +#define MAX_GROUPS 8 +#define MAX_EXPONENTS 304 +#define MAX_MANTISSAS 1024 + +#define MAX_MSTR_EXP 2 +#define MAX_BIAS_EXP 50 + +typedef struct DBEGroup { + uint8_t nb_exponent; + uint8_t nb_bias_exp[MAX_MSTR_EXP]; + uint16_t exp_ofs; + uint16_t mnt_ofs; + const uint8_t *nb_mantissa; + uint8_t imdct_idx; + uint8_t imdct_phs; + uint16_t win_len; + uint16_t dst_ofs; + uint16_t win_ofs; + uint16_t src_ofs; +} DBEGroup; + +typedef struct DBEChannel { + int gr_code; + int bw_code; + + int nb_groups; + int nb_mstr_exp; + DBEGroup groups[MAX_GROUPS]; + + int exp_strategy[MAX_GROUPS]; + int exponents[MAX_EXPONENTS]; + int bap[MAX_EXPONENTS]; + int idx[MAX_EXPONENTS]; + + DECLARE_ALIGNED(32, float, mantissas)[MAX_MANTISSAS]; +} DBEChannel; + +typedef struct DBEDecodeContext { + AVCodecContext *avctx; + DBEContext dectx; + + DolbyEHeaderInfo metadata; + + DBEChannel channels[MAX_SEGMENTS][MAX_CHANNELS]; + + DECLARE_ALIGNED(32, float, history)[MAX_CHANNELS][256]; + + FFTContext imdct[3]; + AVFloatDSPContext *fdsp; +} DBEDecodeContext; + +static const int8_t lfe_channel_tab[MAX_PROG_CONF + 1] = { + 5, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5, 5 +}; + +static const uint8_t ch_reorder_4[4] = { 0, 2, 1, 3 }; +static const uint8_t ch_reorder_6[6] = { 0, 2, 4, 1, 3, 5 }; +static const uint8_t ch_reorder_8[8] = { 0, 2, 6, 4, 1, 3, 7, 5 }; +static const uint8_t ch_reorder_n[8] = { 0, 2, 4, 6, 1, 3, 5, 7 }; + + +static const uint8_t nb_groups_tab[4] = { 1, 8, 7, 1 }; + +static const uint8_t nb_mstr_exp_tab[4] = { 2, 2, 2, 1 }; + +static const uint8_t nb_mantissa_38[38] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, + 7, 8, 9, 10, 11, 12, +}; + +static const uint8_t nb_mantissa_44[44] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, + 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 6, 7, 7, + 8, 9, 10, 11, 12, 13, 15, 16, 18, 20, 22, 25, +}; + +static const uint8_t nb_mantissa_50[50] = { + 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, + 3, 4, 4, 5, 5, 6, 6, 7, 8, 9, 9, 10, 12, 13, 14, 16, + 18, 19, 22, 24, 27, 29, 32, 36, 40, 44, 49, 54, 60, 66, 74, 82, + 90, 100, +}; + +static const uint8_t imdct_bits_tab[3] = { 8, 9, 11 }; + +static const DBEGroup grp_tab_0[1] = { + { 50, { 27, 23 }, 0, 0, nb_mantissa_50, 2, 0, 1152, 0, 1408, 0 }, +}; + +static const DBEGroup grp_tab_1[8] = { + { 38, { 12, 26 }, 0, 0, nb_mantissa_38, 0, 0, 192, 0, 256, 0 }, + { 38, { 12, 26 }, 38, 128, nb_mantissa_38, 0, 1, 256, 64, 448, 0 }, + { 38, { 12, 26 }, 76, 256, nb_mantissa_38, 0, 1, 256, 192, 704, 0 }, + { 38, { 12, 26 }, 114, 384, nb_mantissa_38, 0, 1, 256, 320, 0, 0 }, + { 38, { 12, 26 }, 152, 512, nb_mantissa_38, 0, 1, 256, 448, 0, 0 }, + { 38, { 12, 26 }, 190, 640, nb_mantissa_38, 0, 1, 256, 576, 0, 0 }, + { 38, { 12, 26 }, 228, 768, nb_mantissa_38, 0, 1, 256, 704, 0, 0 }, + { 38, { 12, 26 }, 266, 896, nb_mantissa_38, 0, 1, 256, 832, 0, 0 }, +}; + +static const DBEGroup grp_tab_2[7] = { + { 38, { 12, 26 }, 0, 0, nb_mantissa_38, 0, 0, 192, 0, 256, 0 }, + { 38, { 12, 26 }, 38, 128, nb_mantissa_38, 0, 1, 256, 64, 448, 0 }, + { 38, { 12, 26 }, 76, 256, nb_mantissa_38, 0, 1, 256, 192, 704, 0 }, + { 38, { 12, 26 }, 114, 384, nb_mantissa_38, 0, 1, 256, 320, 0, 0 }, + { 38, { 12, 26 }, 152, 512, nb_mantissa_38, 0, 1, 256, 448, 0, 0 }, + { 38, { 12, 26 }, 190, 640, nb_mantissa_38, 0, 1, 256, 576, 0, 0 }, + { 44, { 19, 25 }, 228, 768, nb_mantissa_44, 1, 1, 448, 704, 960, 64 }, +}; + +static const DBEGroup grp_tab_3[1] = { + { 21, { 21 }, 0, 0, nb_mantissa_50, 2, 0, 1152, 0, 1408, 0 }, +}; + +static const DBEGroup grp_tab_4[1] = { + { 50, { 27, 23 }, 0, 0, nb_mantissa_50, 2, 2, 1152, 0, 1408, 896 }, +}; + +static const DBEGroup grp_tab_5[8] = { + { 38, { 12, 26 }, 0, 0, nb_mantissa_38, 0, 1, 256, 64, 0, 0 }, + { 38, { 12, 26 }, 38, 128, nb_mantissa_38, 0, 1, 256, 192, 0, 0 }, + { 38, { 12, 26 }, 76, 256, nb_mantissa_38, 0, 1, 256, 320, 0, 0 }, + { 38, { 12, 26 }, 114, 384, nb_mantissa_38, 0, 1, 256, 448, 0, 0 }, + { 38, { 12, 26 }, 152, 512, nb_mantissa_38, 0, 1, 256, 576, 0, 0 }, + { 38, { 12, 26 }, 190, 640, nb_mantissa_38, 0, 1, 256, 704, 3008, 0 }, + { 38, { 12, 26 }, 228, 768, nb_mantissa_38, 0, 1, 256, 832, 2752, 0 }, + { 38, { 12, 26 }, 266, 896, nb_mantissa_38, 0, 2, 192, 960, 2560, 64 }, +}; + +static const DBEGroup grp_tab_6[7] = { + { 44, { 19, 25 }, 0, 0, nb_mantissa_44, 1, 1, 448, 0, 3264, 0 }, + { 38, { 12, 26 }, 44, 256, nb_mantissa_38, 0, 1, 256, 320, 0, 0 }, + { 38, { 12, 26 }, 82, 384, nb_mantissa_38, 0, 1, 256, 448, 0, 0 }, + { 38, { 12, 26 }, 120, 512, nb_mantissa_38, 0, 1, 256, 576, 0, 0 }, + { 38, { 12, 26 }, 158, 640, nb_mantissa_38, 0, 1, 256, 704, 3008, 0 }, + { 38, { 12, 26 }, 196, 768, nb_mantissa_38, 0, 1, 256, 832, 2752, 0 }, + { 38, { 12, 26 }, 234, 896, nb_mantissa_38, 0, 2, 192, 960, 2560, 64 }, +}; + +static const DBEGroup grp_tab_7[1] = { + { 21, { 21 }, 0, 0, nb_mantissa_50, 2, 2, 1152, 0, 1408, 896 }, +}; + +static const DBEGroup *const frm_ofs_tab[2][4] = { + { grp_tab_0, grp_tab_1, grp_tab_2, grp_tab_3 }, + { grp_tab_4, grp_tab_5, grp_tab_6, grp_tab_7 } +}; + +static const uint8_t mantissa_size1[16][4] = { + { 0, 0, 0, 0 }, { 2, 1, 1, 1 }, { 3, 2, 1, 1 }, { 4, 3, 2, 1 }, + { 5, 4, 3, 2 }, { 6, 5, 4, 3 }, { 7, 6, 5, 4 }, { 8, 7, 6, 5 }, + { 9, 8, 7, 6 }, { 10, 9, 8, 7 }, { 11, 10, 9, 8 }, { 12, 11, 10, 9 }, + { 13, 12, 11, 10 }, { 14, 13, 12, 11 }, { 15, 14, 13, 12 }, { 16, 15, 14, 13 }, +}; + +static const uint8_t mantissa_size2[16][4] = { + { 0, 0, 0, 0 }, { 2, 1, 2, 2 }, { 3, 2, 3, 3 }, { 4, 3, 4, 4 }, + { 5, 4, 5, 5 }, { 6, 5, 6, 6 }, { 7, 6, 7, 7 }, { 8, 7, 8, 8 }, + { 9, 8, 9, 9 }, { 10, 9, 10, 10 }, { 11, 10, 11, 11 }, { 12, 11, 12, 12 }, + { 13, 12, 13, 13 }, { 14, 13, 14, 14 }, { 15, 14, 15, 15 }, { 16, 15, 16, 16 }, +}; + +static const float start_window[192] = { + 0.00161569379826, 0.00185748233347, 0.00198562758548, 0.00207834078104, + 0.00215717748523, 0.00223067096393, 0.00230299213147, 0.00237651215396, + 0.00245275561606, 0.00253281402069, 0.00261754673613, 0.00270768786168, + 0.00280390761895, 0.00290684998656, 0.00301715751161, 0.00313548872798, + 0.00326253122934, 0.00339901215995, 0.00354570716636, 0.00370344845023, + 0.00387313232586, 0.00405572653911, 0.00425227750970, 0.00446391759265, + 0.00469187240551, 0.00493746822816, 0.00520213944619, 0.00548743597507, + 0.00579503056737, 0.00612672586953, 0.00648446105606, 0.00687031782873, + 0.00728652552677, 0.00773546505205, 0.00821967127415, 0.00874183354619, + 0.00930479393832, 0.00991154278653, 0.01056521116692, 0.01126905994567, + 0.01202646513050, 0.01284089936559, 0.01371590957417, 0.01465509096066, + 0.01566205783408, 0.01674041199523, 0.01789370972358, 0.01912542867865, + 0.02043893626265, 0.02183746113793, 0.02332406961796, 0.02490164852364, + 0.02657289580178, 0.02834031974193, 0.03020624702903, 0.03217283918354, + 0.03424211623810, 0.03641598586180, 0.03869627565015, 0.04108476601498, + 0.04358322107390, 0.04619341515939, 0.04891715301882, 0.05175628239149, + + 0.05471237327267, 0.05778734733755, 0.06098291402413, 0.06430101352084, + 0.06774345212186, 0.07131188644726, 0.07500780649199, 0.07883251748595, + 0.08278712056651, 0.08687249228061, 0.09108926295730, 0.09543779401074, + 0.09991815425851, 0.10453009536427, 0.10927302653894, 0.11414598865987, + 0.11914762799220, 0.12427616972097, 0.12952939152560, 0.13490459744934, + 0.14039859233595, 0.14600765712201, 0.15172752528722, 0.15755336077528, + 0.16347973770491, 0.16950062219342, 0.17560935661442, 0.18179864660619, + 0.18806055113821, 0.19438647593012, 0.20076717050010, 0.20719272909882, + 0.21365259576030, 0.22013557367283, 0.22662983904194, 0.23312295958328, + 0.23960191774666, 0.24605313873388, 0.25246252333253, 0.25881548554631, + 0.26509699495987, 0.27129162373316, 0.27738359807707, 0.28335685401987, + 0.28919509723179, 0.29488186663467, 0.30040060148455, 0.30573471157819, + 0.31086765019993, 0.31578298939317, 0.32046449711227, 0.32489621578468, + 0.32906254179156, 0.33294830535654, 0.33653885031840, 0.33982011325336, + 0.34277870140679, 0.34540196889300, 0.34767809062480, 0.34959613344194, + 0.35114612391958, 0.35231911235422, 0.35310723244504, 0.35350375621308, + + 0.35350314372945, 0.35310108725579, 0.35229454943591, 0.35108179521634, + 0.34946241721522, 0.34743735430290, 0.34500890320420, 0.34218072298001, + 0.33895783229541, 0.33534659943168, 0.33135472505060, 0.32699121776996, + 0.32226636266000, 0.31719168282019, 0.31177989424432, 0.30604485422875, + 0.30000150362379, 0.29366580327088, 0.28705466500775, 0.28018587766131, + 0.27307802848095, 0.26575042049535, 0.25822298630189, 0.25051619882000, + 0.24265097955783, 0.23464860495522, 0.22653061137548, 0.21831869932335, + 0.21003463746705, 0.20170016703857, 0.19333690717811, 0.18496626177620, + 0.17660932835062, 0.16828680947474, 0.16001892724986, 0.15182534128597, + 0.14372507062477, 0.13573642000364, 0.12787691082233, 0.12016321713317, + 0.11261110693234, 0.10523538898282, 0.09804986534955, 0.09106728977263, + 0.08429933194438, 0.07775654768810, 0.07144835495683, 0.06538301547324, + 0.05956762170687, 0.05400808871425, 0.04870915012107, 0.04367435714993, + 0.03890607899172, 0.03440550179663, 0.03017262174627, 0.02620622428513, + 0.02250383492507, 0.01906161305732, 0.01587412848221, 0.01293388032354, + 0.01023019677288, 0.00774641320626, 0.00545109736891, 0.00325868651263, +}; + +static const float short_window2[192] = { + 0.00018861094606, 0.00033433010202, 0.00050309624485, 0.00070306161748, + 0.00093995174533, 0.00121913067128, 0.00154606505568, 0.00192647806126, + 0.00236641248692, 0.00287225985240, 0.00345077377440, 0.00410907465023, + 0.00485464855241, 0.00569534163219, 0.00663935063508, 0.00769520981249, + 0.00887177436246, 0.01017820046395, 0.01162392194150, 0.01321862359335, + 0.01497221122468, 0.01689477844427, 0.01899657030441, 0.02128794388846, + 0.02377932597692, 0.02648116795039, 0.02940389811590, 0.03255787167130, + 0.03595331854986, 0.03960028941437, 0.04350860009563, 0.04768777479454, + 0.05214698838949, 0.05689500821121, 0.06194013566525, 0.06729014809766, + 0.07295224131210, 0.07893297315602, 0.08523820859989, 0.09187306673620, + 0.09884187012422, 0.10614809690222, 0.11379433608064, 0.12178224641797, + 0.13011251926531, 0.13878484574660, 0.14779788861830, 0.15714925912610, + 0.16683549914631, 0.17685206886673, 0.18719334022589, 0.19785259629099, + 0.20882203671372, 0.22009278936030, 0.23165492816694, 0.24349749722585, + 0.25560854105961, 0.26797514099368, 0.28058345748882, 0.29341877824732, + 0.30646557185942, 0.31970754671026, 0.33312771482295, 0.34670846027024, + + 0.36043161174692, 0.37427851885723, 0.38823013163645, 0.40226708279486, + 0.41636977214436, 0.43051845264462, 0.44469331748632, 0.45887458761470, + 0.47304259908636, 0.48717788964798, 0.50126128392546, 0.51527397661778, + 0.52919761310050, 0.54301436685998, 0.55670701320069, 0.57025899869448, + 0.58365450587230, 0.59687851269542, 0.60991684638414, 0.62275623122793, + 0.63538433005035, 0.64778977905593, 0.65996221584264, 0.67189230042379, + 0.68357172916486, 0.69499324160511, 0.70615062019861, 0.71703868307548, + 0.72765326998919, 0.73799122168099, 0.74805035295521, 0.75782941981995, + 0.76732808110520, 0.77654685502339, 0.78548707118622, 0.79415081863423, + 0.80254089047207, 0.81066072573188, 0.81851434910893, 0.82610630922734, + 0.83344161609862, 0.84052567843230, 0.84736424144524, 0.85396332579459, + 0.86032916822973, 0.86646816451999, 0.87238681516918, 0.87809167437532, + 0.88358930263537, 0.88888622333073, 0.89398888356256, 0.89890361943564, + 0.90363662591861, 0.90819393133744, 0.91258137648979, 0.91680459830070, + 0.92086901787718, 0.92477983276087, 0.92854201312583, 0.93216030163834, + 0.93563921662343, 0.93898305819384, 0.94219591693690, 0.94528168477979, + + 0.94823843319821, 0.95106834367330, 0.95377776558539, 0.95636718335775, + 0.95883679961479, 0.96118650212341, 0.96341583179195, 0.96552395212906, + 0.96750962060547, 0.96937116231768, 0.97110644638309, 0.97271286544154, + 0.97418731862798, 0.97552619834964, 0.97672538116257, 0.97778022299974, + 0.97868555895586, 0.97943570778357, 0.98002448120255, 0.98044519806866, + 0.98069070339493, 0.98075339216123, 0.98062523779637, 0.98029782516478, + 0.97976238784222, 0.97900984942031, 0.97803086854002, 0.97681588731895, + 0.97535518280755, 0.97363892108474, 0.97165721358452, 0.96940017523145, + 0.96685798395452, 0.96402094114589, 0.96087953263194, 0.95742448973047, + 0.95364684997699, 0.94953801711660, 0.94508981997396, 0.94029456983253, + 0.93514511597504, 0.92963489905951, 0.92375800202883, 0.91750919827624, + 0.91088399681406, 0.90387868421832, 0.89649036314692, 0.88871698725397, + 0.88055739234735, 0.87201132366062, 0.86307945913336, 0.85376342861693, + 0.84406582894455, 0.83399023482637, 0.82354120554757, 0.81272428745995, + 0.80154601230457, 0.79001389138101, 0.77813640562199, 0.76592299164227, + 0.75338402384395, 0.74053079267526, 0.72737547915460, 0.71393112578527, +}; + +static const float short_window3[64] = { + 0.00326887936450, 0.00550242900936, 0.00786846643791, 0.01045683453520, + 0.01330402120132, 0.01643221072863, 0.01985798040609, 0.02359509464766, + 0.02765559221954, 0.03205025893128, 0.03678884369614, 0.04188015679495, + 0.04733210987781, 0.05315172583924, 0.05934513287609, 0.06591755045290, + 0.07287327156378, 0.08021564389822, 0.08794705152307, 0.09606889811179, + 0.10458159240070, 0.11348453632940, 0.12277611617809, 0.13245369691511, + 0.14251361989876, 0.15295120402567, 0.16376075037904, 0.17493555039885, + 0.18646789757072, 0.19834910260891, 0.21056951208995, 0.22311853047787, + 0.23598464546683, 0.24915545655419, 0.26261770674500, 0.27635731727778, + 0.29035942525136, 0.30460842402318, 0.31908800624032, 0.33378120935681, + 0.34867046348260, 0.36373764140285, 0.37896411059909, 0.39433078709788, + 0.40981819096657, 0.42540650327031, 0.44107562429959, 0.45680523287270, + 0.47257484651351, 0.48836388230077, 0.50415171818214, 0.51991775454258, + 0.53564147581496, 0.55130251191887, 0.56688069931047, 0.58235614142007, + 0.59770926827271, 0.61292089506118, 0.62797227945823, 0.64284517745255, + 0.65752189749349, 0.67198535273209, 0.68621911114984, 0.70020744337099, +}; + +static const uint8_t dc_code_tab[5] = { 0, 0, 0, 1, 1 }; + +static const uint8_t ht_code_tab[5] = { 0, 0, 1, 2, 2 }; + +static const uint8_t band_ofs_tab[3][4] = { + { 12, 8, 4, 0 }, { 14, 10, 6, 0 }, { 12, 8, 4, 0 } +}; + +static const uint8_t band_low_tab[3] = { 9, 17, 24 }; + +static const uint16_t fast_gain_tab[8] = { + 128, 256, 384, 512, 640, 768, 896, 1024 +}; + +static const uint16_t slow_decay_tab[2][2] = { { 27, -1 }, { 32, 21 } }; + +static const uint16_t misc_decay_tab[3][2][2] = { + { { 354, -1 }, { 425, 425 } }, + { { 266, -1 }, { 320, -1 } }, + { { 213, -1 }, { 256, -1 } } +}; + +static const uint16_t fast_decay_tab[3][2][2][50] = { + {{{ + 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + }, { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + }}, {{ + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, + }, { + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + }}}, {{{ + 266, 266, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, + }, { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, + }}, {{ + 319, 319, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, + }, { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, + }}}, {{{ + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + }, { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }}, {{ + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + }, { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }}} +}; + +static const uint16_t fast_gain_adj_tab[3][2][62] = { + {{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 2, 4, 7, 11, 16, 29, 44, 59, + 76, 94, 116, 142, 179, 221, 252, 285, 312, 334, + }, { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 5, 8, 10, 15, 28, 42, 57, 75, 93, + 115, 140, 177, 219, 247, 280, 308, 330, 427, 533, + }}, {{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 5, 8, 12, 21, 35, 51, 69, 89, + 111, 138, 176, 220, 251, 284, 312, 334, + }, { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 5, 8, 11, 18, 33, 49, 65, 84, 106, 132, + 168, 214, 245, 279, 308, 329, 427, 533, + }}, {{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 4, 7, 10, 17, + 31, 47, 65, 84, 107, 134, 171, 215, 250, 283, + 312, 334, + }, { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 6, 9, 13, 27, 43, + 60, 79, 100, 126, 160, 207, 242, 276, 307, 329, + 427, 533, + }} +}; + +static const uint16_t slow_gain_tab[3][2][50] = { + {{ + 3072, 3072, 3072, 3072, 3072, 3072, 1063, 1063, 1063, 1063, + 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, + 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, + 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, + }, { + 3072, 3072, 3072, 3072, 3072, 3072, 850, 850, 850, 850, + 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, + 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, + 850, 850, 850, 850, 850, 850, 850, 850, + }}, {{ + 3072, 1212, 1212, 1212, 999, 999, 999, 999, 999, 999, + 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, + 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, + 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, + 999, 999, 999, 999, + }, { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, + }}, {{ + 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, + 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, + 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, + 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, + 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, + }, { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }} +}; + +static const uint16_t hearing_thresh_tab[3][3][50] = { + {{ + 1403, 1141, 1000, 959, 948, 957, 946, 925, 899, 871, + 843, 815, 789, 766, 745, 727, 705, 687, 681, 686, + 701, 725, 768, 854, 940, 1018, 1075, 1103, 1111, 1106, + 1098, 1105, 1142, 1237, 1419, 1721, 2169, 2805, + }, { + 1401, 1130, 995, 957, 947, 955, 941, 918, 890, 861, + 831, 803, 777, 754, 734, 717, 698, 684, 682, 692, + 712, 743, 798, 894, 976, 1045, 1091, 1109, 1110, 1102, + 1098, 1116, 1174, 1300, 1526, 1884, 2401, 3072, + }, { + 1393, 1086, 974, 949, 957, 941, 913, 878, 843, 808, + 777, 750, 727, 708, 695, 686, 681, 689, 714, 752, + 811, 888, 971, 1044, 1087, 1108, 1110, 1102, 1098, 1115, + 1172, 1290, 1489, 1812, 2293, 2964, 3072, 3072, + }}, {{ + 1412, 1343, 1141, 1047, 1000, 974, 959, 951, 948, 947, + 957, 953, 946, 936, 925, 906, 878, 850, 822, 795, + 771, 745, 719, 700, 687, 681, 685, 701, 733, 784, + 885, 977, 1047, 1092, 1110, 1108, 1099, 1102, 1138, 1233, + 1413, 1711, 2157, 2797, + }, { + 1412, 1336, 1130, 1040, 995, 970, 957, 950, 947, 947, + 955, 950, 941, 930, 918, 897, 868, 838, 810, 783, + 759, 734, 710, 693, 684, 681, 690, 712, 752, 823, + 924, 1009, 1069, 1102, 1111, 1104, 1098, 1111, 1168, 1295, + 1518, 1873, 2388, 3072, + }, { + 1411, 1293, 1086, 1009, 974, 957, 949, 947, 957, 951, + 941, 928, 913, 896, 878, 852, 817, 785, 756, 732, + 713, 695, 683, 682, 689, 710, 746, 811, 906, 992, + 1061, 1099, 1111, 1106, 1098, 1107, 1155, 1266, 1471, 1799, + 2277, 2945, 3072, 3072, + }}, {{ + 1431, 1412, 1403, 1379, 1343, 1293, 1229, 1180, 1125, 1075, + 1040, 1014, 996, 979, 965, 957, 951, 948, 947, 957, + 951, 940, 924, 903, 877, 846, 815, 785, 753, 725, + 702, 686, 681, 689, 714, 760, 847, 947, 1028, 1083, + 1108, 1109, 1101, 1100, 1132, 1222, 1402, 1705, 2160, 2803, + }, { + 1431, 1412, 1401, 1375, 1336, 1278, 1215, 1168, 1115, 1066, + 1032, 1008, 991, 975, 962, 954, 950, 947, 947, 955, + 948, 935, 916, 894, 866, 835, 803, 772, 742, 715, + 695, 683, 683, 697, 729, 784, 887, 982, 1054, 1096, + 1111, 1106, 1098, 1107, 1159, 1281, 1505, 1865, 2391, 3072, + }, { + 1427, 1411, 1393, 1353, 1293, 1215, 1160, 1118, 1072, 1031, + 1003, 984, 971, 960, 952, 948, 947, 957, 952, 941, + 924, 902, 876, 847, 815, 781, 750, 723, 700, 685, + 681, 691, 719, 766, 858, 958, 1039, 1089, 1109, 1108, + 1099, 1102, 1141, 1245, 1442, 1766, 2250, 2930, 3072, 3072, + }} +}; + +static const int16_t lwc_gain_tab[11][7] = { + { -21, -197, -271, -466, 32767, 32767, 32767 }, + { -197, -29, -244, -271, -540, 32767, 32767 }, + { -271, -244, -29, -249, -271, -593, 32767 }, + { -466, -271, -249, -29, -251, -271, -632 }, + { -540, -271, -251, -29, -251, -271, -664 }, + { -593, -271, -251, -29, -252, -271, -690 }, + { -632, -271, -252, -29, -252, -271, -711 }, + { -664, -271, -252, -29, -252, -271, -730 }, + { -690, -271, -252, -29, -252, -271, -745 }, + { -711, -271, -252, -29, -253, -271, -759 }, + { -730, -271, -253, -29, -253, -271, -771 }, +}; + +static const int16_t lwc_adj_tab[7] = { + -192, -320, -448, -512, -448, -320, -192, +}; + +static const uint8_t log_add_tab[212] = { + 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 52, 51, 50, + 49, 48, 47, 47, 46, 45, 44, 44, 43, 42, 41, 41, 40, 39, 38, 38, + 37, 36, 36, 35, 35, 34, 33, 33, 32, 32, 31, 30, 30, 29, 29, 28, + 28, 27, 27, 26, 26, 25, 25, 24, 24, 23, 23, 22, 22, 21, 21, 21, + 20, 20, 19, 19, 19, 18, 18, 18, 17, 17, 17, 16, 16, 16, 15, 15, + 15, 14, 14, 14, 13, 13, 13, 13, 12, 12, 12, 12, 11, 11, 11, 11, + 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, + 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, + 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 0, 0, +}; + +static const uint8_t bap_tab[64] = { + 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, + 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, + 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, + 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 15, +}; + +static float mantissa_tab1[17][4]; +static float mantissa_tab2[17][4]; +static float mantissa_tab3[17][4]; +static float exponent_tab[50]; +static float gain_tab[1024]; + +DECLARE_ALIGNED(32, static float, window)[3712]; + +#endif