1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * Digital Speech Standard - Standard Play mode (DSS SP) audio decoder.
3cabdff1aSopenharmony_ci * Copyright (C) 2014 Oleksij Rempel <linux@rempel-privat.de>
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#include "libavutil/channel_layout.h"
23cabdff1aSopenharmony_ci#include "libavutil/common.h"
24cabdff1aSopenharmony_ci#include "libavutil/mem_internal.h"
25cabdff1aSopenharmony_ci#include "libavutil/opt.h"
26cabdff1aSopenharmony_ci
27cabdff1aSopenharmony_ci#include "avcodec.h"
28cabdff1aSopenharmony_ci#include "codec_internal.h"
29cabdff1aSopenharmony_ci#include "get_bits.h"
30cabdff1aSopenharmony_ci#include "internal.h"
31cabdff1aSopenharmony_ci
32cabdff1aSopenharmony_ci#define SUBFRAMES 4
33cabdff1aSopenharmony_ci#define PULSE_MAX 8
34cabdff1aSopenharmony_ci
35cabdff1aSopenharmony_ci#define DSS_SP_FRAME_SIZE        42
36cabdff1aSopenharmony_ci#define DSS_SP_SAMPLE_COUNT     (66 * SUBFRAMES)
37cabdff1aSopenharmony_ci#define DSS_SP_FORMULA(a, b, c) ((int)((((a) * (1 << 15)) + (b) * (unsigned)(c)) + 0x4000) >> 15)
38cabdff1aSopenharmony_ci
39cabdff1aSopenharmony_citypedef struct DssSpSubframe {
40cabdff1aSopenharmony_ci    int16_t gain;
41cabdff1aSopenharmony_ci    int32_t combined_pulse_pos;
42cabdff1aSopenharmony_ci    int16_t pulse_pos[7];
43cabdff1aSopenharmony_ci    int16_t pulse_val[7];
44cabdff1aSopenharmony_ci} DssSpSubframe;
45cabdff1aSopenharmony_ci
46cabdff1aSopenharmony_citypedef struct DssSpFrame {
47cabdff1aSopenharmony_ci    int16_t filter_idx[14];
48cabdff1aSopenharmony_ci    int16_t sf_adaptive_gain[SUBFRAMES];
49cabdff1aSopenharmony_ci    int16_t pitch_lag[SUBFRAMES];
50cabdff1aSopenharmony_ci    struct DssSpSubframe sf[SUBFRAMES];
51cabdff1aSopenharmony_ci} DssSpFrame;
52cabdff1aSopenharmony_ci
53cabdff1aSopenharmony_citypedef struct DssSpContext {
54cabdff1aSopenharmony_ci    AVCodecContext *avctx;
55cabdff1aSopenharmony_ci    int32_t excitation[288 + 6];
56cabdff1aSopenharmony_ci    int32_t history[187];
57cabdff1aSopenharmony_ci    DssSpFrame fparam;
58cabdff1aSopenharmony_ci    int32_t working_buffer[SUBFRAMES][72];
59cabdff1aSopenharmony_ci    int32_t audio_buf[15];
60cabdff1aSopenharmony_ci    int32_t err_buf1[15];
61cabdff1aSopenharmony_ci    int32_t lpc_filter[14];
62cabdff1aSopenharmony_ci    int32_t filter[15];
63cabdff1aSopenharmony_ci    int32_t vector_buf[72];
64cabdff1aSopenharmony_ci    int noise_state;
65cabdff1aSopenharmony_ci    int32_t err_buf2[15];
66cabdff1aSopenharmony_ci
67cabdff1aSopenharmony_ci    int pulse_dec_mode;
68cabdff1aSopenharmony_ci
69cabdff1aSopenharmony_ci    DECLARE_ALIGNED(16, uint8_t, bits)[DSS_SP_FRAME_SIZE +
70cabdff1aSopenharmony_ci                                       AV_INPUT_BUFFER_PADDING_SIZE];
71cabdff1aSopenharmony_ci} DssSpContext;
72cabdff1aSopenharmony_ci
73cabdff1aSopenharmony_ci/*
74cabdff1aSopenharmony_ci * Used for the coding/decoding of the pulse positions for the MP-MLQ codebook.
75cabdff1aSopenharmony_ci */
76cabdff1aSopenharmony_cistatic const uint32_t dss_sp_combinatorial_table[PULSE_MAX][72] = {
77cabdff1aSopenharmony_ci    {       0,         0,         0,          0,          0,          0,
78cabdff1aSopenharmony_ci            0,         0,         0,          0,          0,          0,
79cabdff1aSopenharmony_ci            0,         0,         0,          0,          0,          0,
80cabdff1aSopenharmony_ci            0,         0,         0,          0,          0,          0,
81cabdff1aSopenharmony_ci            0,         0,         0,          0,          0,          0,
82cabdff1aSopenharmony_ci            0,         0,         0,          0,          0,          0,
83cabdff1aSopenharmony_ci            0,         0,         0,          0,          0,          0,
84cabdff1aSopenharmony_ci            0,         0,         0,          0,          0,          0,
85cabdff1aSopenharmony_ci            0,         0,         0,          0,          0,          0,
86cabdff1aSopenharmony_ci            0,         0,         0,          0,          0,          0,
87cabdff1aSopenharmony_ci            0,         0,         0,          0,          0,          0,
88cabdff1aSopenharmony_ci            0,         0,         0,          0,          0,          0 },
89cabdff1aSopenharmony_ci    {       0,         1,         2,          3,          4,          5,
90cabdff1aSopenharmony_ci            6,         7,         8,          9,         10,         11,
91cabdff1aSopenharmony_ci           12,        13,        14,         15,         16,         17,
92cabdff1aSopenharmony_ci           18,        19,        20,         21,         22,         23,
93cabdff1aSopenharmony_ci           24,        25,        26,         27,         28,         29,
94cabdff1aSopenharmony_ci           30,        31,        32,         33,         34,         35,
95cabdff1aSopenharmony_ci           36,        37,        38,         39,         40,         41,
96cabdff1aSopenharmony_ci           42,        43,        44,         45,         46,         47,
97cabdff1aSopenharmony_ci           48,        49,        50,         51,         52,         53,
98cabdff1aSopenharmony_ci           54,        55,        56,         57,         58,         59,
99cabdff1aSopenharmony_ci           60,        61,        62,         63,         64,         65,
100cabdff1aSopenharmony_ci           66,        67,        68,         69,         70,         71 },
101cabdff1aSopenharmony_ci    {       0,         0,         1,          3,          6,         10,
102cabdff1aSopenharmony_ci           15,        21,        28,         36,         45,         55,
103cabdff1aSopenharmony_ci           66,        78,        91,        105,        120,        136,
104cabdff1aSopenharmony_ci          153,       171,       190,        210,        231,        253,
105cabdff1aSopenharmony_ci          276,       300,       325,        351,        378,        406,
106cabdff1aSopenharmony_ci          435,       465,       496,        528,        561,        595,
107cabdff1aSopenharmony_ci          630,       666,       703,        741,        780,        820,
108cabdff1aSopenharmony_ci          861,       903,       946,        990,       1035,       1081,
109cabdff1aSopenharmony_ci         1128,      1176,      1225,       1275,       1326,       1378,
110cabdff1aSopenharmony_ci         1431,      1485,      1540,       1596,       1653,       1711,
111cabdff1aSopenharmony_ci         1770,      1830,      1891,       1953,       2016,       2080,
112cabdff1aSopenharmony_ci         2145,      2211,      2278,       2346,       2415,       2485 },
113cabdff1aSopenharmony_ci    {       0,         0,         0,          1,          4,         10,
114cabdff1aSopenharmony_ci           20,        35,        56,         84,        120,        165,
115cabdff1aSopenharmony_ci          220,       286,       364,        455,        560,        680,
116cabdff1aSopenharmony_ci          816,       969,      1140,       1330,       1540,       1771,
117cabdff1aSopenharmony_ci         2024,      2300,      2600,       2925,       3276,       3654,
118cabdff1aSopenharmony_ci         4060,      4495,      4960,       5456,       5984,       6545,
119cabdff1aSopenharmony_ci         7140,      7770,      8436,       9139,       9880,      10660,
120cabdff1aSopenharmony_ci        11480,     12341,     13244,      14190,      15180,      16215,
121cabdff1aSopenharmony_ci        17296,     18424,     19600,      20825,      22100,      23426,
122cabdff1aSopenharmony_ci        24804,     26235,     27720,      29260,      30856,      32509,
123cabdff1aSopenharmony_ci        34220,     35990,     37820,      39711,      41664,      43680,
124cabdff1aSopenharmony_ci        45760,     47905,     50116,      52394,      54740,      57155 },
125cabdff1aSopenharmony_ci    {       0,         0,         0,          0,          1,          5,
126cabdff1aSopenharmony_ci           15,        35,        70,        126,        210,        330,
127cabdff1aSopenharmony_ci          495,       715,      1001,       1365,       1820,       2380,
128cabdff1aSopenharmony_ci         3060,      3876,      4845,       5985,       7315,       8855,
129cabdff1aSopenharmony_ci        10626,     12650,     14950,      17550,      20475,      23751,
130cabdff1aSopenharmony_ci        27405,     31465,     35960,      40920,      46376,      52360,
131cabdff1aSopenharmony_ci        58905,     66045,     73815,      82251,      91390,     101270,
132cabdff1aSopenharmony_ci       111930,    123410,    135751,     148995,     163185,     178365,
133cabdff1aSopenharmony_ci       194580,    211876,    230300,     249900,     270725,     292825,
134cabdff1aSopenharmony_ci       316251,    341055,    367290,     395010,     424270,     455126,
135cabdff1aSopenharmony_ci       487635,    521855,    557845,     595665,     635376,     677040,
136cabdff1aSopenharmony_ci       720720,    766480,    814385,     864501,     916895,     971635 },
137cabdff1aSopenharmony_ci    {       0,         0,         0,          0,          0,          1,
138cabdff1aSopenharmony_ci            6,        21,        56,        126,        252,        462,
139cabdff1aSopenharmony_ci          792,      1287,      2002,       3003,       4368,       6188,
140cabdff1aSopenharmony_ci         8568,     11628,     15504,      20349,      26334,      33649,
141cabdff1aSopenharmony_ci        42504,     53130,     65780,      80730,      98280,     118755,
142cabdff1aSopenharmony_ci       142506,    169911,    201376,     237336,     278256,     324632,
143cabdff1aSopenharmony_ci       376992,    435897,    501942,     575757,     658008,     749398,
144cabdff1aSopenharmony_ci       850668,    962598,   1086008,    1221759,    1370754,    1533939,
145cabdff1aSopenharmony_ci      1712304,   1906884,   2118760,    2349060,    2598960,    2869685,
146cabdff1aSopenharmony_ci      3162510,   3478761,   3819816,    4187106,    4582116,    5006386,
147cabdff1aSopenharmony_ci      5461512,   5949147,   6471002,    7028847,    7624512,    8259888,
148cabdff1aSopenharmony_ci      8936928,   9657648,  10424128,   11238513,   12103014,   13019909 },
149cabdff1aSopenharmony_ci    {       0,         0,         0,          0,          0,          0,
150cabdff1aSopenharmony_ci            1,         7,        28,         84,        210,        462,
151cabdff1aSopenharmony_ci          924,      1716,      3003,       5005,       8008,      12376,
152cabdff1aSopenharmony_ci        18564,     27132,     38760,      54264,      74613,     100947,
153cabdff1aSopenharmony_ci       134596,    177100,    230230,     296010,     376740,     475020,
154cabdff1aSopenharmony_ci       593775,    736281,    906192,    1107568,    1344904,    1623160,
155cabdff1aSopenharmony_ci      1947792,   2324784,   2760681,    3262623,    3838380,    4496388,
156cabdff1aSopenharmony_ci      5245786,   6096454,   7059052,    8145060,    9366819,   10737573,
157cabdff1aSopenharmony_ci     12271512,  13983816,  15890700,   18009460,   20358520,   22957480,
158cabdff1aSopenharmony_ci     25827165,  28989675,  32468436,   36288252,   40475358,   45057474,
159cabdff1aSopenharmony_ci     50063860,  55525372,  61474519,   67945521,   74974368,   82598880,
160cabdff1aSopenharmony_ci     90858768,  99795696, 109453344,  119877472,  131115985,  143218999 },
161cabdff1aSopenharmony_ci    {       0,         0,         0,          0,          0,          0,
162cabdff1aSopenharmony_ci            0,         1,         8,         36,        120,        330,
163cabdff1aSopenharmony_ci          792,      1716,      3432,       6435,      11440,      19448,
164cabdff1aSopenharmony_ci        31824,     50388,     77520,     116280,     170544,     245157,
165cabdff1aSopenharmony_ci       346104,    480700,    657800,     888030,    1184040,    1560780,
166cabdff1aSopenharmony_ci      2035800,   2629575,   3365856,    4272048,    5379616,    6724520,
167cabdff1aSopenharmony_ci      8347680,  10295472,  12620256,   15380937,   18643560,   22481940,
168cabdff1aSopenharmony_ci     26978328,  32224114,  38320568,   45379620,   53524680,   62891499,
169cabdff1aSopenharmony_ci     73629072,  85900584,  99884400,  115775100,  133784560,  154143080,
170cabdff1aSopenharmony_ci    177100560, 202927725, 231917400,  264385836,  300674088,  341149446,
171cabdff1aSopenharmony_ci    386206920, 436270780, 491796152,  553270671,  621216192,  696190560,
172cabdff1aSopenharmony_ci    778789440, 869648208, 969443904, 1078897248, 1198774720, 1329890705 },
173cabdff1aSopenharmony_ci};
174cabdff1aSopenharmony_ci
175cabdff1aSopenharmony_cistatic const int16_t dss_sp_filter_cb[14][32] = {
176cabdff1aSopenharmony_ci    { -32653, -32587, -32515, -32438, -32341, -32216, -32062, -31881,
177cabdff1aSopenharmony_ci      -31665, -31398, -31080, -30724, -30299, -29813, -29248, -28572,
178cabdff1aSopenharmony_ci      -27674, -26439, -24666, -22466, -19433, -16133, -12218,  -7783,
179cabdff1aSopenharmony_ci       -2834,   1819,   6544,  11260,  16050,  20220,  24774,  28120 },
180cabdff1aSopenharmony_ci
181cabdff1aSopenharmony_ci    { -27503, -24509, -20644, -17496, -14187, -11277,  -8420,  -5595,
182cabdff1aSopenharmony_ci       -3013,   -624,   1711,   3880,   5844,   7774,   9739,  11592,
183cabdff1aSopenharmony_ci       13364,  14903,  16426,  17900,  19250,  20586,  21803,  23006,
184cabdff1aSopenharmony_ci       24142,  25249,  26275,  27300,  28359,  29249,  30118,  31183 },
185cabdff1aSopenharmony_ci
186cabdff1aSopenharmony_ci    { -27827, -24208, -20943, -17781, -14843, -11848,  -9066,  -6297,
187cabdff1aSopenharmony_ci       -3660,   -910,   1918,   5025,   8223,  11649,  15086,  18423,
188cabdff1aSopenharmony_ci           0,      0,      0,      0,      0,      0,      0,      0,
189cabdff1aSopenharmony_ci           0,      0,      0,      0,      0,      0,      0,      0 },
190cabdff1aSopenharmony_ci
191cabdff1aSopenharmony_ci    { -17128, -11975,  -8270,  -5123,  -2296,    183,   2503,   4707,
192cabdff1aSopenharmony_ci        6798,   8945,  11045,  13239,  15528,  18248,  21115,  24785,
193cabdff1aSopenharmony_ci           0,      0,      0,      0,      0,      0,      0,      0,
194cabdff1aSopenharmony_ci           0,      0,      0,      0,      0,      0,      0,      0 },
195cabdff1aSopenharmony_ci
196cabdff1aSopenharmony_ci    { -21557, -17280, -14286, -11644,  -9268,  -7087,  -4939,  -2831,
197cabdff1aSopenharmony_ci        -691,   1407,   3536,   5721,   8125,  10677,  13721,  17731,
198cabdff1aSopenharmony_ci           0,      0,      0,      0,      0,      0,      0,      0,
199cabdff1aSopenharmony_ci           0,      0,      0,      0,      0,      0,      0,      0 },
200cabdff1aSopenharmony_ci
201cabdff1aSopenharmony_ci    { -15030, -10377,  -7034,  -4327,  -1900,    364,   2458,   4450,
202cabdff1aSopenharmony_ci        6422,   8374,  10374,  12486,  14714,  16997,  19626,  22954,
203cabdff1aSopenharmony_ci           0,      0,      0,      0,      0,      0,      0,      0,
204cabdff1aSopenharmony_ci           0,      0,      0,      0,      0,      0,      0,      0 },
205cabdff1aSopenharmony_ci
206cabdff1aSopenharmony_ci    { -16155, -12362,  -9698,  -7460,  -5258,  -3359,  -1547,    219,
207cabdff1aSopenharmony_ci        1916,   3599,   5299,   6994,   8963,  11226,  13716,  16982,
208cabdff1aSopenharmony_ci           0,      0,      0,      0,      0,      0,      0,      0,
209cabdff1aSopenharmony_ci           0,      0,      0,      0,      0,      0,      0,      0 },
210cabdff1aSopenharmony_ci
211cabdff1aSopenharmony_ci    { -14742,  -9848,  -6921,  -4648,  -2769,  -1065,    499,   2083,
212cabdff1aSopenharmony_ci        3633,   5219,   6857,   8580,  10410,  12672,  15561,  20101,
213cabdff1aSopenharmony_ci           0,      0,      0,      0,      0,      0,      0,      0,
214cabdff1aSopenharmony_ci           0,      0,      0,      0,      0,      0,      0,      0 },
215cabdff1aSopenharmony_ci
216cabdff1aSopenharmony_ci    { -11099,  -7014,  -3855,  -1025,   1680,   4544,   7807,  11932,
217cabdff1aSopenharmony_ci           0,      0,      0,      0,      0,      0,      0,      0,
218cabdff1aSopenharmony_ci           0,      0,      0,      0,      0,      0,      0,      0,
219cabdff1aSopenharmony_ci           0,      0,      0,      0,      0,      0,      0,      0 },
220cabdff1aSopenharmony_ci
221cabdff1aSopenharmony_ci    {  -9060,  -4570,  -1381,   1419,   4034,   6728,   9865,  14149,
222cabdff1aSopenharmony_ci           0,      0,      0,      0,      0,      0,      0,      0,
223cabdff1aSopenharmony_ci           0,      0,      0,      0,      0,      0,      0,      0,
224cabdff1aSopenharmony_ci           0,      0,      0,      0,      0,      0,      0,      0 },
225cabdff1aSopenharmony_ci
226cabdff1aSopenharmony_ci    { -12450,  -7985,  -4596,  -1734,    961,   3629,   6865,  11142,
227cabdff1aSopenharmony_ci           0,      0,      0,      0,      0,      0,      0,      0,
228cabdff1aSopenharmony_ci           0,      0,      0,      0,      0,      0,      0,      0,
229cabdff1aSopenharmony_ci           0,      0,      0,      0,      0,      0,      0,      0 },
230cabdff1aSopenharmony_ci
231cabdff1aSopenharmony_ci    { -11831,  -7404,  -4010,  -1096,   1606,   4291,   7386,  11482,
232cabdff1aSopenharmony_ci           0,      0,      0,      0,      0,      0,      0,      0,
233cabdff1aSopenharmony_ci           0,      0,      0,      0,      0,      0,      0,      0,
234cabdff1aSopenharmony_ci           0,      0,      0,      0,      0,      0,      0,      0 },
235cabdff1aSopenharmony_ci
236cabdff1aSopenharmony_ci    { -13404,  -9250,  -5995,  -3312,   -890,   1594,   4464,   8198,
237cabdff1aSopenharmony_ci           0,      0,      0,      0,      0,      0,      0,      0,
238cabdff1aSopenharmony_ci           0,      0,      0,      0,      0,      0,      0,      0,
239cabdff1aSopenharmony_ci           0,      0,      0,      0,      0,      0,      0,      0 },
240cabdff1aSopenharmony_ci
241cabdff1aSopenharmony_ci    { -11239,  -7220,  -4040,  -1406,    971,   3321,   6006,   9697,
242cabdff1aSopenharmony_ci           0,      0,      0,      0,      0,      0,      0,      0,
243cabdff1aSopenharmony_ci           0,      0,      0,      0,      0,      0,      0,      0,
244cabdff1aSopenharmony_ci           0,      0,      0,      0,      0,      0,      0,      0 },
245cabdff1aSopenharmony_ci};
246cabdff1aSopenharmony_ci
247cabdff1aSopenharmony_cistatic const uint16_t  dss_sp_fixed_cb_gain[64] = {
248cabdff1aSopenharmony_ci       0,    4,    8,   13,   17,   22,   26,   31,
249cabdff1aSopenharmony_ci      35,   40,   44,   48,   53,   58,   63,   69,
250cabdff1aSopenharmony_ci      76,   83,   91,   99,  109,  119,  130,  142,
251cabdff1aSopenharmony_ci     155,  170,  185,  203,  222,  242,  265,  290,
252cabdff1aSopenharmony_ci     317,  346,  378,  414,  452,  494,  540,  591,
253cabdff1aSopenharmony_ci     646,  706,  771,  843,  922, 1007, 1101, 1204,
254cabdff1aSopenharmony_ci    1316, 1438, 1572, 1719, 1879, 2053, 2244, 2453,
255cabdff1aSopenharmony_ci    2682, 2931, 3204, 3502, 3828, 4184, 4574, 5000,
256cabdff1aSopenharmony_ci};
257cabdff1aSopenharmony_ci
258cabdff1aSopenharmony_cistatic const int16_t  dss_sp_pulse_val[8] = {
259cabdff1aSopenharmony_ci    -31182, -22273, -13364, -4455, 4455, 13364, 22273, 31182
260cabdff1aSopenharmony_ci};
261cabdff1aSopenharmony_ci
262cabdff1aSopenharmony_cistatic const uint16_t binary_decreasing_array[] = {
263cabdff1aSopenharmony_ci    32767, 16384, 8192, 4096, 2048, 1024, 512, 256,
264cabdff1aSopenharmony_ci    128, 64, 32, 16, 8, 4, 2,
265cabdff1aSopenharmony_ci};
266cabdff1aSopenharmony_ci
267cabdff1aSopenharmony_cistatic const uint16_t dss_sp_unc_decreasing_array[] = {
268cabdff1aSopenharmony_ci    32767, 26214, 20972, 16777, 13422, 10737, 8590, 6872,
269cabdff1aSopenharmony_ci    5498, 4398, 3518, 2815, 2252, 1801, 1441,
270cabdff1aSopenharmony_ci};
271cabdff1aSopenharmony_ci
272cabdff1aSopenharmony_cistatic const uint16_t dss_sp_adaptive_gain[] = {
273cabdff1aSopenharmony_ci     102,  231,  360,  488,  617,  746,  875, 1004,
274cabdff1aSopenharmony_ci    1133, 1261, 1390, 1519, 1648, 1777, 1905, 2034,
275cabdff1aSopenharmony_ci    2163, 2292, 2421, 2550, 2678, 2807, 2936, 3065,
276cabdff1aSopenharmony_ci    3194, 3323, 3451, 3580, 3709, 3838, 3967, 4096,
277cabdff1aSopenharmony_ci};
278cabdff1aSopenharmony_ci
279cabdff1aSopenharmony_cistatic const int32_t dss_sp_sinc[67] = {
280cabdff1aSopenharmony_ci      262,   293,   323,   348,   356,   336,   269,   139,
281cabdff1aSopenharmony_ci      -67,  -358,  -733, -1178, -1668, -2162, -2607, -2940,
282cabdff1aSopenharmony_ci    -3090, -2986, -2562, -1760,  -541,  1110,  3187,  5651,
283cabdff1aSopenharmony_ci     8435, 11446, 14568, 17670, 20611, 23251, 25460, 27125,
284cabdff1aSopenharmony_ci    28160, 28512, 28160,
285cabdff1aSopenharmony_ci    27125, 25460, 23251, 20611, 17670, 14568, 11446,  8435,
286cabdff1aSopenharmony_ci     5651,  3187,  1110,  -541, -1760, -2562, -2986, -3090,
287cabdff1aSopenharmony_ci    -2940, -2607, -2162, -1668, -1178,  -733,  -358,   -67,
288cabdff1aSopenharmony_ci      139,   269,   336,   356,   348,   323,   293,   262,
289cabdff1aSopenharmony_ci};
290cabdff1aSopenharmony_ci
291cabdff1aSopenharmony_cistatic av_cold int dss_sp_decode_init(AVCodecContext *avctx)
292cabdff1aSopenharmony_ci{
293cabdff1aSopenharmony_ci    DssSpContext *p = avctx->priv_data;
294cabdff1aSopenharmony_ci    avctx->sample_fmt     = AV_SAMPLE_FMT_S16;
295cabdff1aSopenharmony_ci    avctx->sample_rate    = 11025;
296cabdff1aSopenharmony_ci    av_channel_layout_uninit(&avctx->ch_layout);
297cabdff1aSopenharmony_ci    avctx->ch_layout      = (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO;
298cabdff1aSopenharmony_ci
299cabdff1aSopenharmony_ci    p->pulse_dec_mode = 1;
300cabdff1aSopenharmony_ci    p->avctx          = avctx;
301cabdff1aSopenharmony_ci
302cabdff1aSopenharmony_ci    return 0;
303cabdff1aSopenharmony_ci}
304cabdff1aSopenharmony_ci
305cabdff1aSopenharmony_cistatic void dss_sp_unpack_coeffs(DssSpContext *p, const uint8_t *src)
306cabdff1aSopenharmony_ci{
307cabdff1aSopenharmony_ci    GetBitContext gb;
308cabdff1aSopenharmony_ci    DssSpFrame *fparam = &p->fparam;
309cabdff1aSopenharmony_ci    int i;
310cabdff1aSopenharmony_ci    int subframe_idx;
311cabdff1aSopenharmony_ci    uint32_t combined_pitch;
312cabdff1aSopenharmony_ci    uint32_t tmp;
313cabdff1aSopenharmony_ci    uint32_t pitch_lag;
314cabdff1aSopenharmony_ci
315cabdff1aSopenharmony_ci    for (i = 0; i < DSS_SP_FRAME_SIZE; i += 2) {
316cabdff1aSopenharmony_ci        p->bits[i]     = src[i + 1];
317cabdff1aSopenharmony_ci        p->bits[i + 1] = src[i];
318cabdff1aSopenharmony_ci    }
319cabdff1aSopenharmony_ci
320cabdff1aSopenharmony_ci    init_get_bits(&gb, p->bits, DSS_SP_FRAME_SIZE * 8);
321cabdff1aSopenharmony_ci
322cabdff1aSopenharmony_ci    for (i = 0; i < 2; i++)
323cabdff1aSopenharmony_ci        fparam->filter_idx[i] = get_bits(&gb, 5);
324cabdff1aSopenharmony_ci    for (; i < 8; i++)
325cabdff1aSopenharmony_ci        fparam->filter_idx[i] = get_bits(&gb, 4);
326cabdff1aSopenharmony_ci    for (; i < 14; i++)
327cabdff1aSopenharmony_ci        fparam->filter_idx[i] = get_bits(&gb, 3);
328cabdff1aSopenharmony_ci
329cabdff1aSopenharmony_ci    for (subframe_idx = 0; subframe_idx < 4; subframe_idx++) {
330cabdff1aSopenharmony_ci        fparam->sf_adaptive_gain[subframe_idx] = get_bits(&gb, 5);
331cabdff1aSopenharmony_ci
332cabdff1aSopenharmony_ci        fparam->sf[subframe_idx].combined_pulse_pos = get_bits_long(&gb, 31);
333cabdff1aSopenharmony_ci
334cabdff1aSopenharmony_ci        fparam->sf[subframe_idx].gain = get_bits(&gb, 6);
335cabdff1aSopenharmony_ci
336cabdff1aSopenharmony_ci        for (i = 0; i < 7; i++)
337cabdff1aSopenharmony_ci            fparam->sf[subframe_idx].pulse_val[i] = get_bits(&gb, 3);
338cabdff1aSopenharmony_ci    }
339cabdff1aSopenharmony_ci
340cabdff1aSopenharmony_ci    for (subframe_idx = 0; subframe_idx < 4; subframe_idx++) {
341cabdff1aSopenharmony_ci        unsigned int C72_binomials[PULSE_MAX] = {
342cabdff1aSopenharmony_ci            72, 2556, 59640, 1028790, 13991544, 156238908, 1473109704,
343cabdff1aSopenharmony_ci            3379081753
344cabdff1aSopenharmony_ci        };
345cabdff1aSopenharmony_ci        unsigned int combined_pulse_pos =
346cabdff1aSopenharmony_ci            fparam->sf[subframe_idx].combined_pulse_pos;
347cabdff1aSopenharmony_ci        int index = 6;
348cabdff1aSopenharmony_ci
349cabdff1aSopenharmony_ci        if (combined_pulse_pos < C72_binomials[PULSE_MAX - 1]) {
350cabdff1aSopenharmony_ci            if (p->pulse_dec_mode) {
351cabdff1aSopenharmony_ci                int pulse, pulse_idx;
352cabdff1aSopenharmony_ci                pulse              = PULSE_MAX - 1;
353cabdff1aSopenharmony_ci                pulse_idx          = 71;
354cabdff1aSopenharmony_ci                combined_pulse_pos =
355cabdff1aSopenharmony_ci                    fparam->sf[subframe_idx].combined_pulse_pos;
356cabdff1aSopenharmony_ci
357cabdff1aSopenharmony_ci                /* this part seems to be close to g723.1 gen_fcb_excitation()
358cabdff1aSopenharmony_ci                 * RATE_6300 */
359cabdff1aSopenharmony_ci
360cabdff1aSopenharmony_ci                /* TODO: what is 7? size of subframe? */
361cabdff1aSopenharmony_ci                for (i = 0; i < 7; i++) {
362cabdff1aSopenharmony_ci                    for (;
363cabdff1aSopenharmony_ci                         combined_pulse_pos <
364cabdff1aSopenharmony_ci                         dss_sp_combinatorial_table[pulse][pulse_idx];
365cabdff1aSopenharmony_ci                         --pulse_idx)
366cabdff1aSopenharmony_ci                        ;
367cabdff1aSopenharmony_ci                    combined_pulse_pos -=
368cabdff1aSopenharmony_ci                        dss_sp_combinatorial_table[pulse][pulse_idx];
369cabdff1aSopenharmony_ci                    pulse--;
370cabdff1aSopenharmony_ci                    fparam->sf[subframe_idx].pulse_pos[i] = pulse_idx;
371cabdff1aSopenharmony_ci                }
372cabdff1aSopenharmony_ci            }
373cabdff1aSopenharmony_ci        } else {
374cabdff1aSopenharmony_ci            p->pulse_dec_mode = 0;
375cabdff1aSopenharmony_ci
376cabdff1aSopenharmony_ci            /* why do we need this? */
377cabdff1aSopenharmony_ci            fparam->sf[subframe_idx].pulse_pos[6] = 0;
378cabdff1aSopenharmony_ci
379cabdff1aSopenharmony_ci            for (i = 71; i >= 0; i--) {
380cabdff1aSopenharmony_ci                if (C72_binomials[index] <= combined_pulse_pos) {
381cabdff1aSopenharmony_ci                    combined_pulse_pos -= C72_binomials[index];
382cabdff1aSopenharmony_ci
383cabdff1aSopenharmony_ci                    fparam->sf[subframe_idx].pulse_pos[6 - index] = i;
384cabdff1aSopenharmony_ci
385cabdff1aSopenharmony_ci                    if (!index)
386cabdff1aSopenharmony_ci                        break;
387cabdff1aSopenharmony_ci                    --index;
388cabdff1aSopenharmony_ci                }
389cabdff1aSopenharmony_ci                --C72_binomials[0];
390cabdff1aSopenharmony_ci                if (index) {
391cabdff1aSopenharmony_ci                    int a;
392cabdff1aSopenharmony_ci                    for (a = 0; a < index; a++)
393cabdff1aSopenharmony_ci                        C72_binomials[a + 1] -= C72_binomials[a];
394cabdff1aSopenharmony_ci                }
395cabdff1aSopenharmony_ci            }
396cabdff1aSopenharmony_ci        }
397cabdff1aSopenharmony_ci    }
398cabdff1aSopenharmony_ci
399cabdff1aSopenharmony_ci    combined_pitch = get_bits(&gb, 24);
400cabdff1aSopenharmony_ci
401cabdff1aSopenharmony_ci    fparam->pitch_lag[0] = (combined_pitch % 151) + 36;
402cabdff1aSopenharmony_ci
403cabdff1aSopenharmony_ci    combined_pitch /= 151;
404cabdff1aSopenharmony_ci
405cabdff1aSopenharmony_ci    for (i = 1; i < SUBFRAMES - 1; i++) {
406cabdff1aSopenharmony_ci        fparam->pitch_lag[i] = combined_pitch % 48;
407cabdff1aSopenharmony_ci        combined_pitch      /= 48;
408cabdff1aSopenharmony_ci    }
409cabdff1aSopenharmony_ci    if (combined_pitch > 47) {
410cabdff1aSopenharmony_ci        av_log (p->avctx, AV_LOG_WARNING, "combined_pitch was too large\n");
411cabdff1aSopenharmony_ci        combined_pitch = 0;
412cabdff1aSopenharmony_ci    }
413cabdff1aSopenharmony_ci    fparam->pitch_lag[i] = combined_pitch;
414cabdff1aSopenharmony_ci
415cabdff1aSopenharmony_ci    pitch_lag = fparam->pitch_lag[0];
416cabdff1aSopenharmony_ci    for (i = 1; i < SUBFRAMES; i++) {
417cabdff1aSopenharmony_ci        if (pitch_lag > 162) {
418cabdff1aSopenharmony_ci            fparam->pitch_lag[i] += 162 - 23;
419cabdff1aSopenharmony_ci        } else {
420cabdff1aSopenharmony_ci            tmp = pitch_lag - 23;
421cabdff1aSopenharmony_ci            if (tmp < 36)
422cabdff1aSopenharmony_ci                tmp = 36;
423cabdff1aSopenharmony_ci            fparam->pitch_lag[i] += tmp;
424cabdff1aSopenharmony_ci        }
425cabdff1aSopenharmony_ci        pitch_lag = fparam->pitch_lag[i];
426cabdff1aSopenharmony_ci    }
427cabdff1aSopenharmony_ci}
428cabdff1aSopenharmony_ci
429cabdff1aSopenharmony_cistatic void dss_sp_unpack_filter(DssSpContext *p)
430cabdff1aSopenharmony_ci{
431cabdff1aSopenharmony_ci    int i;
432cabdff1aSopenharmony_ci
433cabdff1aSopenharmony_ci    for (i = 0; i < 14; i++)
434cabdff1aSopenharmony_ci        p->lpc_filter[i] = dss_sp_filter_cb[i][p->fparam.filter_idx[i]];
435cabdff1aSopenharmony_ci}
436cabdff1aSopenharmony_ci
437cabdff1aSopenharmony_cistatic void dss_sp_convert_coeffs(int32_t *lpc_filter, int32_t *coeffs)
438cabdff1aSopenharmony_ci{
439cabdff1aSopenharmony_ci    int a, a_plus, i;
440cabdff1aSopenharmony_ci
441cabdff1aSopenharmony_ci    coeffs[0] = 0x2000;
442cabdff1aSopenharmony_ci    for (a = 0; a < 14; a++) {
443cabdff1aSopenharmony_ci        a_plus         = a + 1;
444cabdff1aSopenharmony_ci        coeffs[a_plus] = lpc_filter[a] >> 2;
445cabdff1aSopenharmony_ci        if (a_plus / 2 >= 1) {
446cabdff1aSopenharmony_ci            for (i = 1; i <= a_plus / 2; i++) {
447cabdff1aSopenharmony_ci                int coeff_1, coeff_2, tmp;
448cabdff1aSopenharmony_ci
449cabdff1aSopenharmony_ci                coeff_1 = coeffs[i];
450cabdff1aSopenharmony_ci                coeff_2 = coeffs[a_plus - i];
451cabdff1aSopenharmony_ci
452cabdff1aSopenharmony_ci                tmp = DSS_SP_FORMULA(coeff_1, lpc_filter[a], coeff_2);
453cabdff1aSopenharmony_ci                coeffs[i] = av_clip_int16(tmp);
454cabdff1aSopenharmony_ci
455cabdff1aSopenharmony_ci                tmp = DSS_SP_FORMULA(coeff_2, lpc_filter[a], coeff_1);
456cabdff1aSopenharmony_ci                coeffs[a_plus - i] = av_clip_int16(tmp);
457cabdff1aSopenharmony_ci            }
458cabdff1aSopenharmony_ci        }
459cabdff1aSopenharmony_ci    }
460cabdff1aSopenharmony_ci}
461cabdff1aSopenharmony_ci
462cabdff1aSopenharmony_cistatic void dss_sp_add_pulses(int32_t *vector_buf,
463cabdff1aSopenharmony_ci                              const struct DssSpSubframe *sf)
464cabdff1aSopenharmony_ci{
465cabdff1aSopenharmony_ci    int i;
466cabdff1aSopenharmony_ci
467cabdff1aSopenharmony_ci    for (i = 0; i < 7; i++)
468cabdff1aSopenharmony_ci        vector_buf[sf->pulse_pos[i]] += (dss_sp_fixed_cb_gain[sf->gain] *
469cabdff1aSopenharmony_ci                                         dss_sp_pulse_val[sf->pulse_val[i]] +
470cabdff1aSopenharmony_ci                                         0x4000) >> 15;
471cabdff1aSopenharmony_ci}
472cabdff1aSopenharmony_ci
473cabdff1aSopenharmony_cistatic void dss_sp_gen_exc(int32_t *vector, int32_t *prev_exc,
474cabdff1aSopenharmony_ci                           int pitch_lag, int gain)
475cabdff1aSopenharmony_ci{
476cabdff1aSopenharmony_ci    int i;
477cabdff1aSopenharmony_ci
478cabdff1aSopenharmony_ci    /* do we actually need this check? we can use just [a3 - i % a3]
479cabdff1aSopenharmony_ci     * for both cases */
480cabdff1aSopenharmony_ci    if (pitch_lag < 72)
481cabdff1aSopenharmony_ci        for (i = 0; i < 72; i++)
482cabdff1aSopenharmony_ci            vector[i] = prev_exc[pitch_lag - i % pitch_lag];
483cabdff1aSopenharmony_ci    else
484cabdff1aSopenharmony_ci        for (i = 0; i < 72; i++)
485cabdff1aSopenharmony_ci            vector[i] = prev_exc[pitch_lag - i];
486cabdff1aSopenharmony_ci
487cabdff1aSopenharmony_ci    for (i = 0; i < 72; i++) {
488cabdff1aSopenharmony_ci        int tmp = gain * vector[i] >> 11;
489cabdff1aSopenharmony_ci        vector[i] = av_clip_int16(tmp);
490cabdff1aSopenharmony_ci    }
491cabdff1aSopenharmony_ci}
492cabdff1aSopenharmony_ci
493cabdff1aSopenharmony_cistatic void dss_sp_scale_vector(int32_t *vec, int bits, int size)
494cabdff1aSopenharmony_ci{
495cabdff1aSopenharmony_ci    int i;
496cabdff1aSopenharmony_ci
497cabdff1aSopenharmony_ci    if (bits < 0)
498cabdff1aSopenharmony_ci        for (i = 0; i < size; i++)
499cabdff1aSopenharmony_ci            vec[i] = vec[i] >> -bits;
500cabdff1aSopenharmony_ci    else
501cabdff1aSopenharmony_ci        for (i = 0; i < size; i++)
502cabdff1aSopenharmony_ci            vec[i] = vec[i] * (1 << bits);
503cabdff1aSopenharmony_ci}
504cabdff1aSopenharmony_ci
505cabdff1aSopenharmony_cistatic void dss_sp_update_buf(int32_t *hist, int32_t *vector)
506cabdff1aSopenharmony_ci{
507cabdff1aSopenharmony_ci    int i;
508cabdff1aSopenharmony_ci
509cabdff1aSopenharmony_ci    for (i = 114; i > 0; i--)
510cabdff1aSopenharmony_ci        vector[i + 72] = vector[i];
511cabdff1aSopenharmony_ci
512cabdff1aSopenharmony_ci    for (i = 0; i < 72; i++)
513cabdff1aSopenharmony_ci        vector[72 - i] = hist[i];
514cabdff1aSopenharmony_ci}
515cabdff1aSopenharmony_ci
516cabdff1aSopenharmony_cistatic void dss_sp_shift_sq_sub(const int32_t *filter_buf,
517cabdff1aSopenharmony_ci                                int32_t *error_buf, int32_t *dst)
518cabdff1aSopenharmony_ci{
519cabdff1aSopenharmony_ci    int a;
520cabdff1aSopenharmony_ci
521cabdff1aSopenharmony_ci    for (a = 0; a < 72; a++) {
522cabdff1aSopenharmony_ci        int i, tmp;
523cabdff1aSopenharmony_ci
524cabdff1aSopenharmony_ci        tmp = dst[a] * filter_buf[0];
525cabdff1aSopenharmony_ci
526cabdff1aSopenharmony_ci        for (i = 14; i > 0; i--)
527cabdff1aSopenharmony_ci            tmp -= error_buf[i] * (unsigned)filter_buf[i];
528cabdff1aSopenharmony_ci
529cabdff1aSopenharmony_ci        for (i = 14; i > 0; i--)
530cabdff1aSopenharmony_ci            error_buf[i] = error_buf[i - 1];
531cabdff1aSopenharmony_ci
532cabdff1aSopenharmony_ci        tmp = (int)(tmp + 4096U) >> 13;
533cabdff1aSopenharmony_ci
534cabdff1aSopenharmony_ci        error_buf[1] = tmp;
535cabdff1aSopenharmony_ci
536cabdff1aSopenharmony_ci        dst[a] = av_clip_int16(tmp);
537cabdff1aSopenharmony_ci    }
538cabdff1aSopenharmony_ci}
539cabdff1aSopenharmony_ci
540cabdff1aSopenharmony_cistatic void dss_sp_shift_sq_add(const int32_t *filter_buf, int32_t *audio_buf,
541cabdff1aSopenharmony_ci                                int32_t *dst)
542cabdff1aSopenharmony_ci{
543cabdff1aSopenharmony_ci    int a;
544cabdff1aSopenharmony_ci
545cabdff1aSopenharmony_ci    for (a = 0; a < 72; a++) {
546cabdff1aSopenharmony_ci        int i, tmp = 0;
547cabdff1aSopenharmony_ci
548cabdff1aSopenharmony_ci        audio_buf[0] = dst[a];
549cabdff1aSopenharmony_ci
550cabdff1aSopenharmony_ci        for (i = 14; i >= 0; i--)
551cabdff1aSopenharmony_ci            tmp += audio_buf[i] * filter_buf[i];
552cabdff1aSopenharmony_ci
553cabdff1aSopenharmony_ci        for (i = 14; i > 0; i--)
554cabdff1aSopenharmony_ci            audio_buf[i] = audio_buf[i - 1];
555cabdff1aSopenharmony_ci
556cabdff1aSopenharmony_ci        tmp = (tmp + 4096) >> 13;
557cabdff1aSopenharmony_ci
558cabdff1aSopenharmony_ci        dst[a] = av_clip_int16(tmp);
559cabdff1aSopenharmony_ci    }
560cabdff1aSopenharmony_ci}
561cabdff1aSopenharmony_ci
562cabdff1aSopenharmony_cistatic void dss_sp_vec_mult(const int32_t *src, int32_t *dst,
563cabdff1aSopenharmony_ci                            const int16_t *mult)
564cabdff1aSopenharmony_ci{
565cabdff1aSopenharmony_ci    int i;
566cabdff1aSopenharmony_ci
567cabdff1aSopenharmony_ci    dst[0] = src[0];
568cabdff1aSopenharmony_ci
569cabdff1aSopenharmony_ci    for (i = 1; i < 15; i++)
570cabdff1aSopenharmony_ci        dst[i] = (src[i] * mult[i] + 0x4000) >> 15;
571cabdff1aSopenharmony_ci}
572cabdff1aSopenharmony_ci
573cabdff1aSopenharmony_cistatic int dss_sp_get_normalize_bits(int32_t *vector_buf, int16_t size)
574cabdff1aSopenharmony_ci{
575cabdff1aSopenharmony_ci    unsigned int val;
576cabdff1aSopenharmony_ci    int max_val;
577cabdff1aSopenharmony_ci    int i;
578cabdff1aSopenharmony_ci
579cabdff1aSopenharmony_ci    val = 1;
580cabdff1aSopenharmony_ci    for (i = 0; i < size; i++)
581cabdff1aSopenharmony_ci        val |= FFABS(vector_buf[i]);
582cabdff1aSopenharmony_ci
583cabdff1aSopenharmony_ci    for (max_val = 0; val <= 0x4000; ++max_val)
584cabdff1aSopenharmony_ci        val *= 2;
585cabdff1aSopenharmony_ci    return max_val;
586cabdff1aSopenharmony_ci}
587cabdff1aSopenharmony_ci
588cabdff1aSopenharmony_cistatic int dss_sp_vector_sum(DssSpContext *p, int size)
589cabdff1aSopenharmony_ci{
590cabdff1aSopenharmony_ci    int i, sum = 0;
591cabdff1aSopenharmony_ci    for (i = 0; i < size; i++)
592cabdff1aSopenharmony_ci        sum += FFABS(p->vector_buf[i]);
593cabdff1aSopenharmony_ci    return sum;
594cabdff1aSopenharmony_ci}
595cabdff1aSopenharmony_ci
596cabdff1aSopenharmony_cistatic void dss_sp_sf_synthesis(DssSpContext *p, int32_t lpc_filter,
597cabdff1aSopenharmony_ci                                int32_t *dst, int size)
598cabdff1aSopenharmony_ci{
599cabdff1aSopenharmony_ci    int32_t tmp_buf[15];
600cabdff1aSopenharmony_ci    int32_t noise[72];
601cabdff1aSopenharmony_ci    int bias, vsum_2 = 0, vsum_1 = 0, v36, normalize_bits;
602cabdff1aSopenharmony_ci    int i, tmp;
603cabdff1aSopenharmony_ci
604cabdff1aSopenharmony_ci    if (size > 0) {
605cabdff1aSopenharmony_ci        vsum_1 = dss_sp_vector_sum(p, size);
606cabdff1aSopenharmony_ci
607cabdff1aSopenharmony_ci        if (vsum_1 > 0xFFFFF)
608cabdff1aSopenharmony_ci            vsum_1 = 0xFFFFF;
609cabdff1aSopenharmony_ci    }
610cabdff1aSopenharmony_ci
611cabdff1aSopenharmony_ci    normalize_bits = dss_sp_get_normalize_bits(p->vector_buf, size);
612cabdff1aSopenharmony_ci
613cabdff1aSopenharmony_ci    dss_sp_scale_vector(p->vector_buf, normalize_bits - 3, size);
614cabdff1aSopenharmony_ci    dss_sp_scale_vector(p->audio_buf, normalize_bits, 15);
615cabdff1aSopenharmony_ci    dss_sp_scale_vector(p->err_buf1, normalize_bits, 15);
616cabdff1aSopenharmony_ci
617cabdff1aSopenharmony_ci    v36 = p->err_buf1[1];
618cabdff1aSopenharmony_ci
619cabdff1aSopenharmony_ci    dss_sp_vec_mult(p->filter, tmp_buf, binary_decreasing_array);
620cabdff1aSopenharmony_ci    dss_sp_shift_sq_add(tmp_buf, p->audio_buf, p->vector_buf);
621cabdff1aSopenharmony_ci
622cabdff1aSopenharmony_ci    dss_sp_vec_mult(p->filter, tmp_buf, dss_sp_unc_decreasing_array);
623cabdff1aSopenharmony_ci    dss_sp_shift_sq_sub(tmp_buf, p->err_buf1, p->vector_buf);
624cabdff1aSopenharmony_ci
625cabdff1aSopenharmony_ci    /* lpc_filter can be negative */
626cabdff1aSopenharmony_ci    lpc_filter = lpc_filter >> 1;
627cabdff1aSopenharmony_ci    if (lpc_filter >= 0)
628cabdff1aSopenharmony_ci        lpc_filter = 0;
629cabdff1aSopenharmony_ci
630cabdff1aSopenharmony_ci    if (size > 1) {
631cabdff1aSopenharmony_ci        for (i = size - 1; i > 0; i--) {
632cabdff1aSopenharmony_ci            tmp = DSS_SP_FORMULA(p->vector_buf[i], lpc_filter,
633cabdff1aSopenharmony_ci                                 p->vector_buf[i - 1]);
634cabdff1aSopenharmony_ci            p->vector_buf[i] = av_clip_int16(tmp);
635cabdff1aSopenharmony_ci        }
636cabdff1aSopenharmony_ci    }
637cabdff1aSopenharmony_ci
638cabdff1aSopenharmony_ci    tmp              = DSS_SP_FORMULA(p->vector_buf[0], lpc_filter, v36);
639cabdff1aSopenharmony_ci    p->vector_buf[0] = av_clip_int16(tmp);
640cabdff1aSopenharmony_ci
641cabdff1aSopenharmony_ci    dss_sp_scale_vector(p->vector_buf, -normalize_bits, size);
642cabdff1aSopenharmony_ci    dss_sp_scale_vector(p->audio_buf, -normalize_bits, 15);
643cabdff1aSopenharmony_ci    dss_sp_scale_vector(p->err_buf1, -normalize_bits, 15);
644cabdff1aSopenharmony_ci
645cabdff1aSopenharmony_ci    if (size > 0)
646cabdff1aSopenharmony_ci        vsum_2 = dss_sp_vector_sum(p, size);
647cabdff1aSopenharmony_ci
648cabdff1aSopenharmony_ci    if (vsum_2 >= 0x40)
649cabdff1aSopenharmony_ci        tmp = (vsum_1 << 11) / vsum_2;
650cabdff1aSopenharmony_ci    else
651cabdff1aSopenharmony_ci        tmp = 1;
652cabdff1aSopenharmony_ci
653cabdff1aSopenharmony_ci    bias     = 409 * tmp >> 15 << 15;
654cabdff1aSopenharmony_ci    tmp      = (bias + 32358 * p->noise_state) >> 15;
655cabdff1aSopenharmony_ci    noise[0] = av_clip_int16(tmp);
656cabdff1aSopenharmony_ci
657cabdff1aSopenharmony_ci    for (i = 1; i < size; i++) {
658cabdff1aSopenharmony_ci        tmp      = (bias + 32358 * noise[i - 1]) >> 15;
659cabdff1aSopenharmony_ci        noise[i] = av_clip_int16(tmp);
660cabdff1aSopenharmony_ci    }
661cabdff1aSopenharmony_ci
662cabdff1aSopenharmony_ci    p->noise_state = noise[size - 1];
663cabdff1aSopenharmony_ci    for (i = 0; i < size; i++) {
664cabdff1aSopenharmony_ci        tmp    = (p->vector_buf[i] * noise[i]) >> 11;
665cabdff1aSopenharmony_ci        dst[i] = av_clip_int16(tmp);
666cabdff1aSopenharmony_ci    }
667cabdff1aSopenharmony_ci}
668cabdff1aSopenharmony_ci
669cabdff1aSopenharmony_cistatic void dss_sp_update_state(DssSpContext *p, int32_t *dst)
670cabdff1aSopenharmony_ci{
671cabdff1aSopenharmony_ci    int i, offset = 6, counter = 0, a = 0;
672cabdff1aSopenharmony_ci
673cabdff1aSopenharmony_ci    for (i = 0; i < 6; i++)
674cabdff1aSopenharmony_ci        p->excitation[i] = p->excitation[288 + i];
675cabdff1aSopenharmony_ci
676cabdff1aSopenharmony_ci    for (i = 0; i < 72 * SUBFRAMES; i++)
677cabdff1aSopenharmony_ci        p->excitation[6 + i] = dst[i];
678cabdff1aSopenharmony_ci
679cabdff1aSopenharmony_ci    do {
680cabdff1aSopenharmony_ci        int tmp = 0;
681cabdff1aSopenharmony_ci
682cabdff1aSopenharmony_ci        for (i = 0; i < 6; i++)
683cabdff1aSopenharmony_ci            tmp += p->excitation[offset--] * dss_sp_sinc[a + i * 11];
684cabdff1aSopenharmony_ci
685cabdff1aSopenharmony_ci        offset += 7;
686cabdff1aSopenharmony_ci
687cabdff1aSopenharmony_ci        tmp >>= 15;
688cabdff1aSopenharmony_ci        dst[counter] = av_clip_int16(tmp);
689cabdff1aSopenharmony_ci
690cabdff1aSopenharmony_ci        counter++;
691cabdff1aSopenharmony_ci
692cabdff1aSopenharmony_ci        a = (a + 1) % 11;
693cabdff1aSopenharmony_ci        if (!a)
694cabdff1aSopenharmony_ci            offset++;
695cabdff1aSopenharmony_ci    } while (offset < FF_ARRAY_ELEMS(p->excitation));
696cabdff1aSopenharmony_ci}
697cabdff1aSopenharmony_ci
698cabdff1aSopenharmony_cistatic void dss_sp_32to16bit(int16_t *dst, int32_t *src, int size)
699cabdff1aSopenharmony_ci{
700cabdff1aSopenharmony_ci    int i;
701cabdff1aSopenharmony_ci
702cabdff1aSopenharmony_ci    for (i = 0; i < size; i++)
703cabdff1aSopenharmony_ci        dst[i] = av_clip_int16(src[i]);
704cabdff1aSopenharmony_ci}
705cabdff1aSopenharmony_ci
706cabdff1aSopenharmony_cistatic int dss_sp_decode_one_frame(DssSpContext *p,
707cabdff1aSopenharmony_ci                                   int16_t *abuf_dst, const uint8_t *abuf_src)
708cabdff1aSopenharmony_ci{
709cabdff1aSopenharmony_ci    int i, j;
710cabdff1aSopenharmony_ci
711cabdff1aSopenharmony_ci    dss_sp_unpack_coeffs(p, abuf_src);
712cabdff1aSopenharmony_ci
713cabdff1aSopenharmony_ci    dss_sp_unpack_filter(p);
714cabdff1aSopenharmony_ci
715cabdff1aSopenharmony_ci    dss_sp_convert_coeffs(p->lpc_filter, p->filter);
716cabdff1aSopenharmony_ci
717cabdff1aSopenharmony_ci    for (j = 0; j < SUBFRAMES; j++) {
718cabdff1aSopenharmony_ci        dss_sp_gen_exc(p->vector_buf, p->history,
719cabdff1aSopenharmony_ci                       p->fparam.pitch_lag[j],
720cabdff1aSopenharmony_ci                       dss_sp_adaptive_gain[p->fparam.sf_adaptive_gain[j]]);
721cabdff1aSopenharmony_ci
722cabdff1aSopenharmony_ci        dss_sp_add_pulses(p->vector_buf, &p->fparam.sf[j]);
723cabdff1aSopenharmony_ci
724cabdff1aSopenharmony_ci        dss_sp_update_buf(p->vector_buf, p->history);
725cabdff1aSopenharmony_ci
726cabdff1aSopenharmony_ci        for (i = 0; i < 72; i++)
727cabdff1aSopenharmony_ci            p->vector_buf[i] = p->history[72 - i];
728cabdff1aSopenharmony_ci
729cabdff1aSopenharmony_ci        dss_sp_shift_sq_sub(p->filter,
730cabdff1aSopenharmony_ci                            p->err_buf2, p->vector_buf);
731cabdff1aSopenharmony_ci
732cabdff1aSopenharmony_ci        dss_sp_sf_synthesis(p, p->lpc_filter[0],
733cabdff1aSopenharmony_ci                            &p->working_buffer[j][0], 72);
734cabdff1aSopenharmony_ci    }
735cabdff1aSopenharmony_ci
736cabdff1aSopenharmony_ci    dss_sp_update_state(p, &p->working_buffer[0][0]);
737cabdff1aSopenharmony_ci
738cabdff1aSopenharmony_ci    dss_sp_32to16bit(abuf_dst,
739cabdff1aSopenharmony_ci                     &p->working_buffer[0][0], 264);
740cabdff1aSopenharmony_ci    return 0;
741cabdff1aSopenharmony_ci}
742cabdff1aSopenharmony_ci
743cabdff1aSopenharmony_cistatic int dss_sp_decode_frame(AVCodecContext *avctx, AVFrame *frame,
744cabdff1aSopenharmony_ci                               int *got_frame_ptr, AVPacket *avpkt)
745cabdff1aSopenharmony_ci{
746cabdff1aSopenharmony_ci    DssSpContext *p    = avctx->priv_data;
747cabdff1aSopenharmony_ci    const uint8_t *buf = avpkt->data;
748cabdff1aSopenharmony_ci    int buf_size       = avpkt->size;
749cabdff1aSopenharmony_ci
750cabdff1aSopenharmony_ci    int16_t *out;
751cabdff1aSopenharmony_ci    int ret;
752cabdff1aSopenharmony_ci
753cabdff1aSopenharmony_ci    if (buf_size < DSS_SP_FRAME_SIZE) {
754cabdff1aSopenharmony_ci        if (buf_size)
755cabdff1aSopenharmony_ci            av_log(avctx, AV_LOG_WARNING,
756cabdff1aSopenharmony_ci                   "Expected %d bytes, got %d - skipping packet.\n",
757cabdff1aSopenharmony_ci                   DSS_SP_FRAME_SIZE, buf_size);
758cabdff1aSopenharmony_ci        *got_frame_ptr = 0;
759cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
760cabdff1aSopenharmony_ci    }
761cabdff1aSopenharmony_ci
762cabdff1aSopenharmony_ci    frame->nb_samples = DSS_SP_SAMPLE_COUNT;
763cabdff1aSopenharmony_ci    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
764cabdff1aSopenharmony_ci        return ret;
765cabdff1aSopenharmony_ci
766cabdff1aSopenharmony_ci    out = (int16_t *)frame->data[0];
767cabdff1aSopenharmony_ci
768cabdff1aSopenharmony_ci    dss_sp_decode_one_frame(p, out, buf);
769cabdff1aSopenharmony_ci
770cabdff1aSopenharmony_ci    *got_frame_ptr = 1;
771cabdff1aSopenharmony_ci
772cabdff1aSopenharmony_ci    return DSS_SP_FRAME_SIZE;
773cabdff1aSopenharmony_ci}
774cabdff1aSopenharmony_ci
775cabdff1aSopenharmony_ciconst FFCodec ff_dss_sp_decoder = {
776cabdff1aSopenharmony_ci    .p.name         = "dss_sp",
777cabdff1aSopenharmony_ci    .p.long_name    = NULL_IF_CONFIG_SMALL("Digital Speech Standard - Standard Play mode (DSS SP)"),
778cabdff1aSopenharmony_ci    .p.type         = AVMEDIA_TYPE_AUDIO,
779cabdff1aSopenharmony_ci    .p.id           = AV_CODEC_ID_DSS_SP,
780cabdff1aSopenharmony_ci    .priv_data_size = sizeof(DssSpContext),
781cabdff1aSopenharmony_ci    .init           = dss_sp_decode_init,
782cabdff1aSopenharmony_ci    FF_CODEC_DECODE_CB(dss_sp_decode_frame),
783cabdff1aSopenharmony_ci    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
784cabdff1aSopenharmony_ci    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
785cabdff1aSopenharmony_ci};
786