1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * NellyMoser audio decoder
3cabdff1aSopenharmony_ci * Copyright (c) 2007 a840bda5870ba11f19698ff6eb9581dfb0f95fa5,
4cabdff1aSopenharmony_ci *                    539459aeb7d425140b62a3ec7dbf6dc8e408a306, and
5cabdff1aSopenharmony_ci *                    520e17cd55896441042b14df2566a6eb610ed444
6cabdff1aSopenharmony_ci * Copyright (c) 2007 Loic Minier <lool at dooz.org>
7cabdff1aSopenharmony_ci *                    Benjamin Larsson
8cabdff1aSopenharmony_ci *
9cabdff1aSopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
10cabdff1aSopenharmony_ci * copy of this software and associated documentation files (the "Software"),
11cabdff1aSopenharmony_ci * to deal in the Software without restriction, including without limitation
12cabdff1aSopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13cabdff1aSopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
14cabdff1aSopenharmony_ci * Software is furnished to do so, subject to the following conditions:
15cabdff1aSopenharmony_ci *
16cabdff1aSopenharmony_ci * The above copyright notice and this permission notice shall be included in
17cabdff1aSopenharmony_ci * all copies or substantial portions of the Software.
18cabdff1aSopenharmony_ci *
19cabdff1aSopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20cabdff1aSopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21cabdff1aSopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22cabdff1aSopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23cabdff1aSopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24cabdff1aSopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25cabdff1aSopenharmony_ci * DEALINGS IN THE SOFTWARE.
26cabdff1aSopenharmony_ci */
27cabdff1aSopenharmony_ci
28cabdff1aSopenharmony_ci/**
29cabdff1aSopenharmony_ci * @file
30cabdff1aSopenharmony_ci * The 3 alphanumeric copyright notices are md5summed they are from the original
31cabdff1aSopenharmony_ci * implementors. The original code is available from http://code.google.com/p/nelly2pcm/
32cabdff1aSopenharmony_ci */
33cabdff1aSopenharmony_ci
34cabdff1aSopenharmony_ci#include "libavutil/channel_layout.h"
35cabdff1aSopenharmony_ci#include "libavutil/float_dsp.h"
36cabdff1aSopenharmony_ci#include "libavutil/lfg.h"
37cabdff1aSopenharmony_ci#include "libavutil/mem_internal.h"
38cabdff1aSopenharmony_ci#include "libavutil/random_seed.h"
39cabdff1aSopenharmony_ci
40cabdff1aSopenharmony_ci#define BITSTREAM_READER_LE
41cabdff1aSopenharmony_ci#include "avcodec.h"
42cabdff1aSopenharmony_ci#include "codec_internal.h"
43cabdff1aSopenharmony_ci#include "fft.h"
44cabdff1aSopenharmony_ci#include "get_bits.h"
45cabdff1aSopenharmony_ci#include "internal.h"
46cabdff1aSopenharmony_ci#include "nellymoser.h"
47cabdff1aSopenharmony_ci#include "sinewin.h"
48cabdff1aSopenharmony_ci
49cabdff1aSopenharmony_ci
50cabdff1aSopenharmony_citypedef struct NellyMoserDecodeContext {
51cabdff1aSopenharmony_ci    AVCodecContext* avctx;
52cabdff1aSopenharmony_ci    AVLFG           random_state;
53cabdff1aSopenharmony_ci    GetBitContext   gb;
54cabdff1aSopenharmony_ci    float           scale_bias;
55cabdff1aSopenharmony_ci    AVFloatDSPContext *fdsp;
56cabdff1aSopenharmony_ci    FFTContext      imdct_ctx;
57cabdff1aSopenharmony_ci    DECLARE_ALIGNED(32, float, imdct_buf)[2][NELLY_BUF_LEN];
58cabdff1aSopenharmony_ci    float          *imdct_out;
59cabdff1aSopenharmony_ci    float          *imdct_prev;
60cabdff1aSopenharmony_ci} NellyMoserDecodeContext;
61cabdff1aSopenharmony_ci
62cabdff1aSopenharmony_cistatic void nelly_decode_block(NellyMoserDecodeContext *s,
63cabdff1aSopenharmony_ci                               const unsigned char block[NELLY_BLOCK_LEN],
64cabdff1aSopenharmony_ci                               float audio[NELLY_SAMPLES])
65cabdff1aSopenharmony_ci{
66cabdff1aSopenharmony_ci    int i,j;
67cabdff1aSopenharmony_ci    float buf[NELLY_FILL_LEN], pows[NELLY_FILL_LEN];
68cabdff1aSopenharmony_ci    float *aptr, *bptr, *pptr, val, pval;
69cabdff1aSopenharmony_ci    int bits[NELLY_BUF_LEN];
70cabdff1aSopenharmony_ci    unsigned char v;
71cabdff1aSopenharmony_ci
72cabdff1aSopenharmony_ci    init_get_bits(&s->gb, block, NELLY_BLOCK_LEN * 8);
73cabdff1aSopenharmony_ci
74cabdff1aSopenharmony_ci    bptr = buf;
75cabdff1aSopenharmony_ci    pptr = pows;
76cabdff1aSopenharmony_ci    val = ff_nelly_init_table[get_bits(&s->gb, 6)];
77cabdff1aSopenharmony_ci    for (i=0 ; i<NELLY_BANDS ; i++) {
78cabdff1aSopenharmony_ci        if (i > 0)
79cabdff1aSopenharmony_ci            val += ff_nelly_delta_table[get_bits(&s->gb, 5)];
80cabdff1aSopenharmony_ci        pval = -exp2(val/2048) * s->scale_bias;
81cabdff1aSopenharmony_ci        for (j = 0; j < ff_nelly_band_sizes_table[i]; j++) {
82cabdff1aSopenharmony_ci            *bptr++ = val;
83cabdff1aSopenharmony_ci            *pptr++ = pval;
84cabdff1aSopenharmony_ci        }
85cabdff1aSopenharmony_ci
86cabdff1aSopenharmony_ci    }
87cabdff1aSopenharmony_ci
88cabdff1aSopenharmony_ci    ff_nelly_get_sample_bits(buf, bits);
89cabdff1aSopenharmony_ci
90cabdff1aSopenharmony_ci    for (i = 0; i < 2; i++) {
91cabdff1aSopenharmony_ci        aptr = audio + i * NELLY_BUF_LEN;
92cabdff1aSopenharmony_ci
93cabdff1aSopenharmony_ci        init_get_bits(&s->gb, block, NELLY_BLOCK_LEN * 8);
94cabdff1aSopenharmony_ci        skip_bits_long(&s->gb, NELLY_HEADER_BITS + i*NELLY_DETAIL_BITS);
95cabdff1aSopenharmony_ci
96cabdff1aSopenharmony_ci        for (j = 0; j < NELLY_FILL_LEN; j++) {
97cabdff1aSopenharmony_ci            if (bits[j] <= 0) {
98cabdff1aSopenharmony_ci                aptr[j] = M_SQRT1_2*pows[j];
99cabdff1aSopenharmony_ci                if (av_lfg_get(&s->random_state) & 1)
100cabdff1aSopenharmony_ci                    aptr[j] *= -1.0;
101cabdff1aSopenharmony_ci            } else {
102cabdff1aSopenharmony_ci                v = get_bits(&s->gb, bits[j]);
103cabdff1aSopenharmony_ci                aptr[j] = ff_nelly_dequantization_table[(1<<bits[j])-1+v]*pows[j];
104cabdff1aSopenharmony_ci            }
105cabdff1aSopenharmony_ci        }
106cabdff1aSopenharmony_ci        memset(&aptr[NELLY_FILL_LEN], 0,
107cabdff1aSopenharmony_ci               (NELLY_BUF_LEN - NELLY_FILL_LEN) * sizeof(float));
108cabdff1aSopenharmony_ci
109cabdff1aSopenharmony_ci        s->imdct_ctx.imdct_half(&s->imdct_ctx, s->imdct_out, aptr);
110cabdff1aSopenharmony_ci        s->fdsp->vector_fmul_window(aptr, s->imdct_prev + NELLY_BUF_LEN / 2,
111cabdff1aSopenharmony_ci                                   s->imdct_out, ff_sine_128,
112cabdff1aSopenharmony_ci                                   NELLY_BUF_LEN / 2);
113cabdff1aSopenharmony_ci        FFSWAP(float *, s->imdct_out, s->imdct_prev);
114cabdff1aSopenharmony_ci    }
115cabdff1aSopenharmony_ci}
116cabdff1aSopenharmony_ci
117cabdff1aSopenharmony_cistatic av_cold int decode_init(AVCodecContext * avctx) {
118cabdff1aSopenharmony_ci    NellyMoserDecodeContext *s = avctx->priv_data;
119cabdff1aSopenharmony_ci
120cabdff1aSopenharmony_ci    s->avctx = avctx;
121cabdff1aSopenharmony_ci    s->imdct_out = s->imdct_buf[0];
122cabdff1aSopenharmony_ci    s->imdct_prev = s->imdct_buf[1];
123cabdff1aSopenharmony_ci    av_lfg_init(&s->random_state, 0);
124cabdff1aSopenharmony_ci    ff_mdct_init(&s->imdct_ctx, 8, 1, 1.0);
125cabdff1aSopenharmony_ci
126cabdff1aSopenharmony_ci    s->fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT);
127cabdff1aSopenharmony_ci    if (!s->fdsp)
128cabdff1aSopenharmony_ci        return AVERROR(ENOMEM);
129cabdff1aSopenharmony_ci
130cabdff1aSopenharmony_ci    s->scale_bias = 1.0/(32768*8);
131cabdff1aSopenharmony_ci    avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
132cabdff1aSopenharmony_ci
133cabdff1aSopenharmony_ci    av_channel_layout_uninit(&avctx->ch_layout);
134cabdff1aSopenharmony_ci    avctx->ch_layout      = (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO;
135cabdff1aSopenharmony_ci
136cabdff1aSopenharmony_ci    /* Generate overlap window */
137cabdff1aSopenharmony_ci    ff_init_ff_sine_windows(7);
138cabdff1aSopenharmony_ci
139cabdff1aSopenharmony_ci    return 0;
140cabdff1aSopenharmony_ci}
141cabdff1aSopenharmony_ci
142cabdff1aSopenharmony_cistatic int decode_tag(AVCodecContext *avctx, AVFrame *frame,
143cabdff1aSopenharmony_ci                      int *got_frame_ptr, AVPacket *avpkt)
144cabdff1aSopenharmony_ci{
145cabdff1aSopenharmony_ci    const uint8_t *buf = avpkt->data;
146cabdff1aSopenharmony_ci    int buf_size = avpkt->size;
147cabdff1aSopenharmony_ci    NellyMoserDecodeContext *s = avctx->priv_data;
148cabdff1aSopenharmony_ci    int blocks, i, ret;
149cabdff1aSopenharmony_ci    float   *samples_flt;
150cabdff1aSopenharmony_ci
151cabdff1aSopenharmony_ci    blocks     = buf_size / NELLY_BLOCK_LEN;
152cabdff1aSopenharmony_ci
153cabdff1aSopenharmony_ci    if (blocks <= 0) {
154cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_ERROR, "Packet is too small\n");
155cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
156cabdff1aSopenharmony_ci    }
157cabdff1aSopenharmony_ci
158cabdff1aSopenharmony_ci    if (buf_size % NELLY_BLOCK_LEN) {
159cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_WARNING, "Leftover bytes: %d.\n",
160cabdff1aSopenharmony_ci               buf_size % NELLY_BLOCK_LEN);
161cabdff1aSopenharmony_ci    }
162cabdff1aSopenharmony_ci
163cabdff1aSopenharmony_ci    /* get output buffer */
164cabdff1aSopenharmony_ci    frame->nb_samples = NELLY_SAMPLES * blocks;
165cabdff1aSopenharmony_ci    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
166cabdff1aSopenharmony_ci        return ret;
167cabdff1aSopenharmony_ci    samples_flt = (float *)frame->data[0];
168cabdff1aSopenharmony_ci
169cabdff1aSopenharmony_ci    for (i=0 ; i<blocks ; i++) {
170cabdff1aSopenharmony_ci        nelly_decode_block(s, buf, samples_flt);
171cabdff1aSopenharmony_ci        samples_flt += NELLY_SAMPLES;
172cabdff1aSopenharmony_ci        buf += NELLY_BLOCK_LEN;
173cabdff1aSopenharmony_ci    }
174cabdff1aSopenharmony_ci
175cabdff1aSopenharmony_ci    *got_frame_ptr = 1;
176cabdff1aSopenharmony_ci
177cabdff1aSopenharmony_ci    return buf_size;
178cabdff1aSopenharmony_ci}
179cabdff1aSopenharmony_ci
180cabdff1aSopenharmony_cistatic av_cold int decode_end(AVCodecContext * avctx) {
181cabdff1aSopenharmony_ci    NellyMoserDecodeContext *s = avctx->priv_data;
182cabdff1aSopenharmony_ci
183cabdff1aSopenharmony_ci    ff_mdct_end(&s->imdct_ctx);
184cabdff1aSopenharmony_ci    av_freep(&s->fdsp);
185cabdff1aSopenharmony_ci
186cabdff1aSopenharmony_ci    return 0;
187cabdff1aSopenharmony_ci}
188cabdff1aSopenharmony_ci
189cabdff1aSopenharmony_ciconst FFCodec ff_nellymoser_decoder = {
190cabdff1aSopenharmony_ci    .p.name         = "nellymoser",
191cabdff1aSopenharmony_ci    .p.long_name    = NULL_IF_CONFIG_SMALL("Nellymoser Asao"),
192cabdff1aSopenharmony_ci    .p.type         = AVMEDIA_TYPE_AUDIO,
193cabdff1aSopenharmony_ci    .p.id           = AV_CODEC_ID_NELLYMOSER,
194cabdff1aSopenharmony_ci    .priv_data_size = sizeof(NellyMoserDecodeContext),
195cabdff1aSopenharmony_ci    .init           = decode_init,
196cabdff1aSopenharmony_ci    .close          = decode_end,
197cabdff1aSopenharmony_ci    FF_CODEC_DECODE_CB(decode_tag),
198cabdff1aSopenharmony_ci    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_PARAM_CHANGE | AV_CODEC_CAP_CHANNEL_CONF,
199cabdff1aSopenharmony_ci    .p.sample_fmts  = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLT,
200cabdff1aSopenharmony_ci                                                      AV_SAMPLE_FMT_NONE },
201cabdff1aSopenharmony_ci    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
202cabdff1aSopenharmony_ci};
203