1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * QCELP decoder
3cabdff1aSopenharmony_ci * Copyright (c) 2007 Reynaldo H. Verdejo Pinochet
4cabdff1aSopenharmony_ci *
5cabdff1aSopenharmony_ci * This file is part of FFmpeg.
6cabdff1aSopenharmony_ci *
7cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
8cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
9cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
10cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
11cabdff1aSopenharmony_ci *
12cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
13cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
14cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15cabdff1aSopenharmony_ci * Lesser General Public License for more details.
16cabdff1aSopenharmony_ci *
17cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
18cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
19cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20cabdff1aSopenharmony_ci */
21cabdff1aSopenharmony_ci
22cabdff1aSopenharmony_ci/**
23cabdff1aSopenharmony_ci * @file
24cabdff1aSopenharmony_ci * QCELP decoder
25cabdff1aSopenharmony_ci * @author Reynaldo H. Verdejo Pinochet
26cabdff1aSopenharmony_ci * @remark FFmpeg merging spearheaded by Kenan Gillet
27cabdff1aSopenharmony_ci * @remark Development mentored by Benjamin Larson
28cabdff1aSopenharmony_ci */
29cabdff1aSopenharmony_ci
30cabdff1aSopenharmony_ci#include <stddef.h>
31cabdff1aSopenharmony_ci
32cabdff1aSopenharmony_ci#include "libavutil/avassert.h"
33cabdff1aSopenharmony_ci#include "libavutil/channel_layout.h"
34cabdff1aSopenharmony_ci#include "libavutil/float_dsp.h"
35cabdff1aSopenharmony_ci#include "avcodec.h"
36cabdff1aSopenharmony_ci#include "codec_internal.h"
37cabdff1aSopenharmony_ci#include "internal.h"
38cabdff1aSopenharmony_ci#include "get_bits.h"
39cabdff1aSopenharmony_ci#include "qcelpdata.h"
40cabdff1aSopenharmony_ci#include "celp_filters.h"
41cabdff1aSopenharmony_ci#include "acelp_filters.h"
42cabdff1aSopenharmony_ci#include "acelp_vectors.h"
43cabdff1aSopenharmony_ci#include "lsp.h"
44cabdff1aSopenharmony_ci
45cabdff1aSopenharmony_citypedef enum {
46cabdff1aSopenharmony_ci    I_F_Q = -1,    /**< insufficient frame quality */
47cabdff1aSopenharmony_ci    SILENCE,
48cabdff1aSopenharmony_ci    RATE_OCTAVE,
49cabdff1aSopenharmony_ci    RATE_QUARTER,
50cabdff1aSopenharmony_ci    RATE_HALF,
51cabdff1aSopenharmony_ci    RATE_FULL
52cabdff1aSopenharmony_ci} qcelp_packet_rate;
53cabdff1aSopenharmony_ci
54cabdff1aSopenharmony_citypedef struct QCELPContext {
55cabdff1aSopenharmony_ci    GetBitContext     gb;
56cabdff1aSopenharmony_ci    qcelp_packet_rate bitrate;
57cabdff1aSopenharmony_ci    QCELPFrame        frame;    /**< unpacked data frame */
58cabdff1aSopenharmony_ci
59cabdff1aSopenharmony_ci    uint8_t  erasure_count;
60cabdff1aSopenharmony_ci    uint8_t  octave_count;      /**< count the consecutive RATE_OCTAVE frames */
61cabdff1aSopenharmony_ci    float    prev_lspf[10];
62cabdff1aSopenharmony_ci    float    predictor_lspf[10];/**< LSP predictor for RATE_OCTAVE and I_F_Q */
63cabdff1aSopenharmony_ci    float    pitch_synthesis_filter_mem[303];
64cabdff1aSopenharmony_ci    float    pitch_pre_filter_mem[303];
65cabdff1aSopenharmony_ci    float    rnd_fir_filter_mem[180];
66cabdff1aSopenharmony_ci    float    formant_mem[170];
67cabdff1aSopenharmony_ci    float    last_codebook_gain;
68cabdff1aSopenharmony_ci    int      prev_g1[2];
69cabdff1aSopenharmony_ci    int      prev_bitrate;
70cabdff1aSopenharmony_ci    float    pitch_gain[4];
71cabdff1aSopenharmony_ci    uint8_t  pitch_lag[4];
72cabdff1aSopenharmony_ci    uint16_t first16bits;
73cabdff1aSopenharmony_ci    uint8_t  warned_buf_mismatch_bitrate;
74cabdff1aSopenharmony_ci
75cabdff1aSopenharmony_ci    /* postfilter */
76cabdff1aSopenharmony_ci    float    postfilter_synth_mem[10];
77cabdff1aSopenharmony_ci    float    postfilter_agc_mem;
78cabdff1aSopenharmony_ci    float    postfilter_tilt_mem;
79cabdff1aSopenharmony_ci} QCELPContext;
80cabdff1aSopenharmony_ci
81cabdff1aSopenharmony_ci/**
82cabdff1aSopenharmony_ci * Initialize the speech codec according to the specification.
83cabdff1aSopenharmony_ci *
84cabdff1aSopenharmony_ci * TIA/EIA/IS-733 2.4.9
85cabdff1aSopenharmony_ci */
86cabdff1aSopenharmony_cistatic av_cold int qcelp_decode_init(AVCodecContext *avctx)
87cabdff1aSopenharmony_ci{
88cabdff1aSopenharmony_ci    QCELPContext *q = avctx->priv_data;
89cabdff1aSopenharmony_ci    int i;
90cabdff1aSopenharmony_ci
91cabdff1aSopenharmony_ci    av_channel_layout_uninit(&avctx->ch_layout);
92cabdff1aSopenharmony_ci    avctx->ch_layout      = (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO;
93cabdff1aSopenharmony_ci    avctx->sample_fmt     = AV_SAMPLE_FMT_FLT;
94cabdff1aSopenharmony_ci
95cabdff1aSopenharmony_ci    for (i = 0; i < 10; i++)
96cabdff1aSopenharmony_ci        q->prev_lspf[i] = (i + 1) / 11.0;
97cabdff1aSopenharmony_ci
98cabdff1aSopenharmony_ci    return 0;
99cabdff1aSopenharmony_ci}
100cabdff1aSopenharmony_ci
101cabdff1aSopenharmony_ci/**
102cabdff1aSopenharmony_ci * Decode the 10 quantized LSP frequencies from the LSPV/LSP
103cabdff1aSopenharmony_ci * transmission codes of any bitrate and check for badly received packets.
104cabdff1aSopenharmony_ci *
105cabdff1aSopenharmony_ci * @param q the context
106cabdff1aSopenharmony_ci * @param lspf line spectral pair frequencies
107cabdff1aSopenharmony_ci *
108cabdff1aSopenharmony_ci * @return 0 on success, -1 if the packet is badly received
109cabdff1aSopenharmony_ci *
110cabdff1aSopenharmony_ci * TIA/EIA/IS-733 2.4.3.2.6.2-2, 2.4.8.7.3
111cabdff1aSopenharmony_ci */
112cabdff1aSopenharmony_cistatic int decode_lspf(QCELPContext *q, float *lspf)
113cabdff1aSopenharmony_ci{
114cabdff1aSopenharmony_ci    int i;
115cabdff1aSopenharmony_ci    float tmp_lspf, smooth, erasure_coeff;
116cabdff1aSopenharmony_ci    const float *predictors;
117cabdff1aSopenharmony_ci
118cabdff1aSopenharmony_ci    if (q->bitrate == RATE_OCTAVE || q->bitrate == I_F_Q) {
119cabdff1aSopenharmony_ci        predictors = q->prev_bitrate != RATE_OCTAVE &&
120cabdff1aSopenharmony_ci                     q->prev_bitrate != I_F_Q ? q->prev_lspf
121cabdff1aSopenharmony_ci                                              : q->predictor_lspf;
122cabdff1aSopenharmony_ci
123cabdff1aSopenharmony_ci        if (q->bitrate == RATE_OCTAVE) {
124cabdff1aSopenharmony_ci            q->octave_count++;
125cabdff1aSopenharmony_ci
126cabdff1aSopenharmony_ci            for (i = 0; i < 10; i++) {
127cabdff1aSopenharmony_ci                q->predictor_lspf[i] =
128cabdff1aSopenharmony_ci                             lspf[i] = (q->frame.lspv[i] ?  QCELP_LSP_SPREAD_FACTOR
129cabdff1aSopenharmony_ci                                                         : -QCELP_LSP_SPREAD_FACTOR) +
130cabdff1aSopenharmony_ci                                        predictors[i] * QCELP_LSP_OCTAVE_PREDICTOR   +
131cabdff1aSopenharmony_ci                                        (i + 1) * ((1 - QCELP_LSP_OCTAVE_PREDICTOR) / 11);
132cabdff1aSopenharmony_ci            }
133cabdff1aSopenharmony_ci            smooth = q->octave_count < 10 ? .875 : 0.1;
134cabdff1aSopenharmony_ci        } else {
135cabdff1aSopenharmony_ci            erasure_coeff = QCELP_LSP_OCTAVE_PREDICTOR;
136cabdff1aSopenharmony_ci
137cabdff1aSopenharmony_ci            av_assert2(q->bitrate == I_F_Q);
138cabdff1aSopenharmony_ci
139cabdff1aSopenharmony_ci            if (q->erasure_count > 1)
140cabdff1aSopenharmony_ci                erasure_coeff *= q->erasure_count < 4 ? 0.9 : 0.7;
141cabdff1aSopenharmony_ci
142cabdff1aSopenharmony_ci            for (i = 0; i < 10; i++) {
143cabdff1aSopenharmony_ci                q->predictor_lspf[i] =
144cabdff1aSopenharmony_ci                             lspf[i] = (i + 1) * (1 - erasure_coeff) / 11 +
145cabdff1aSopenharmony_ci                                       erasure_coeff * predictors[i];
146cabdff1aSopenharmony_ci            }
147cabdff1aSopenharmony_ci            smooth = 0.125;
148cabdff1aSopenharmony_ci        }
149cabdff1aSopenharmony_ci
150cabdff1aSopenharmony_ci        // Check the stability of the LSP frequencies.
151cabdff1aSopenharmony_ci        lspf[0] = FFMAX(lspf[0], QCELP_LSP_SPREAD_FACTOR);
152cabdff1aSopenharmony_ci        for (i = 1; i < 10; i++)
153cabdff1aSopenharmony_ci            lspf[i] = FFMAX(lspf[i], lspf[i - 1] + QCELP_LSP_SPREAD_FACTOR);
154cabdff1aSopenharmony_ci
155cabdff1aSopenharmony_ci        lspf[9] = FFMIN(lspf[9], 1.0 - QCELP_LSP_SPREAD_FACTOR);
156cabdff1aSopenharmony_ci        for (i = 9; i > 0; i--)
157cabdff1aSopenharmony_ci            lspf[i - 1] = FFMIN(lspf[i - 1], lspf[i] - QCELP_LSP_SPREAD_FACTOR);
158cabdff1aSopenharmony_ci
159cabdff1aSopenharmony_ci        // Low-pass filter the LSP frequencies.
160cabdff1aSopenharmony_ci        ff_weighted_vector_sumf(lspf, lspf, q->prev_lspf, smooth, 1.0 - smooth, 10);
161cabdff1aSopenharmony_ci    } else {
162cabdff1aSopenharmony_ci        q->octave_count = 0;
163cabdff1aSopenharmony_ci
164cabdff1aSopenharmony_ci        tmp_lspf = 0.0;
165cabdff1aSopenharmony_ci        for (i = 0; i < 5; i++) {
166cabdff1aSopenharmony_ci            lspf[2 * i + 0] = tmp_lspf += qcelp_lspvq[i][q->frame.lspv[i]][0] * 0.0001;
167cabdff1aSopenharmony_ci            lspf[2 * i + 1] = tmp_lspf += qcelp_lspvq[i][q->frame.lspv[i]][1] * 0.0001;
168cabdff1aSopenharmony_ci        }
169cabdff1aSopenharmony_ci
170cabdff1aSopenharmony_ci        // Check for badly received packets.
171cabdff1aSopenharmony_ci        if (q->bitrate == RATE_QUARTER) {
172cabdff1aSopenharmony_ci            if (lspf[9] <= .70 || lspf[9] >= .97)
173cabdff1aSopenharmony_ci                return -1;
174cabdff1aSopenharmony_ci            for (i = 3; i < 10; i++)
175cabdff1aSopenharmony_ci                if (fabs(lspf[i] - lspf[i - 2]) < .08)
176cabdff1aSopenharmony_ci                    return -1;
177cabdff1aSopenharmony_ci        } else {
178cabdff1aSopenharmony_ci            if (lspf[9] <= .66 || lspf[9] >= .985)
179cabdff1aSopenharmony_ci                return -1;
180cabdff1aSopenharmony_ci            for (i = 4; i < 10; i++)
181cabdff1aSopenharmony_ci                if (fabs(lspf[i] - lspf[i - 4]) < .0931)
182cabdff1aSopenharmony_ci                    return -1;
183cabdff1aSopenharmony_ci        }
184cabdff1aSopenharmony_ci    }
185cabdff1aSopenharmony_ci    return 0;
186cabdff1aSopenharmony_ci}
187cabdff1aSopenharmony_ci
188cabdff1aSopenharmony_ci/**
189cabdff1aSopenharmony_ci * Convert codebook transmission codes to GAIN and INDEX.
190cabdff1aSopenharmony_ci *
191cabdff1aSopenharmony_ci * @param q the context
192cabdff1aSopenharmony_ci * @param gain array holding the decoded gain
193cabdff1aSopenharmony_ci *
194cabdff1aSopenharmony_ci * TIA/EIA/IS-733 2.4.6.2
195cabdff1aSopenharmony_ci */
196cabdff1aSopenharmony_cistatic void decode_gain_and_index(QCELPContext *q, float *gain)
197cabdff1aSopenharmony_ci{
198cabdff1aSopenharmony_ci    int i, subframes_count, g1[16];
199cabdff1aSopenharmony_ci    float slope;
200cabdff1aSopenharmony_ci
201cabdff1aSopenharmony_ci    if (q->bitrate >= RATE_QUARTER) {
202cabdff1aSopenharmony_ci        switch (q->bitrate) {
203cabdff1aSopenharmony_ci        case RATE_FULL: subframes_count = 16; break;
204cabdff1aSopenharmony_ci        case RATE_HALF: subframes_count =  4; break;
205cabdff1aSopenharmony_ci        default:        subframes_count =  5;
206cabdff1aSopenharmony_ci        }
207cabdff1aSopenharmony_ci        for (i = 0; i < subframes_count; i++) {
208cabdff1aSopenharmony_ci            g1[i] = 4 * q->frame.cbgain[i];
209cabdff1aSopenharmony_ci            if (q->bitrate == RATE_FULL && !((i + 1) & 3)) {
210cabdff1aSopenharmony_ci                g1[i] += av_clip((g1[i - 1] + g1[i - 2] + g1[i - 3]) / 3 - 6, 0, 32);
211cabdff1aSopenharmony_ci            }
212cabdff1aSopenharmony_ci
213cabdff1aSopenharmony_ci            gain[i] = qcelp_g12ga[g1[i]];
214cabdff1aSopenharmony_ci
215cabdff1aSopenharmony_ci            if (q->frame.cbsign[i]) {
216cabdff1aSopenharmony_ci                gain[i] = -gain[i];
217cabdff1aSopenharmony_ci                q->frame.cindex[i] = (q->frame.cindex[i] - 89) & 127;
218cabdff1aSopenharmony_ci            }
219cabdff1aSopenharmony_ci        }
220cabdff1aSopenharmony_ci
221cabdff1aSopenharmony_ci        q->prev_g1[0]         = g1[i - 2];
222cabdff1aSopenharmony_ci        q->prev_g1[1]         = g1[i - 1];
223cabdff1aSopenharmony_ci        q->last_codebook_gain = qcelp_g12ga[g1[i - 1]];
224cabdff1aSopenharmony_ci
225cabdff1aSopenharmony_ci        if (q->bitrate == RATE_QUARTER) {
226cabdff1aSopenharmony_ci            // Provide smoothing of the unvoiced excitation energy.
227cabdff1aSopenharmony_ci            gain[7] =       gain[4];
228cabdff1aSopenharmony_ci            gain[6] = 0.4 * gain[3] + 0.6 * gain[4];
229cabdff1aSopenharmony_ci            gain[5] =       gain[3];
230cabdff1aSopenharmony_ci            gain[4] = 0.8 * gain[2] + 0.2 * gain[3];
231cabdff1aSopenharmony_ci            gain[3] = 0.2 * gain[1] + 0.8 * gain[2];
232cabdff1aSopenharmony_ci            gain[2] =       gain[1];
233cabdff1aSopenharmony_ci            gain[1] = 0.6 * gain[0] + 0.4 * gain[1];
234cabdff1aSopenharmony_ci        }
235cabdff1aSopenharmony_ci    } else if (q->bitrate != SILENCE) {
236cabdff1aSopenharmony_ci        if (q->bitrate == RATE_OCTAVE) {
237cabdff1aSopenharmony_ci            g1[0] = 2 * q->frame.cbgain[0] +
238cabdff1aSopenharmony_ci                    av_clip((q->prev_g1[0] + q->prev_g1[1]) / 2 - 5, 0, 54);
239cabdff1aSopenharmony_ci            subframes_count = 8;
240cabdff1aSopenharmony_ci        } else {
241cabdff1aSopenharmony_ci            av_assert2(q->bitrate == I_F_Q);
242cabdff1aSopenharmony_ci
243cabdff1aSopenharmony_ci            g1[0] = q->prev_g1[1];
244cabdff1aSopenharmony_ci            switch (q->erasure_count) {
245cabdff1aSopenharmony_ci            case 1 : break;
246cabdff1aSopenharmony_ci            case 2 : g1[0] -= 1; break;
247cabdff1aSopenharmony_ci            case 3 : g1[0] -= 2; break;
248cabdff1aSopenharmony_ci            default: g1[0] -= 6;
249cabdff1aSopenharmony_ci            }
250cabdff1aSopenharmony_ci            if (g1[0] < 0)
251cabdff1aSopenharmony_ci                g1[0] = 0;
252cabdff1aSopenharmony_ci            subframes_count = 4;
253cabdff1aSopenharmony_ci        }
254cabdff1aSopenharmony_ci        // This interpolation is done to produce smoother background noise.
255cabdff1aSopenharmony_ci        slope = 0.5 * (qcelp_g12ga[g1[0]] - q->last_codebook_gain) / subframes_count;
256cabdff1aSopenharmony_ci        for (i = 1; i <= subframes_count; i++)
257cabdff1aSopenharmony_ci                gain[i - 1] = q->last_codebook_gain + slope * i;
258cabdff1aSopenharmony_ci
259cabdff1aSopenharmony_ci        q->last_codebook_gain = gain[i - 2];
260cabdff1aSopenharmony_ci        q->prev_g1[0]         = q->prev_g1[1];
261cabdff1aSopenharmony_ci        q->prev_g1[1]         = g1[0];
262cabdff1aSopenharmony_ci    }
263cabdff1aSopenharmony_ci}
264cabdff1aSopenharmony_ci
265cabdff1aSopenharmony_ci/**
266cabdff1aSopenharmony_ci * If the received packet is Rate 1/4 a further sanity check is made of the
267cabdff1aSopenharmony_ci * codebook gain.
268cabdff1aSopenharmony_ci *
269cabdff1aSopenharmony_ci * @param cbgain the unpacked cbgain array
270cabdff1aSopenharmony_ci * @return -1 if the sanity check fails, 0 otherwise
271cabdff1aSopenharmony_ci *
272cabdff1aSopenharmony_ci * TIA/EIA/IS-733 2.4.8.7.3
273cabdff1aSopenharmony_ci */
274cabdff1aSopenharmony_cistatic int codebook_sanity_check_for_rate_quarter(const uint8_t *cbgain)
275cabdff1aSopenharmony_ci{
276cabdff1aSopenharmony_ci    int i, diff, prev_diff = 0;
277cabdff1aSopenharmony_ci
278cabdff1aSopenharmony_ci    for (i = 1; i < 5; i++) {
279cabdff1aSopenharmony_ci        diff = cbgain[i] - cbgain[i-1];
280cabdff1aSopenharmony_ci        if (FFABS(diff) > 10)
281cabdff1aSopenharmony_ci            return -1;
282cabdff1aSopenharmony_ci        else if (FFABS(diff - prev_diff) > 12)
283cabdff1aSopenharmony_ci            return -1;
284cabdff1aSopenharmony_ci        prev_diff = diff;
285cabdff1aSopenharmony_ci    }
286cabdff1aSopenharmony_ci    return 0;
287cabdff1aSopenharmony_ci}
288cabdff1aSopenharmony_ci
289cabdff1aSopenharmony_ci/**
290cabdff1aSopenharmony_ci * Compute the scaled codebook vector Cdn From INDEX and GAIN
291cabdff1aSopenharmony_ci * for all rates.
292cabdff1aSopenharmony_ci *
293cabdff1aSopenharmony_ci * The specification lacks some information here.
294cabdff1aSopenharmony_ci *
295cabdff1aSopenharmony_ci * TIA/EIA/IS-733 has an omission on the codebook index determination
296cabdff1aSopenharmony_ci * formula for RATE_FULL and RATE_HALF frames at section 2.4.8.1.1. It says
297cabdff1aSopenharmony_ci * you have to subtract the decoded index parameter from the given scaled
298cabdff1aSopenharmony_ci * codebook vector index 'n' to get the desired circular codebook index, but
299cabdff1aSopenharmony_ci * it does not mention that you have to clamp 'n' to [0-9] in order to get
300cabdff1aSopenharmony_ci * RI-compliant results.
301cabdff1aSopenharmony_ci *
302cabdff1aSopenharmony_ci * The reason for this mistake seems to be the fact they forgot to mention you
303cabdff1aSopenharmony_ci * have to do these calculations per codebook subframe and adjust given
304cabdff1aSopenharmony_ci * equation values accordingly.
305cabdff1aSopenharmony_ci *
306cabdff1aSopenharmony_ci * @param q the context
307cabdff1aSopenharmony_ci * @param gain array holding the 4 pitch subframe gain values
308cabdff1aSopenharmony_ci * @param cdn_vector array for the generated scaled codebook vector
309cabdff1aSopenharmony_ci */
310cabdff1aSopenharmony_cistatic void compute_svector(QCELPContext *q, const float *gain,
311cabdff1aSopenharmony_ci                            float *cdn_vector)
312cabdff1aSopenharmony_ci{
313cabdff1aSopenharmony_ci    int i, j, k;
314cabdff1aSopenharmony_ci    uint16_t cbseed, cindex;
315cabdff1aSopenharmony_ci    float *rnd, tmp_gain, fir_filter_value;
316cabdff1aSopenharmony_ci
317cabdff1aSopenharmony_ci    switch (q->bitrate) {
318cabdff1aSopenharmony_ci    case RATE_FULL:
319cabdff1aSopenharmony_ci        for (i = 0; i < 16; i++) {
320cabdff1aSopenharmony_ci            tmp_gain = gain[i] * QCELP_RATE_FULL_CODEBOOK_RATIO;
321cabdff1aSopenharmony_ci            cindex   = -q->frame.cindex[i];
322cabdff1aSopenharmony_ci            for (j = 0; j < 10; j++)
323cabdff1aSopenharmony_ci                *cdn_vector++ = tmp_gain *
324cabdff1aSopenharmony_ci                                qcelp_rate_full_codebook[cindex++ & 127];
325cabdff1aSopenharmony_ci        }
326cabdff1aSopenharmony_ci        break;
327cabdff1aSopenharmony_ci    case RATE_HALF:
328cabdff1aSopenharmony_ci        for (i = 0; i < 4; i++) {
329cabdff1aSopenharmony_ci            tmp_gain = gain[i] * QCELP_RATE_HALF_CODEBOOK_RATIO;
330cabdff1aSopenharmony_ci            cindex   = -q->frame.cindex[i];
331cabdff1aSopenharmony_ci            for (j = 0; j < 40; j++)
332cabdff1aSopenharmony_ci                *cdn_vector++ = tmp_gain *
333cabdff1aSopenharmony_ci                                qcelp_rate_half_codebook[cindex++ & 127];
334cabdff1aSopenharmony_ci        }
335cabdff1aSopenharmony_ci        break;
336cabdff1aSopenharmony_ci    case RATE_QUARTER:
337cabdff1aSopenharmony_ci        cbseed = (0x0003 & q->frame.lspv[4]) << 14 |
338cabdff1aSopenharmony_ci                 (0x003F & q->frame.lspv[3]) <<  8 |
339cabdff1aSopenharmony_ci                 (0x0060 & q->frame.lspv[2]) <<  1 |
340cabdff1aSopenharmony_ci                 (0x0007 & q->frame.lspv[1]) <<  3 |
341cabdff1aSopenharmony_ci                 (0x0038 & q->frame.lspv[0]) >>  3;
342cabdff1aSopenharmony_ci        rnd    = q->rnd_fir_filter_mem + 20;
343cabdff1aSopenharmony_ci        for (i = 0; i < 8; i++) {
344cabdff1aSopenharmony_ci            tmp_gain = gain[i] * (QCELP_SQRT1887 / 32768.0);
345cabdff1aSopenharmony_ci            for (k = 0; k < 20; k++) {
346cabdff1aSopenharmony_ci                cbseed = 521 * cbseed + 259;
347cabdff1aSopenharmony_ci                *rnd   = (int16_t) cbseed;
348cabdff1aSopenharmony_ci
349cabdff1aSopenharmony_ci                    // FIR filter
350cabdff1aSopenharmony_ci                fir_filter_value = 0.0;
351cabdff1aSopenharmony_ci                for (j = 0; j < 10; j++)
352cabdff1aSopenharmony_ci                    fir_filter_value += qcelp_rnd_fir_coefs[j] *
353cabdff1aSopenharmony_ci                                        (rnd[-j] + rnd[-20+j]);
354cabdff1aSopenharmony_ci
355cabdff1aSopenharmony_ci                fir_filter_value += qcelp_rnd_fir_coefs[10] * rnd[-10];
356cabdff1aSopenharmony_ci                *cdn_vector++     = tmp_gain * fir_filter_value;
357cabdff1aSopenharmony_ci                rnd++;
358cabdff1aSopenharmony_ci            }
359cabdff1aSopenharmony_ci        }
360cabdff1aSopenharmony_ci        memcpy(q->rnd_fir_filter_mem, q->rnd_fir_filter_mem + 160,
361cabdff1aSopenharmony_ci               20 * sizeof(float));
362cabdff1aSopenharmony_ci        break;
363cabdff1aSopenharmony_ci    case RATE_OCTAVE:
364cabdff1aSopenharmony_ci        cbseed = q->first16bits;
365cabdff1aSopenharmony_ci        for (i = 0; i < 8; i++) {
366cabdff1aSopenharmony_ci            tmp_gain = gain[i] * (QCELP_SQRT1887 / 32768.0);
367cabdff1aSopenharmony_ci            for (j = 0; j < 20; j++) {
368cabdff1aSopenharmony_ci                cbseed        = 521 * cbseed + 259;
369cabdff1aSopenharmony_ci                *cdn_vector++ = tmp_gain * (int16_t) cbseed;
370cabdff1aSopenharmony_ci            }
371cabdff1aSopenharmony_ci        }
372cabdff1aSopenharmony_ci        break;
373cabdff1aSopenharmony_ci    case I_F_Q:
374cabdff1aSopenharmony_ci        cbseed = -44; // random codebook index
375cabdff1aSopenharmony_ci        for (i = 0; i < 4; i++) {
376cabdff1aSopenharmony_ci            tmp_gain = gain[i] * QCELP_RATE_FULL_CODEBOOK_RATIO;
377cabdff1aSopenharmony_ci            for (j = 0; j < 40; j++)
378cabdff1aSopenharmony_ci                *cdn_vector++ = tmp_gain *
379cabdff1aSopenharmony_ci                                qcelp_rate_full_codebook[cbseed++ & 127];
380cabdff1aSopenharmony_ci        }
381cabdff1aSopenharmony_ci        break;
382cabdff1aSopenharmony_ci    case SILENCE:
383cabdff1aSopenharmony_ci        memset(cdn_vector, 0, 160 * sizeof(float));
384cabdff1aSopenharmony_ci        break;
385cabdff1aSopenharmony_ci    }
386cabdff1aSopenharmony_ci}
387cabdff1aSopenharmony_ci
388cabdff1aSopenharmony_ci/**
389cabdff1aSopenharmony_ci * Apply generic gain control.
390cabdff1aSopenharmony_ci *
391cabdff1aSopenharmony_ci * @param v_out output vector
392cabdff1aSopenharmony_ci * @param v_in gain-controlled vector
393cabdff1aSopenharmony_ci * @param v_ref vector to control gain of
394cabdff1aSopenharmony_ci *
395cabdff1aSopenharmony_ci * TIA/EIA/IS-733 2.4.8.3, 2.4.8.6
396cabdff1aSopenharmony_ci */
397cabdff1aSopenharmony_cistatic void apply_gain_ctrl(float *v_out, const float *v_ref, const float *v_in)
398cabdff1aSopenharmony_ci{
399cabdff1aSopenharmony_ci    int i;
400cabdff1aSopenharmony_ci
401cabdff1aSopenharmony_ci    for (i = 0; i < 160; i += 40) {
402cabdff1aSopenharmony_ci        float res = avpriv_scalarproduct_float_c(v_ref + i, v_ref + i, 40);
403cabdff1aSopenharmony_ci        ff_scale_vector_to_given_sum_of_squares(v_out + i, v_in + i, res, 40);
404cabdff1aSopenharmony_ci    }
405cabdff1aSopenharmony_ci}
406cabdff1aSopenharmony_ci
407cabdff1aSopenharmony_ci/**
408cabdff1aSopenharmony_ci * Apply filter in pitch-subframe steps.
409cabdff1aSopenharmony_ci *
410cabdff1aSopenharmony_ci * @param memory buffer for the previous state of the filter
411cabdff1aSopenharmony_ci *        - must be able to contain 303 elements
412cabdff1aSopenharmony_ci *        - the 143 first elements are from the previous state
413cabdff1aSopenharmony_ci *        - the next 160 are for output
414cabdff1aSopenharmony_ci * @param v_in input filter vector
415cabdff1aSopenharmony_ci * @param gain per-subframe gain array, each element is between 0.0 and 2.0
416cabdff1aSopenharmony_ci * @param lag per-subframe lag array, each element is
417cabdff1aSopenharmony_ci *        - between 16 and 143 if its corresponding pfrac is 0,
418cabdff1aSopenharmony_ci *        - between 16 and 139 otherwise
419cabdff1aSopenharmony_ci * @param pfrac per-subframe boolean array, 1 if the lag is fractional, 0
420cabdff1aSopenharmony_ci *        otherwise
421cabdff1aSopenharmony_ci *
422cabdff1aSopenharmony_ci * @return filter output vector
423cabdff1aSopenharmony_ci */
424cabdff1aSopenharmony_cistatic const float *do_pitchfilter(float memory[303], const float v_in[160],
425cabdff1aSopenharmony_ci                                   const float gain[4], const uint8_t *lag,
426cabdff1aSopenharmony_ci                                   const uint8_t pfrac[4])
427cabdff1aSopenharmony_ci{
428cabdff1aSopenharmony_ci    int i, j;
429cabdff1aSopenharmony_ci    float *v_lag, *v_out;
430cabdff1aSopenharmony_ci    const float *v_len;
431cabdff1aSopenharmony_ci
432cabdff1aSopenharmony_ci    v_out = memory + 143; // Output vector starts at memory[143].
433cabdff1aSopenharmony_ci
434cabdff1aSopenharmony_ci    for (i = 0; i < 4; i++) {
435cabdff1aSopenharmony_ci        if (gain[i]) {
436cabdff1aSopenharmony_ci            v_lag = memory + 143 + 40 * i - lag[i];
437cabdff1aSopenharmony_ci            for (v_len = v_in + 40; v_in < v_len; v_in++) {
438cabdff1aSopenharmony_ci                if (pfrac[i]) { // If it is a fractional lag...
439cabdff1aSopenharmony_ci                    for (j = 0, *v_out = 0.0; j < 4; j++)
440cabdff1aSopenharmony_ci                        *v_out += qcelp_hammsinc_table[j] *
441cabdff1aSopenharmony_ci                                  (v_lag[j - 4] + v_lag[3 - j]);
442cabdff1aSopenharmony_ci                } else
443cabdff1aSopenharmony_ci                    *v_out = *v_lag;
444cabdff1aSopenharmony_ci
445cabdff1aSopenharmony_ci                *v_out = *v_in + gain[i] * *v_out;
446cabdff1aSopenharmony_ci
447cabdff1aSopenharmony_ci                v_lag++;
448cabdff1aSopenharmony_ci                v_out++;
449cabdff1aSopenharmony_ci            }
450cabdff1aSopenharmony_ci        } else {
451cabdff1aSopenharmony_ci            memcpy(v_out, v_in, 40 * sizeof(float));
452cabdff1aSopenharmony_ci            v_in  += 40;
453cabdff1aSopenharmony_ci            v_out += 40;
454cabdff1aSopenharmony_ci        }
455cabdff1aSopenharmony_ci    }
456cabdff1aSopenharmony_ci
457cabdff1aSopenharmony_ci    memmove(memory, memory + 160, 143 * sizeof(float));
458cabdff1aSopenharmony_ci    return memory + 143;
459cabdff1aSopenharmony_ci}
460cabdff1aSopenharmony_ci
461cabdff1aSopenharmony_ci/**
462cabdff1aSopenharmony_ci * Apply pitch synthesis filter and pitch prefilter to the scaled codebook vector.
463cabdff1aSopenharmony_ci * TIA/EIA/IS-733 2.4.5.2, 2.4.8.7.2
464cabdff1aSopenharmony_ci *
465cabdff1aSopenharmony_ci * @param q the context
466cabdff1aSopenharmony_ci * @param cdn_vector the scaled codebook vector
467cabdff1aSopenharmony_ci */
468cabdff1aSopenharmony_cistatic void apply_pitch_filters(QCELPContext *q, float *cdn_vector)
469cabdff1aSopenharmony_ci{
470cabdff1aSopenharmony_ci    int i;
471cabdff1aSopenharmony_ci    const float *v_synthesis_filtered, *v_pre_filtered;
472cabdff1aSopenharmony_ci
473cabdff1aSopenharmony_ci    if (q->bitrate >= RATE_HALF || q->bitrate == SILENCE ||
474cabdff1aSopenharmony_ci        (q->bitrate == I_F_Q && (q->prev_bitrate >= RATE_HALF))) {
475cabdff1aSopenharmony_ci
476cabdff1aSopenharmony_ci        if (q->bitrate >= RATE_HALF) {
477cabdff1aSopenharmony_ci            // Compute gain & lag for the whole frame.
478cabdff1aSopenharmony_ci            for (i = 0; i < 4; i++) {
479cabdff1aSopenharmony_ci                q->pitch_gain[i] = q->frame.plag[i] ? (q->frame.pgain[i] + 1) * 0.25 : 0.0;
480cabdff1aSopenharmony_ci
481cabdff1aSopenharmony_ci                q->pitch_lag[i] = q->frame.plag[i] + 16;
482cabdff1aSopenharmony_ci            }
483cabdff1aSopenharmony_ci        } else {
484cabdff1aSopenharmony_ci            float max_pitch_gain;
485cabdff1aSopenharmony_ci
486cabdff1aSopenharmony_ci            if (q->bitrate == I_F_Q) {
487cabdff1aSopenharmony_ci                  if (q->erasure_count < 3)
488cabdff1aSopenharmony_ci                      max_pitch_gain = 0.9 - 0.3 * (q->erasure_count - 1);
489cabdff1aSopenharmony_ci                  else
490cabdff1aSopenharmony_ci                      max_pitch_gain = 0.0;
491cabdff1aSopenharmony_ci            } else {
492cabdff1aSopenharmony_ci                av_assert2(q->bitrate == SILENCE);
493cabdff1aSopenharmony_ci                max_pitch_gain = 1.0;
494cabdff1aSopenharmony_ci            }
495cabdff1aSopenharmony_ci            for (i = 0; i < 4; i++)
496cabdff1aSopenharmony_ci                q->pitch_gain[i] = FFMIN(q->pitch_gain[i], max_pitch_gain);
497cabdff1aSopenharmony_ci
498cabdff1aSopenharmony_ci            memset(q->frame.pfrac, 0, sizeof(q->frame.pfrac));
499cabdff1aSopenharmony_ci        }
500cabdff1aSopenharmony_ci
501cabdff1aSopenharmony_ci        // pitch synthesis filter
502cabdff1aSopenharmony_ci        v_synthesis_filtered = do_pitchfilter(q->pitch_synthesis_filter_mem,
503cabdff1aSopenharmony_ci                                              cdn_vector, q->pitch_gain,
504cabdff1aSopenharmony_ci                                              q->pitch_lag, q->frame.pfrac);
505cabdff1aSopenharmony_ci
506cabdff1aSopenharmony_ci        // pitch prefilter update
507cabdff1aSopenharmony_ci        for (i = 0; i < 4; i++)
508cabdff1aSopenharmony_ci            q->pitch_gain[i] = 0.5 * FFMIN(q->pitch_gain[i], 1.0);
509cabdff1aSopenharmony_ci
510cabdff1aSopenharmony_ci        v_pre_filtered       = do_pitchfilter(q->pitch_pre_filter_mem,
511cabdff1aSopenharmony_ci                                              v_synthesis_filtered,
512cabdff1aSopenharmony_ci                                              q->pitch_gain, q->pitch_lag,
513cabdff1aSopenharmony_ci                                              q->frame.pfrac);
514cabdff1aSopenharmony_ci
515cabdff1aSopenharmony_ci        apply_gain_ctrl(cdn_vector, v_synthesis_filtered, v_pre_filtered);
516cabdff1aSopenharmony_ci    } else {
517cabdff1aSopenharmony_ci        memcpy(q->pitch_synthesis_filter_mem,
518cabdff1aSopenharmony_ci               cdn_vector + 17, 143 * sizeof(float));
519cabdff1aSopenharmony_ci        memcpy(q->pitch_pre_filter_mem, cdn_vector + 17, 143 * sizeof(float));
520cabdff1aSopenharmony_ci        memset(q->pitch_gain, 0, sizeof(q->pitch_gain));
521cabdff1aSopenharmony_ci        memset(q->pitch_lag,  0, sizeof(q->pitch_lag));
522cabdff1aSopenharmony_ci    }
523cabdff1aSopenharmony_ci}
524cabdff1aSopenharmony_ci
525cabdff1aSopenharmony_ci/**
526cabdff1aSopenharmony_ci * Reconstruct LPC coefficients from the line spectral pair frequencies
527cabdff1aSopenharmony_ci * and perform bandwidth expansion.
528cabdff1aSopenharmony_ci *
529cabdff1aSopenharmony_ci * @param lspf line spectral pair frequencies
530cabdff1aSopenharmony_ci * @param lpc linear predictive coding coefficients
531cabdff1aSopenharmony_ci *
532cabdff1aSopenharmony_ci * @note: bandwidth_expansion_coeff could be precalculated into a table
533cabdff1aSopenharmony_ci *        but it seems to be slower on x86
534cabdff1aSopenharmony_ci *
535cabdff1aSopenharmony_ci * TIA/EIA/IS-733 2.4.3.3.5
536cabdff1aSopenharmony_ci */
537cabdff1aSopenharmony_cistatic void lspf2lpc(const float *lspf, float *lpc)
538cabdff1aSopenharmony_ci{
539cabdff1aSopenharmony_ci    double lsp[10];
540cabdff1aSopenharmony_ci    double bandwidth_expansion_coeff = QCELP_BANDWIDTH_EXPANSION_COEFF;
541cabdff1aSopenharmony_ci    int i;
542cabdff1aSopenharmony_ci
543cabdff1aSopenharmony_ci    for (i = 0; i < 10; i++)
544cabdff1aSopenharmony_ci        lsp[i] = cos(M_PI * lspf[i]);
545cabdff1aSopenharmony_ci
546cabdff1aSopenharmony_ci    ff_acelp_lspd2lpc(lsp, lpc, 5);
547cabdff1aSopenharmony_ci
548cabdff1aSopenharmony_ci    for (i = 0; i < 10; i++) {
549cabdff1aSopenharmony_ci        lpc[i]                    *= bandwidth_expansion_coeff;
550cabdff1aSopenharmony_ci        bandwidth_expansion_coeff *= QCELP_BANDWIDTH_EXPANSION_COEFF;
551cabdff1aSopenharmony_ci    }
552cabdff1aSopenharmony_ci}
553cabdff1aSopenharmony_ci
554cabdff1aSopenharmony_ci/**
555cabdff1aSopenharmony_ci * Interpolate LSP frequencies and compute LPC coefficients
556cabdff1aSopenharmony_ci * for a given bitrate & pitch subframe.
557cabdff1aSopenharmony_ci *
558cabdff1aSopenharmony_ci * TIA/EIA/IS-733 2.4.3.3.4, 2.4.8.7.2
559cabdff1aSopenharmony_ci *
560cabdff1aSopenharmony_ci * @param q the context
561cabdff1aSopenharmony_ci * @param curr_lspf LSP frequencies vector of the current frame
562cabdff1aSopenharmony_ci * @param lpc float vector for the resulting LPC
563cabdff1aSopenharmony_ci * @param subframe_num frame number in decoded stream
564cabdff1aSopenharmony_ci */
565cabdff1aSopenharmony_cistatic void interpolate_lpc(QCELPContext *q, const float *curr_lspf,
566cabdff1aSopenharmony_ci                            float *lpc, const int subframe_num)
567cabdff1aSopenharmony_ci{
568cabdff1aSopenharmony_ci    float interpolated_lspf[10];
569cabdff1aSopenharmony_ci    float weight;
570cabdff1aSopenharmony_ci
571cabdff1aSopenharmony_ci    if (q->bitrate >= RATE_QUARTER)
572cabdff1aSopenharmony_ci        weight = 0.25 * (subframe_num + 1);
573cabdff1aSopenharmony_ci    else if (q->bitrate == RATE_OCTAVE && !subframe_num)
574cabdff1aSopenharmony_ci        weight = 0.625;
575cabdff1aSopenharmony_ci    else
576cabdff1aSopenharmony_ci        weight = 1.0;
577cabdff1aSopenharmony_ci
578cabdff1aSopenharmony_ci    if (weight != 1.0) {
579cabdff1aSopenharmony_ci        ff_weighted_vector_sumf(interpolated_lspf, curr_lspf, q->prev_lspf,
580cabdff1aSopenharmony_ci                                weight, 1.0 - weight, 10);
581cabdff1aSopenharmony_ci        lspf2lpc(interpolated_lspf, lpc);
582cabdff1aSopenharmony_ci    } else if (q->bitrate >= RATE_QUARTER ||
583cabdff1aSopenharmony_ci               (q->bitrate == I_F_Q && !subframe_num))
584cabdff1aSopenharmony_ci        lspf2lpc(curr_lspf, lpc);
585cabdff1aSopenharmony_ci    else if (q->bitrate == SILENCE && !subframe_num)
586cabdff1aSopenharmony_ci        lspf2lpc(q->prev_lspf, lpc);
587cabdff1aSopenharmony_ci}
588cabdff1aSopenharmony_ci
589cabdff1aSopenharmony_cistatic qcelp_packet_rate buf_size2bitrate(const int buf_size)
590cabdff1aSopenharmony_ci{
591cabdff1aSopenharmony_ci    switch (buf_size) {
592cabdff1aSopenharmony_ci    case 35: return RATE_FULL;
593cabdff1aSopenharmony_ci    case 17: return RATE_HALF;
594cabdff1aSopenharmony_ci    case  8: return RATE_QUARTER;
595cabdff1aSopenharmony_ci    case  4: return RATE_OCTAVE;
596cabdff1aSopenharmony_ci    case  1: return SILENCE;
597cabdff1aSopenharmony_ci    }
598cabdff1aSopenharmony_ci
599cabdff1aSopenharmony_ci    return I_F_Q;
600cabdff1aSopenharmony_ci}
601cabdff1aSopenharmony_ci
602cabdff1aSopenharmony_ci/**
603cabdff1aSopenharmony_ci * Determine the bitrate from the frame size and/or the first byte of the frame.
604cabdff1aSopenharmony_ci *
605cabdff1aSopenharmony_ci * @param avctx the AV codec context
606cabdff1aSopenharmony_ci * @param buf_size length of the buffer
607cabdff1aSopenharmony_ci * @param buf the buffer
608cabdff1aSopenharmony_ci *
609cabdff1aSopenharmony_ci * @return the bitrate on success,
610cabdff1aSopenharmony_ci *         I_F_Q  if the bitrate cannot be satisfactorily determined
611cabdff1aSopenharmony_ci *
612cabdff1aSopenharmony_ci * TIA/EIA/IS-733 2.4.8.7.1
613cabdff1aSopenharmony_ci */
614cabdff1aSopenharmony_cistatic qcelp_packet_rate determine_bitrate(AVCodecContext *avctx,
615cabdff1aSopenharmony_ci                                           const int buf_size,
616cabdff1aSopenharmony_ci                                           const uint8_t **buf)
617cabdff1aSopenharmony_ci{
618cabdff1aSopenharmony_ci    qcelp_packet_rate bitrate;
619cabdff1aSopenharmony_ci
620cabdff1aSopenharmony_ci    if ((bitrate = buf_size2bitrate(buf_size)) >= 0) {
621cabdff1aSopenharmony_ci        if (bitrate > **buf) {
622cabdff1aSopenharmony_ci            QCELPContext *q = avctx->priv_data;
623cabdff1aSopenharmony_ci            if (!q->warned_buf_mismatch_bitrate) {
624cabdff1aSopenharmony_ci            av_log(avctx, AV_LOG_WARNING,
625cabdff1aSopenharmony_ci                   "Claimed bitrate and buffer size mismatch.\n");
626cabdff1aSopenharmony_ci                q->warned_buf_mismatch_bitrate = 1;
627cabdff1aSopenharmony_ci            }
628cabdff1aSopenharmony_ci            bitrate = **buf;
629cabdff1aSopenharmony_ci        } else if (bitrate < **buf) {
630cabdff1aSopenharmony_ci            av_log(avctx, AV_LOG_ERROR,
631cabdff1aSopenharmony_ci                   "Buffer is too small for the claimed bitrate.\n");
632cabdff1aSopenharmony_ci            return I_F_Q;
633cabdff1aSopenharmony_ci        }
634cabdff1aSopenharmony_ci        (*buf)++;
635cabdff1aSopenharmony_ci    } else if ((bitrate = buf_size2bitrate(buf_size + 1)) >= 0) {
636cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_WARNING,
637cabdff1aSopenharmony_ci               "Bitrate byte missing, guessing bitrate from packet size.\n");
638cabdff1aSopenharmony_ci    } else
639cabdff1aSopenharmony_ci        return I_F_Q;
640cabdff1aSopenharmony_ci
641cabdff1aSopenharmony_ci    if (bitrate == SILENCE) {
642cabdff1aSopenharmony_ci        // FIXME: Remove this warning when tested with samples.
643cabdff1aSopenharmony_ci        avpriv_request_sample(avctx, "Blank frame handling");
644cabdff1aSopenharmony_ci    }
645cabdff1aSopenharmony_ci    return bitrate;
646cabdff1aSopenharmony_ci}
647cabdff1aSopenharmony_ci
648cabdff1aSopenharmony_cistatic void warn_insufficient_frame_quality(AVCodecContext *avctx,
649cabdff1aSopenharmony_ci                                            const char *message)
650cabdff1aSopenharmony_ci{
651cabdff1aSopenharmony_ci    av_log(avctx, AV_LOG_WARNING, "Frame #%d, IFQ: %s\n",
652cabdff1aSopenharmony_ci           avctx->frame_number, message);
653cabdff1aSopenharmony_ci}
654cabdff1aSopenharmony_ci
655cabdff1aSopenharmony_cistatic void postfilter(QCELPContext *q, float *samples, float *lpc)
656cabdff1aSopenharmony_ci{
657cabdff1aSopenharmony_ci    static const float pow_0_775[10] = {
658cabdff1aSopenharmony_ci        0.775000, 0.600625, 0.465484, 0.360750, 0.279582,
659cabdff1aSopenharmony_ci        0.216676, 0.167924, 0.130141, 0.100859, 0.078166
660cabdff1aSopenharmony_ci    }, pow_0_625[10] = {
661cabdff1aSopenharmony_ci        0.625000, 0.390625, 0.244141, 0.152588, 0.095367,
662cabdff1aSopenharmony_ci        0.059605, 0.037253, 0.023283, 0.014552, 0.009095
663cabdff1aSopenharmony_ci    };
664cabdff1aSopenharmony_ci    float lpc_s[10], lpc_p[10], pole_out[170], zero_out[160];
665cabdff1aSopenharmony_ci    int n;
666cabdff1aSopenharmony_ci
667cabdff1aSopenharmony_ci    for (n = 0; n < 10; n++) {
668cabdff1aSopenharmony_ci        lpc_s[n] = lpc[n] * pow_0_625[n];
669cabdff1aSopenharmony_ci        lpc_p[n] = lpc[n] * pow_0_775[n];
670cabdff1aSopenharmony_ci    }
671cabdff1aSopenharmony_ci
672cabdff1aSopenharmony_ci    ff_celp_lp_zero_synthesis_filterf(zero_out, lpc_s,
673cabdff1aSopenharmony_ci                                      q->formant_mem + 10, 160, 10);
674cabdff1aSopenharmony_ci    memcpy(pole_out, q->postfilter_synth_mem, sizeof(float) * 10);
675cabdff1aSopenharmony_ci    ff_celp_lp_synthesis_filterf(pole_out + 10, lpc_p, zero_out, 160, 10);
676cabdff1aSopenharmony_ci    memcpy(q->postfilter_synth_mem, pole_out + 160, sizeof(float) * 10);
677cabdff1aSopenharmony_ci
678cabdff1aSopenharmony_ci    ff_tilt_compensation(&q->postfilter_tilt_mem, 0.3, pole_out + 10, 160);
679cabdff1aSopenharmony_ci
680cabdff1aSopenharmony_ci    ff_adaptive_gain_control(samples, pole_out + 10,
681cabdff1aSopenharmony_ci                             avpriv_scalarproduct_float_c(q->formant_mem + 10,
682cabdff1aSopenharmony_ci                                                          q->formant_mem + 10,
683cabdff1aSopenharmony_ci                                                          160),
684cabdff1aSopenharmony_ci                             160, 0.9375, &q->postfilter_agc_mem);
685cabdff1aSopenharmony_ci}
686cabdff1aSopenharmony_ci
687cabdff1aSopenharmony_cistatic int qcelp_decode_frame(AVCodecContext *avctx, AVFrame *frame,
688cabdff1aSopenharmony_ci                              int *got_frame_ptr, AVPacket *avpkt)
689cabdff1aSopenharmony_ci{
690cabdff1aSopenharmony_ci    const uint8_t *buf = avpkt->data;
691cabdff1aSopenharmony_ci    int buf_size       = avpkt->size;
692cabdff1aSopenharmony_ci    QCELPContext *q    = avctx->priv_data;
693cabdff1aSopenharmony_ci    float *outbuffer;
694cabdff1aSopenharmony_ci    int   i, ret;
695cabdff1aSopenharmony_ci    float quantized_lspf[10], lpc[10];
696cabdff1aSopenharmony_ci    float gain[16];
697cabdff1aSopenharmony_ci    float *formant_mem;
698cabdff1aSopenharmony_ci
699cabdff1aSopenharmony_ci    /* get output buffer */
700cabdff1aSopenharmony_ci    frame->nb_samples = 160;
701cabdff1aSopenharmony_ci    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
702cabdff1aSopenharmony_ci        return ret;
703cabdff1aSopenharmony_ci    outbuffer = (float *)frame->data[0];
704cabdff1aSopenharmony_ci
705cabdff1aSopenharmony_ci    if ((q->bitrate = determine_bitrate(avctx, buf_size, &buf)) == I_F_Q) {
706cabdff1aSopenharmony_ci        warn_insufficient_frame_quality(avctx, "Bitrate cannot be determined.");
707cabdff1aSopenharmony_ci        goto erasure;
708cabdff1aSopenharmony_ci    }
709cabdff1aSopenharmony_ci
710cabdff1aSopenharmony_ci    if (q->bitrate == RATE_OCTAVE &&
711cabdff1aSopenharmony_ci        (q->first16bits = AV_RB16(buf)) == 0xFFFF) {
712cabdff1aSopenharmony_ci        warn_insufficient_frame_quality(avctx, "Bitrate is 1/8 and first 16 bits are on.");
713cabdff1aSopenharmony_ci        goto erasure;
714cabdff1aSopenharmony_ci    }
715cabdff1aSopenharmony_ci
716cabdff1aSopenharmony_ci    if (q->bitrate > SILENCE) {
717cabdff1aSopenharmony_ci        const QCELPBitmap *bitmaps     = qcelp_unpacking_bitmaps_per_rate[q->bitrate];
718cabdff1aSopenharmony_ci        const QCELPBitmap *bitmaps_end = qcelp_unpacking_bitmaps_per_rate[q->bitrate] +
719cabdff1aSopenharmony_ci                                         qcelp_unpacking_bitmaps_lengths[q->bitrate];
720cabdff1aSopenharmony_ci        uint8_t *unpacked_data         = (uint8_t *)&q->frame;
721cabdff1aSopenharmony_ci
722cabdff1aSopenharmony_ci        if ((ret = init_get_bits8(&q->gb, buf, buf_size)) < 0)
723cabdff1aSopenharmony_ci            return ret;
724cabdff1aSopenharmony_ci
725cabdff1aSopenharmony_ci        memset(&q->frame, 0, sizeof(QCELPFrame));
726cabdff1aSopenharmony_ci
727cabdff1aSopenharmony_ci        for (; bitmaps < bitmaps_end; bitmaps++)
728cabdff1aSopenharmony_ci            unpacked_data[bitmaps->index] |= get_bits(&q->gb, bitmaps->bitlen) << bitmaps->bitpos;
729cabdff1aSopenharmony_ci
730cabdff1aSopenharmony_ci        // Check for erasures/blanks on rates 1, 1/4 and 1/8.
731cabdff1aSopenharmony_ci        if (q->frame.reserved) {
732cabdff1aSopenharmony_ci            warn_insufficient_frame_quality(avctx, "Wrong data in reserved frame area.");
733cabdff1aSopenharmony_ci            goto erasure;
734cabdff1aSopenharmony_ci        }
735cabdff1aSopenharmony_ci        if (q->bitrate == RATE_QUARTER &&
736cabdff1aSopenharmony_ci            codebook_sanity_check_for_rate_quarter(q->frame.cbgain)) {
737cabdff1aSopenharmony_ci            warn_insufficient_frame_quality(avctx, "Codebook gain sanity check failed.");
738cabdff1aSopenharmony_ci            goto erasure;
739cabdff1aSopenharmony_ci        }
740cabdff1aSopenharmony_ci
741cabdff1aSopenharmony_ci        if (q->bitrate >= RATE_HALF) {
742cabdff1aSopenharmony_ci            for (i = 0; i < 4; i++) {
743cabdff1aSopenharmony_ci                if (q->frame.pfrac[i] && q->frame.plag[i] >= 124) {
744cabdff1aSopenharmony_ci                    warn_insufficient_frame_quality(avctx, "Cannot initialize pitch filter.");
745cabdff1aSopenharmony_ci                    goto erasure;
746cabdff1aSopenharmony_ci                }
747cabdff1aSopenharmony_ci            }
748cabdff1aSopenharmony_ci        }
749cabdff1aSopenharmony_ci    }
750cabdff1aSopenharmony_ci
751cabdff1aSopenharmony_ci    decode_gain_and_index(q, gain);
752cabdff1aSopenharmony_ci    compute_svector(q, gain, outbuffer);
753cabdff1aSopenharmony_ci
754cabdff1aSopenharmony_ci    if (decode_lspf(q, quantized_lspf) < 0) {
755cabdff1aSopenharmony_ci        warn_insufficient_frame_quality(avctx, "Badly received packets in frame.");
756cabdff1aSopenharmony_ci        goto erasure;
757cabdff1aSopenharmony_ci    }
758cabdff1aSopenharmony_ci
759cabdff1aSopenharmony_ci    apply_pitch_filters(q, outbuffer);
760cabdff1aSopenharmony_ci
761cabdff1aSopenharmony_ci    if (q->bitrate == I_F_Q) {
762cabdff1aSopenharmony_cierasure:
763cabdff1aSopenharmony_ci        q->bitrate = I_F_Q;
764cabdff1aSopenharmony_ci        q->erasure_count++;
765cabdff1aSopenharmony_ci        decode_gain_and_index(q, gain);
766cabdff1aSopenharmony_ci        compute_svector(q, gain, outbuffer);
767cabdff1aSopenharmony_ci        decode_lspf(q, quantized_lspf);
768cabdff1aSopenharmony_ci        apply_pitch_filters(q, outbuffer);
769cabdff1aSopenharmony_ci    } else
770cabdff1aSopenharmony_ci        q->erasure_count = 0;
771cabdff1aSopenharmony_ci
772cabdff1aSopenharmony_ci    formant_mem = q->formant_mem + 10;
773cabdff1aSopenharmony_ci    for (i = 0; i < 4; i++) {
774cabdff1aSopenharmony_ci        interpolate_lpc(q, quantized_lspf, lpc, i);
775cabdff1aSopenharmony_ci        ff_celp_lp_synthesis_filterf(formant_mem, lpc,
776cabdff1aSopenharmony_ci                                     outbuffer + i * 40, 40, 10);
777cabdff1aSopenharmony_ci        formant_mem += 40;
778cabdff1aSopenharmony_ci    }
779cabdff1aSopenharmony_ci
780cabdff1aSopenharmony_ci    // postfilter, as per TIA/EIA/IS-733 2.4.8.6
781cabdff1aSopenharmony_ci    postfilter(q, outbuffer, lpc);
782cabdff1aSopenharmony_ci
783cabdff1aSopenharmony_ci    memcpy(q->formant_mem, q->formant_mem + 160, 10 * sizeof(float));
784cabdff1aSopenharmony_ci
785cabdff1aSopenharmony_ci    memcpy(q->prev_lspf, quantized_lspf, sizeof(q->prev_lspf));
786cabdff1aSopenharmony_ci    q->prev_bitrate  = q->bitrate;
787cabdff1aSopenharmony_ci
788cabdff1aSopenharmony_ci    *got_frame_ptr = 1;
789cabdff1aSopenharmony_ci
790cabdff1aSopenharmony_ci    return buf_size;
791cabdff1aSopenharmony_ci}
792cabdff1aSopenharmony_ci
793cabdff1aSopenharmony_ciconst FFCodec ff_qcelp_decoder = {
794cabdff1aSopenharmony_ci    .p.name         = "qcelp",
795cabdff1aSopenharmony_ci    .p.long_name    = NULL_IF_CONFIG_SMALL("QCELP / PureVoice"),
796cabdff1aSopenharmony_ci    .p.type         = AVMEDIA_TYPE_AUDIO,
797cabdff1aSopenharmony_ci    .p.id           = AV_CODEC_ID_QCELP,
798cabdff1aSopenharmony_ci    .init           = qcelp_decode_init,
799cabdff1aSopenharmony_ci    FF_CODEC_DECODE_CB(qcelp_decode_frame),
800cabdff1aSopenharmony_ci    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
801cabdff1aSopenharmony_ci    .priv_data_size = sizeof(QCELPContext),
802cabdff1aSopenharmony_ci    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
803cabdff1aSopenharmony_ci};
804