xref: /btstack/3rd-party/lc3-google/src/spec.c (revision 4930cef6e21e6da2d7571b9259c7f0fb8bed3d01)
19a19cd78SMatthias Ringwald /******************************************************************************
29a19cd78SMatthias Ringwald  *
3*4930cef6SMatthias Ringwald  *  Copyright 2022 Google LLC
49a19cd78SMatthias Ringwald  *
59a19cd78SMatthias Ringwald  *  Licensed under the Apache License, Version 2.0 (the "License");
69a19cd78SMatthias Ringwald  *  you may not use this file except in compliance with the License.
79a19cd78SMatthias Ringwald  *  You may obtain a copy of the License at:
89a19cd78SMatthias Ringwald  *
99a19cd78SMatthias Ringwald  *  http://www.apache.org/licenses/LICENSE-2.0
109a19cd78SMatthias Ringwald  *
119a19cd78SMatthias Ringwald  *  Unless required by applicable law or agreed to in writing, software
129a19cd78SMatthias Ringwald  *  distributed under the License is distributed on an "AS IS" BASIS,
139a19cd78SMatthias Ringwald  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
149a19cd78SMatthias Ringwald  *  See the License for the specific language governing permissions and
159a19cd78SMatthias Ringwald  *  limitations under the License.
169a19cd78SMatthias Ringwald  *
179a19cd78SMatthias Ringwald  ******************************************************************************/
189a19cd78SMatthias Ringwald 
199a19cd78SMatthias Ringwald #include "spec.h"
209a19cd78SMatthias Ringwald #include "bits.h"
219a19cd78SMatthias Ringwald #include "tables.h"
229a19cd78SMatthias Ringwald 
239a19cd78SMatthias Ringwald 
249a19cd78SMatthias Ringwald /* ----------------------------------------------------------------------------
259a19cd78SMatthias Ringwald  *  Global Gain / Quantization
269a19cd78SMatthias Ringwald  * -------------------------------------------------------------------------- */
279a19cd78SMatthias Ringwald 
289a19cd78SMatthias Ringwald /**
299a19cd78SMatthias Ringwald  * Resolve quantized gain index offset
309a19cd78SMatthias Ringwald  * sr, nbytes      Samplerate and size of the frame
319a19cd78SMatthias Ringwald  * return          Gain index offset
329a19cd78SMatthias Ringwald  */
339a19cd78SMatthias Ringwald static int resolve_gain_offset(enum lc3_srate sr, int nbytes)
349a19cd78SMatthias Ringwald {
359a19cd78SMatthias Ringwald     int g_off = (nbytes * 8) / (10 * (1 + sr));
369a19cd78SMatthias Ringwald     return 105 + 5*(1 + sr) + LC3_MIN(g_off, 115);
379a19cd78SMatthias Ringwald }
389a19cd78SMatthias Ringwald 
399a19cd78SMatthias Ringwald /**
409a19cd78SMatthias Ringwald  * Global Gain Estimation
419a19cd78SMatthias Ringwald  * dt, sr          Duration and samplerate of the frame
429a19cd78SMatthias Ringwald  * x               Spectral coefficients
439a19cd78SMatthias Ringwald  * nbits_budget    Number of bits available coding the spectrum
449a19cd78SMatthias Ringwald  * nbits_off       Offset on the available bits, temporarily smoothed
459a19cd78SMatthias Ringwald  * g_off           Gain index offset
469a19cd78SMatthias Ringwald  * reset_off       Return True when the nbits_off must be reset
479a19cd78SMatthias Ringwald  * return          The quantized gain value
489a19cd78SMatthias Ringwald  */
49*4930cef6SMatthias Ringwald LC3_HOT static int estimate_gain(
509a19cd78SMatthias Ringwald     enum lc3_dt dt, enum lc3_srate sr, const float *x,
519a19cd78SMatthias Ringwald     int nbits_budget, float nbits_off, int g_off, bool *reset_off)
529a19cd78SMatthias Ringwald {
539a19cd78SMatthias Ringwald     int ne = LC3_NE(dt, sr) >> 2;
54*4930cef6SMatthias Ringwald     int e[ne];
559a19cd78SMatthias Ringwald 
56*4930cef6SMatthias Ringwald     /* --- Energy (dB) by 4 MDCT blocks --- */
579a19cd78SMatthias Ringwald 
58*4930cef6SMatthias Ringwald     float x2_max = 0;
599a19cd78SMatthias Ringwald 
609a19cd78SMatthias Ringwald     for (int i = 0; i < ne; i++, x += 4) {
61*4930cef6SMatthias Ringwald         float x0 = x[0] * x[0];
62*4930cef6SMatthias Ringwald         float x1 = x[1] * x[1];
63*4930cef6SMatthias Ringwald         float x2 = x[2] * x[2];
64*4930cef6SMatthias Ringwald         float x3 = x[3] * x[3];
659a19cd78SMatthias Ringwald 
66*4930cef6SMatthias Ringwald         x2_max = fmaxf(x2_max, x0);
67*4930cef6SMatthias Ringwald         x2_max = fmaxf(x2_max, x1);
68*4930cef6SMatthias Ringwald         x2_max = fmaxf(x2_max, x2);
69*4930cef6SMatthias Ringwald         x2_max = fmaxf(x2_max, x3);
709a19cd78SMatthias Ringwald 
71*4930cef6SMatthias Ringwald         e[i] = fast_db_q16(fmaxf(x0 + x1 + x2 + x3, 1e-10f));
729a19cd78SMatthias Ringwald     }
739a19cd78SMatthias Ringwald 
749a19cd78SMatthias Ringwald     /* --- Determine gain index --- */
759a19cd78SMatthias Ringwald 
769a19cd78SMatthias Ringwald     int nbits = nbits_budget + nbits_off + 0.5f;
779a19cd78SMatthias Ringwald     int g_int = 255 - g_off;
789a19cd78SMatthias Ringwald 
79*4930cef6SMatthias Ringwald     const int k_20_28 = 20.f/28 * 0x1p16f + 0.5f;
80*4930cef6SMatthias Ringwald     const int k_2u7 = 2.7f * 0x1p16f + 0.5f;
81*4930cef6SMatthias Ringwald     const int k_1u4 = 1.4f * 0x1p16f + 0.5f;
829a19cd78SMatthias Ringwald 
83*4930cef6SMatthias Ringwald     for (int i = 128, j, j0 = ne-1, j1 ; i > 0; i >>= 1) {
84*4930cef6SMatthias Ringwald         int gn = (g_int - i) * k_20_28;
85*4930cef6SMatthias Ringwald         int v = 0;
869a19cd78SMatthias Ringwald 
87*4930cef6SMatthias Ringwald         for (j = j0; j >= 0 && e[j] < gn; j--);
889a19cd78SMatthias Ringwald 
89*4930cef6SMatthias Ringwald         for (j1 = j; j >= 0; j--) {
90*4930cef6SMatthias Ringwald             int e_diff = e[j] - gn;
919a19cd78SMatthias Ringwald 
92*4930cef6SMatthias Ringwald             v += e_diff < 0 ? k_2u7 :
93*4930cef6SMatthias Ringwald                  e_diff < 43 << 16 ?   e_diff + ( 7 << 16)
94*4930cef6SMatthias Ringwald                                    : 2*e_diff - (36 << 16);
959a19cd78SMatthias Ringwald         }
969a19cd78SMatthias Ringwald 
97*4930cef6SMatthias Ringwald         if (v > nbits * k_1u4)
98*4930cef6SMatthias Ringwald             j0 = j1;
99*4930cef6SMatthias Ringwald         else
100*4930cef6SMatthias Ringwald             g_int = g_int - i;
1019a19cd78SMatthias Ringwald     }
1029a19cd78SMatthias Ringwald 
1039a19cd78SMatthias Ringwald     /* --- Limit gain index --- */
1049a19cd78SMatthias Ringwald 
105*4930cef6SMatthias Ringwald     int g_min = x2_max == 0 ? -g_off :
106*4930cef6SMatthias Ringwald         ceilf(28 * log10f(sqrtf(x2_max) / (32768 - 0.375f)));
1079a19cd78SMatthias Ringwald 
108*4930cef6SMatthias Ringwald     *reset_off = g_int < g_min || x2_max == 0;
1099a19cd78SMatthias Ringwald     if (*reset_off)
1109a19cd78SMatthias Ringwald         g_int = g_min;
1119a19cd78SMatthias Ringwald 
1129a19cd78SMatthias Ringwald     return g_int;
1139a19cd78SMatthias Ringwald }
1149a19cd78SMatthias Ringwald 
1159a19cd78SMatthias Ringwald /**
1169a19cd78SMatthias Ringwald  * Global Gain Adjustment
1179a19cd78SMatthias Ringwald  * sr              Samplerate of the frame
1189a19cd78SMatthias Ringwald  * g_idx           The estimated quantized gain index
1199a19cd78SMatthias Ringwald  * nbits           Computed number of bits coding the spectrum
1209a19cd78SMatthias Ringwald  * nbits_budget    Number of bits available for coding the spectrum
1219a19cd78SMatthias Ringwald  * return          Gain adjust value (-1 to 2)
1229a19cd78SMatthias Ringwald  */
123*4930cef6SMatthias Ringwald LC3_HOT static int adjust_gain(
124*4930cef6SMatthias Ringwald     enum lc3_srate sr, int g_idx, int nbits, int nbits_budget)
1259a19cd78SMatthias Ringwald {
1269a19cd78SMatthias Ringwald     /* --- Compute delta threshold --- */
1279a19cd78SMatthias Ringwald 
1289a19cd78SMatthias Ringwald     const int *t = (const int [LC3_NUM_SRATE][3]){
1299a19cd78SMatthias Ringwald         {  80,  500,  850 }, { 230, 1025, 1700 }, { 380, 1550, 2550 },
1309a19cd78SMatthias Ringwald         { 530, 2075, 3400 }, { 680, 2600, 4250 }
1319a19cd78SMatthias Ringwald     }[sr];
1329a19cd78SMatthias Ringwald 
1339a19cd78SMatthias Ringwald     int delta, den = 48;
1349a19cd78SMatthias Ringwald 
1359a19cd78SMatthias Ringwald     if (nbits < t[0]) {
1369a19cd78SMatthias Ringwald         delta = 3*(nbits + 48);
1379a19cd78SMatthias Ringwald 
1389a19cd78SMatthias Ringwald     } else if (nbits < t[1]) {
1399a19cd78SMatthias Ringwald         int n0 = 3*(t[0] + 48), range = t[1] - t[0];
1409a19cd78SMatthias Ringwald         delta = n0 * range + (nbits - t[0]) * (t[1] - n0);
1419a19cd78SMatthias Ringwald         den *= range;
1429a19cd78SMatthias Ringwald 
1439a19cd78SMatthias Ringwald     } else {
1449a19cd78SMatthias Ringwald         delta = LC3_MIN(nbits, t[2]);
1459a19cd78SMatthias Ringwald     }
1469a19cd78SMatthias Ringwald 
1479a19cd78SMatthias Ringwald     delta = (delta + den/2) / den;
1489a19cd78SMatthias Ringwald 
1499a19cd78SMatthias Ringwald     /* --- Adjust gain --- */
1509a19cd78SMatthias Ringwald 
1519a19cd78SMatthias Ringwald     if (nbits < nbits_budget - (delta + 2))
1529a19cd78SMatthias Ringwald         return -(g_idx > 0);
1539a19cd78SMatthias Ringwald 
1549a19cd78SMatthias Ringwald     if (nbits > nbits_budget)
1559a19cd78SMatthias Ringwald         return (g_idx < 255) + (g_idx < 254 && nbits >= nbits_budget + delta);
1569a19cd78SMatthias Ringwald 
1579a19cd78SMatthias Ringwald     return 0;
1589a19cd78SMatthias Ringwald }
1599a19cd78SMatthias Ringwald 
1609a19cd78SMatthias Ringwald /**
1619a19cd78SMatthias Ringwald  * Unquantize gain
1629a19cd78SMatthias Ringwald  * g_int           Quantization gain value
1639a19cd78SMatthias Ringwald  * return          Unquantized gain value
1649a19cd78SMatthias Ringwald  */
1659a19cd78SMatthias Ringwald static float unquantize_gain(int g_int)
1669a19cd78SMatthias Ringwald {
1679a19cd78SMatthias Ringwald     /* Unquantization gain table :
1689a19cd78SMatthias Ringwald      * G[i] = 10 ^ (i / 28) , i = [0..64] */
1699a19cd78SMatthias Ringwald 
1709a19cd78SMatthias Ringwald     static const float iq_table[] = {
1719a19cd78SMatthias Ringwald         1.00000000e+00, 1.08571112e+00, 1.17876863e+00, 1.27980221e+00,
1729a19cd78SMatthias Ringwald         1.38949549e+00, 1.50859071e+00, 1.63789371e+00, 1.77827941e+00,
1739a19cd78SMatthias Ringwald         1.93069773e+00, 2.09617999e+00, 2.27584593e+00, 2.47091123e+00,
1749a19cd78SMatthias Ringwald         2.68269580e+00, 2.91263265e+00, 3.16227766e+00, 3.43332002e+00,
1759a19cd78SMatthias Ringwald         3.72759372e+00, 4.04708995e+00, 4.39397056e+00, 4.77058270e+00,
1769a19cd78SMatthias Ringwald         5.17947468e+00, 5.62341325e+00, 6.10540230e+00, 6.62870316e+00,
1779a19cd78SMatthias Ringwald         7.19685673e+00, 7.81370738e+00, 8.48342898e+00, 9.21055318e+00,
1789a19cd78SMatthias Ringwald         1.00000000e+01, 1.08571112e+01, 1.17876863e+01, 1.27980221e+01,
1799a19cd78SMatthias Ringwald         1.38949549e+01, 1.50859071e+01, 1.63789371e+01, 1.77827941e+01,
1809a19cd78SMatthias Ringwald         1.93069773e+01, 2.09617999e+01, 2.27584593e+01, 2.47091123e+01,
1819a19cd78SMatthias Ringwald         2.68269580e+01, 2.91263265e+01, 3.16227766e+01, 3.43332002e+01,
1829a19cd78SMatthias Ringwald         3.72759372e+01, 4.04708995e+01, 4.39397056e+01, 4.77058270e+01,
1839a19cd78SMatthias Ringwald         5.17947468e+01, 5.62341325e+01, 6.10540230e+01, 6.62870316e+01,
1849a19cd78SMatthias Ringwald         7.19685673e+01, 7.81370738e+01, 8.48342898e+01, 9.21055318e+01,
1859a19cd78SMatthias Ringwald         1.00000000e+02, 1.08571112e+02, 1.17876863e+02, 1.27980221e+02,
1869a19cd78SMatthias Ringwald         1.38949549e+02, 1.50859071e+02, 1.63789371e+02, 1.77827941e+02,
1879a19cd78SMatthias Ringwald         1.93069773e+02
1889a19cd78SMatthias Ringwald     };
1899a19cd78SMatthias Ringwald 
1909a19cd78SMatthias Ringwald     float g = iq_table[LC3_ABS(g_int) & 0x3f];
1919a19cd78SMatthias Ringwald     for(int n64 = LC3_ABS(g_int) >> 6; n64--; )
1929a19cd78SMatthias Ringwald         g *= iq_table[64];
1939a19cd78SMatthias Ringwald 
1949a19cd78SMatthias Ringwald     return g_int >= 0 ? g : 1 / g;
1959a19cd78SMatthias Ringwald }
1969a19cd78SMatthias Ringwald 
1979a19cd78SMatthias Ringwald /**
1989a19cd78SMatthias Ringwald  * Spectrum quantization
1999a19cd78SMatthias Ringwald  * dt, sr          Duration and samplerate of the frame
2009a19cd78SMatthias Ringwald  * g_int           Quantization gain value
2019a19cd78SMatthias Ringwald  * x               Spectral coefficients, scaled as output
2029a19cd78SMatthias Ringwald  * xq, nq          Output spectral quantized coefficients, and count
203*4930cef6SMatthias Ringwald  *
204*4930cef6SMatthias Ringwald  * The spectral coefficients `xq` are stored as :
205*4930cef6SMatthias Ringwald  *   b0       0:positive or zero  1:negative
206*4930cef6SMatthias Ringwald  *   b15..b1  Absolute value
2079a19cd78SMatthias Ringwald  */
208*4930cef6SMatthias Ringwald LC3_HOT static void quantize(enum lc3_dt dt, enum lc3_srate sr,
209*4930cef6SMatthias Ringwald     int g_int, float *x, uint16_t *xq, int *nq)
2109a19cd78SMatthias Ringwald {
2119a19cd78SMatthias Ringwald     float g_inv = 1 / unquantize_gain(g_int);
2129a19cd78SMatthias Ringwald     int ne = LC3_NE(dt, sr);
2139a19cd78SMatthias Ringwald 
2149a19cd78SMatthias Ringwald     *nq = ne;
2159a19cd78SMatthias Ringwald 
2169a19cd78SMatthias Ringwald     for (int i = 0; i < ne; i += 2) {
217*4930cef6SMatthias Ringwald         uint16_t x0, x1;
2189a19cd78SMatthias Ringwald 
2199a19cd78SMatthias Ringwald         x[i+0] *= g_inv;
2209a19cd78SMatthias Ringwald         x[i+1] *= g_inv;
221*4930cef6SMatthias Ringwald 
222*4930cef6SMatthias Ringwald         x0 = fminf(fabsf(x[i+0]) + 6.f/16, INT16_MAX);
223*4930cef6SMatthias Ringwald         x1 = fminf(fabsf(x[i+1]) + 6.f/16, INT16_MAX);
224*4930cef6SMatthias Ringwald 
225*4930cef6SMatthias Ringwald         xq[i+0] = (x0 << 1) + ((x0 > 0) & (x[i+0] < 0));
226*4930cef6SMatthias Ringwald         xq[i+1] = (x1 << 1) + ((x1 > 0) & (x[i+1] < 0));
2279a19cd78SMatthias Ringwald 
2289a19cd78SMatthias Ringwald         *nq = x0 || x1 ? ne : *nq - 2;
2299a19cd78SMatthias Ringwald     }
2309a19cd78SMatthias Ringwald }
2319a19cd78SMatthias Ringwald 
2329a19cd78SMatthias Ringwald /**
2339a19cd78SMatthias Ringwald  * Spectrum quantization inverse
2349a19cd78SMatthias Ringwald  * dt, sr          Duration and samplerate of the frame
2359a19cd78SMatthias Ringwald  * g_int           Quantization gain value
2369a19cd78SMatthias Ringwald  * x, nq           Spectral quantized, and count of significants
2379a19cd78SMatthias Ringwald  * return          Unquantized gain value
2389a19cd78SMatthias Ringwald  */
239*4930cef6SMatthias Ringwald LC3_HOT static float unquantize(enum lc3_dt dt, enum lc3_srate sr,
2409a19cd78SMatthias Ringwald     int g_int, float *x, int nq)
2419a19cd78SMatthias Ringwald {
2429a19cd78SMatthias Ringwald     float g = unquantize_gain(g_int);
2439a19cd78SMatthias Ringwald     int i, ne = LC3_NE(dt, sr);
2449a19cd78SMatthias Ringwald 
2459a19cd78SMatthias Ringwald     for (i = 0; i < nq; i++)
2469a19cd78SMatthias Ringwald         x[i] = x[i] * g;
2479a19cd78SMatthias Ringwald 
2489a19cd78SMatthias Ringwald     for ( ; i < ne; i++)
2499a19cd78SMatthias Ringwald         x[i] = 0;
2509a19cd78SMatthias Ringwald 
2519a19cd78SMatthias Ringwald     return g;
2529a19cd78SMatthias Ringwald }
2539a19cd78SMatthias Ringwald 
2549a19cd78SMatthias Ringwald 
2559a19cd78SMatthias Ringwald /* ----------------------------------------------------------------------------
2569a19cd78SMatthias Ringwald  *  Spectrum coding
2579a19cd78SMatthias Ringwald  * -------------------------------------------------------------------------- */
2589a19cd78SMatthias Ringwald 
2599a19cd78SMatthias Ringwald /**
2609a19cd78SMatthias Ringwald  * Resolve High-bitrate mode according size of the frame
2619a19cd78SMatthias Ringwald  * sr, nbytes      Samplerate and size of the frame
2629a19cd78SMatthias Ringwald  * return          True when High-Rate mode enabled
2639a19cd78SMatthias Ringwald  */
2649a19cd78SMatthias Ringwald static int resolve_high_rate(enum lc3_srate sr, int nbytes)
2659a19cd78SMatthias Ringwald {
2669a19cd78SMatthias Ringwald     return nbytes > 20 * (1 + (int)sr);
2679a19cd78SMatthias Ringwald }
2689a19cd78SMatthias Ringwald 
2699a19cd78SMatthias Ringwald /**
2709a19cd78SMatthias Ringwald  * Bit consumption
2719a19cd78SMatthias Ringwald  * dt, sr, nbytes  Duration, samplerate and size of the frame
2729a19cd78SMatthias Ringwald  * x               Spectral quantized coefficients
2739a19cd78SMatthias Ringwald  * n               Count of significant coefficients, updated on truncation
2749a19cd78SMatthias Ringwald  * nbits_budget    Truncate to stay in budget, when not zero
2759a19cd78SMatthias Ringwald  * p_lsb_mode      Return True when LSB's are not AC coded, or NULL
2769a19cd78SMatthias Ringwald  * return          The number of bits coding the spectrum
277*4930cef6SMatthias Ringwald  *
278*4930cef6SMatthias Ringwald  * The spectral coefficients `x` storage is :
279*4930cef6SMatthias Ringwald  *   b0       0:positive or zero  1:negative
280*4930cef6SMatthias Ringwald  *   b15..b1  Absolute value
2819a19cd78SMatthias Ringwald  */
282*4930cef6SMatthias Ringwald LC3_HOT static int compute_nbits(
2839a19cd78SMatthias Ringwald     enum lc3_dt dt, enum lc3_srate sr, int nbytes,
284*4930cef6SMatthias Ringwald     const uint16_t *x, int *n, int nbits_budget, bool *p_lsb_mode)
2859a19cd78SMatthias Ringwald {
2869a19cd78SMatthias Ringwald     int ne = LC3_NE(dt, sr);
2879a19cd78SMatthias Ringwald 
2889a19cd78SMatthias Ringwald     /* --- Mode and rate --- */
2899a19cd78SMatthias Ringwald 
2909a19cd78SMatthias Ringwald     bool lsb_mode  = nbytes >= 20 * (3 + (int)sr);
2919a19cd78SMatthias Ringwald     bool high_rate = resolve_high_rate(sr, nbytes);
2929a19cd78SMatthias Ringwald 
2939a19cd78SMatthias Ringwald     /* --- Loop on quantized coefficients --- */
2949a19cd78SMatthias Ringwald 
2959a19cd78SMatthias Ringwald     int nbits = 0, nbits_lsb = 0;
2969a19cd78SMatthias Ringwald     uint8_t state = 0;
2979a19cd78SMatthias Ringwald 
2989a19cd78SMatthias Ringwald     int nbits_end = 0;
2999a19cd78SMatthias Ringwald     int n_end = 0;
3009a19cd78SMatthias Ringwald 
3019a19cd78SMatthias Ringwald     nbits_budget = nbits_budget ? nbits_budget * 2048 : INT_MAX;
3029a19cd78SMatthias Ringwald 
3039a19cd78SMatthias Ringwald     for (int i = 0, h = 0; h < 2; h++) {
3049a19cd78SMatthias Ringwald         const uint8_t (*lut_coeff)[4] = lc3_spectrum_lookup[high_rate][h];
3059a19cd78SMatthias Ringwald 
3069a19cd78SMatthias Ringwald         for ( ; i < LC3_MIN(*n, (ne + 2) >> (1 - h))
3079a19cd78SMatthias Ringwald                 && nbits <= nbits_budget; i += 2) {
3089a19cd78SMatthias Ringwald 
3099a19cd78SMatthias Ringwald             const uint8_t *lut = lut_coeff[state];
310*4930cef6SMatthias Ringwald             uint16_t a = x[i] >> 1, b = x[i+1] >> 1;
3119a19cd78SMatthias Ringwald 
3129a19cd78SMatthias Ringwald             /* --- Sign values --- */
3139a19cd78SMatthias Ringwald 
314*4930cef6SMatthias Ringwald             int s = (a > 0) + (b > 0);
3159a19cd78SMatthias Ringwald             nbits += s * 2048;
3169a19cd78SMatthias Ringwald 
3179a19cd78SMatthias Ringwald             /* --- LSB values Reduce to 2*2 bits MSB values ---
3189a19cd78SMatthias Ringwald              * Reduce to 2x2 bits MSB values. The LSB's pair are arithmetic
3199a19cd78SMatthias Ringwald              * coded with an escape code followed by 1 bit for each values.
3209a19cd78SMatthias Ringwald              * The LSB mode does not arthmetic code the first LSB,
3219a19cd78SMatthias Ringwald              * add the sign of the LSB when one of pair was at value 1 */
3229a19cd78SMatthias Ringwald 
3239a19cd78SMatthias Ringwald             int k = 0;
3249a19cd78SMatthias Ringwald             int m = (a | b) >> 2;
3259a19cd78SMatthias Ringwald 
3269a19cd78SMatthias Ringwald             if (m) {
327*4930cef6SMatthias Ringwald 
3289a19cd78SMatthias Ringwald                 if (lsb_mode) {
3299a19cd78SMatthias Ringwald                     nbits += lc3_spectrum_bits[lut[k++]][16] - 2*2048;
3309a19cd78SMatthias Ringwald                     nbits_lsb += 2 + (a == 1) + (b == 1);
3319a19cd78SMatthias Ringwald                 }
3329a19cd78SMatthias Ringwald 
3339a19cd78SMatthias Ringwald                 for (m >>= lsb_mode; m; m >>= 1, k++)
3349a19cd78SMatthias Ringwald                     nbits += lc3_spectrum_bits[lut[LC3_MIN(k, 3)]][16];
3359a19cd78SMatthias Ringwald 
3369a19cd78SMatthias Ringwald                 nbits += k * 2*2048;
3379a19cd78SMatthias Ringwald                 a >>= k;
3389a19cd78SMatthias Ringwald                 b >>= k;
3399a19cd78SMatthias Ringwald 
3409a19cd78SMatthias Ringwald                 k = LC3_MIN(k, 3);
3419a19cd78SMatthias Ringwald             }
3429a19cd78SMatthias Ringwald 
3439a19cd78SMatthias Ringwald             /* --- MSB values --- */
3449a19cd78SMatthias Ringwald 
3459a19cd78SMatthias Ringwald             nbits += lc3_spectrum_bits[lut[k]][a + 4*b];
3469a19cd78SMatthias Ringwald 
3479a19cd78SMatthias Ringwald             /* --- Update state --- */
3489a19cd78SMatthias Ringwald 
3499a19cd78SMatthias Ringwald             if (s && nbits <= nbits_budget) {
3509a19cd78SMatthias Ringwald                 n_end = i + 2;
3519a19cd78SMatthias Ringwald                 nbits_end = nbits;
3529a19cd78SMatthias Ringwald             }
3539a19cd78SMatthias Ringwald 
3549a19cd78SMatthias Ringwald             state = (state << 4) + (k > 1 ? 12 + k : 1 + (a + b) * (k + 1));
3559a19cd78SMatthias Ringwald         }
3569a19cd78SMatthias Ringwald     }
3579a19cd78SMatthias Ringwald 
3589a19cd78SMatthias Ringwald     /* --- Return --- */
3599a19cd78SMatthias Ringwald 
3609a19cd78SMatthias Ringwald     *n = n_end;
3619a19cd78SMatthias Ringwald 
3629a19cd78SMatthias Ringwald     if (p_lsb_mode)
3639a19cd78SMatthias Ringwald         *p_lsb_mode = lsb_mode &&
3649a19cd78SMatthias Ringwald             nbits_end + nbits_lsb * 2048 > nbits_budget;
3659a19cd78SMatthias Ringwald 
3669a19cd78SMatthias Ringwald     if (nbits_budget >= INT_MAX)
3679a19cd78SMatthias Ringwald         nbits_end += nbits_lsb * 2048;
3689a19cd78SMatthias Ringwald 
3699a19cd78SMatthias Ringwald     return (nbits_end + 2047) / 2048;
3709a19cd78SMatthias Ringwald }
3719a19cd78SMatthias Ringwald 
3729a19cd78SMatthias Ringwald /**
3739a19cd78SMatthias Ringwald  * Put quantized spectrum
3749a19cd78SMatthias Ringwald  * bits            Bitstream context
3759a19cd78SMatthias Ringwald  * dt, sr, nbytes  Duration, samplerate and size of the frame
3769a19cd78SMatthias Ringwald  * x               Spectral quantized
3779a19cd78SMatthias Ringwald  * nq, lsb_mode    Count of significants, and LSB discard indication
378*4930cef6SMatthias Ringwald  *
379*4930cef6SMatthias Ringwald  * The spectral coefficients `x` storage is :
380*4930cef6SMatthias Ringwald  *   b0       0:positive or zero  1:negative
381*4930cef6SMatthias Ringwald  *   b15..b1  Absolute value
3829a19cd78SMatthias Ringwald  */
383*4930cef6SMatthias Ringwald LC3_HOT static void put_quantized(lc3_bits_t *bits,
3849a19cd78SMatthias Ringwald     enum lc3_dt dt, enum lc3_srate sr, int nbytes,
385*4930cef6SMatthias Ringwald     const uint16_t *x, int nq, bool lsb_mode)
3869a19cd78SMatthias Ringwald {
3879a19cd78SMatthias Ringwald     int ne = LC3_NE(dt, sr);
3889a19cd78SMatthias Ringwald     bool high_rate = resolve_high_rate(sr, nbytes);
3899a19cd78SMatthias Ringwald 
3909a19cd78SMatthias Ringwald     /* --- Loop on quantized coefficients --- */
3919a19cd78SMatthias Ringwald 
3929a19cd78SMatthias Ringwald     uint8_t state = 0;
3939a19cd78SMatthias Ringwald 
3949a19cd78SMatthias Ringwald     for (int i = 0, h = 0; h < 2; h++) {
3959a19cd78SMatthias Ringwald         const uint8_t (*lut_coeff)[4] = lc3_spectrum_lookup[high_rate][h];
3969a19cd78SMatthias Ringwald 
3979a19cd78SMatthias Ringwald         for ( ; i < LC3_MIN(nq, (ne + 2) >> (1 - h)); i += 2) {
3989a19cd78SMatthias Ringwald 
3999a19cd78SMatthias Ringwald             const uint8_t *lut = lut_coeff[state];
400*4930cef6SMatthias Ringwald             uint16_t a = x[i] >> 1, b = x[i+1] >> 1;
4019a19cd78SMatthias Ringwald 
4029a19cd78SMatthias Ringwald             /* --- LSB values Reduce to 2*2 bits MSB values ---
4039a19cd78SMatthias Ringwald              * Reduce to 2x2 bits MSB values. The LSB's pair are arithmetic
4049a19cd78SMatthias Ringwald              * coded with an escape code and 1 bits for each values.
4059a19cd78SMatthias Ringwald              * The LSB mode discard the first LSB (at this step) */
4069a19cd78SMatthias Ringwald 
4079a19cd78SMatthias Ringwald             int m = (a | b) >> 2;
4089a19cd78SMatthias Ringwald             int k = 0, shr = 0;
4099a19cd78SMatthias Ringwald 
4109a19cd78SMatthias Ringwald             if (m) {
4119a19cd78SMatthias Ringwald 
4129a19cd78SMatthias Ringwald                 if (lsb_mode)
4139a19cd78SMatthias Ringwald                     lc3_put_symbol(bits,
4149a19cd78SMatthias Ringwald                         lc3_spectrum_models + lut[k++], 16);
4159a19cd78SMatthias Ringwald 
4169a19cd78SMatthias Ringwald                 for (m >>= lsb_mode; m; m >>= 1, k++) {
4179a19cd78SMatthias Ringwald                     lc3_put_bit(bits, (a >> k) & 1);
4189a19cd78SMatthias Ringwald                     lc3_put_bit(bits, (b >> k) & 1);
4199a19cd78SMatthias Ringwald                     lc3_put_symbol(bits,
4209a19cd78SMatthias Ringwald                         lc3_spectrum_models + lut[LC3_MIN(k, 3)], 16);
4219a19cd78SMatthias Ringwald                 }
4229a19cd78SMatthias Ringwald 
4239a19cd78SMatthias Ringwald                 a >>= lsb_mode;
4249a19cd78SMatthias Ringwald                 b >>= lsb_mode;
4259a19cd78SMatthias Ringwald 
4269a19cd78SMatthias Ringwald                 shr = k - lsb_mode;
4279a19cd78SMatthias Ringwald                 k = LC3_MIN(k, 3);
4289a19cd78SMatthias Ringwald             }
4299a19cd78SMatthias Ringwald 
4309a19cd78SMatthias Ringwald             /* --- Sign values --- */
4319a19cd78SMatthias Ringwald 
432*4930cef6SMatthias Ringwald             if (a) lc3_put_bit(bits, x[i+0] & 1);
433*4930cef6SMatthias Ringwald             if (b) lc3_put_bit(bits, x[i+1] & 1);
4349a19cd78SMatthias Ringwald 
4359a19cd78SMatthias Ringwald             /* --- MSB values --- */
4369a19cd78SMatthias Ringwald 
4379a19cd78SMatthias Ringwald             a >>= shr;
4389a19cd78SMatthias Ringwald             b >>= shr;
4399a19cd78SMatthias Ringwald 
4409a19cd78SMatthias Ringwald             lc3_put_symbol(bits, lc3_spectrum_models + lut[k], a + 4*b);
4419a19cd78SMatthias Ringwald 
4429a19cd78SMatthias Ringwald             /* --- Update state --- */
4439a19cd78SMatthias Ringwald 
4449a19cd78SMatthias Ringwald             state = (state << 4) + (k > 1 ? 12 + k : 1 + (a + b) * (k + 1));
4459a19cd78SMatthias Ringwald         }
4469a19cd78SMatthias Ringwald     }
4479a19cd78SMatthias Ringwald }
4489a19cd78SMatthias Ringwald 
4499a19cd78SMatthias Ringwald /**
4509a19cd78SMatthias Ringwald  * Get quantized spectrum
4519a19cd78SMatthias Ringwald  * bits            Bitstream context
4529a19cd78SMatthias Ringwald  * dt, sr, nbytes  Duration, samplerate and size of the frame
4539a19cd78SMatthias Ringwald  * nq, lsb_mode    Count of significants, and LSB discard indication
4549a19cd78SMatthias Ringwald  * xq              Return `nq` spectral quantized coefficients
4559a19cd78SMatthias Ringwald  * nf_seed         Return the noise factor seed associated
4569a19cd78SMatthias Ringwald  * return          0: Ok  -1: Invalid bitstream data
4579a19cd78SMatthias Ringwald  */
458*4930cef6SMatthias Ringwald LC3_HOT static int get_quantized(lc3_bits_t *bits,
4599a19cd78SMatthias Ringwald     enum lc3_dt dt, enum lc3_srate sr, int nbytes,
4609a19cd78SMatthias Ringwald     int nq, bool lsb_mode, float *xq, uint16_t *nf_seed)
4619a19cd78SMatthias Ringwald {
4629a19cd78SMatthias Ringwald     int ne = LC3_NE(dt, sr);
4639a19cd78SMatthias Ringwald     bool high_rate = resolve_high_rate(sr, nbytes);
4649a19cd78SMatthias Ringwald 
4659a19cd78SMatthias Ringwald      *nf_seed = 0;
4669a19cd78SMatthias Ringwald 
4679a19cd78SMatthias Ringwald     /* --- Loop on quantized coefficients --- */
4689a19cd78SMatthias Ringwald 
4699a19cd78SMatthias Ringwald     uint8_t state = 0;
4709a19cd78SMatthias Ringwald 
4719a19cd78SMatthias Ringwald     for (int i = 0, h = 0; h < 2; h++) {
4729a19cd78SMatthias Ringwald         const uint8_t (*lut_coeff)[4] = lc3_spectrum_lookup[high_rate][h];
4739a19cd78SMatthias Ringwald 
4749a19cd78SMatthias Ringwald         for ( ; i < LC3_MIN(nq, (ne + 2) >> (1 - h)); i += 2) {
4759a19cd78SMatthias Ringwald 
4769a19cd78SMatthias Ringwald             const uint8_t *lut = lut_coeff[state];
4779a19cd78SMatthias Ringwald 
4789a19cd78SMatthias Ringwald             /* --- LSB values ---
4799a19cd78SMatthias Ringwald              * Until the symbol read indicates the escape value 16,
4809a19cd78SMatthias Ringwald              * read an LSB bit for each values.
4819a19cd78SMatthias Ringwald              * The LSB mode discard the first LSB (at this step) */
4829a19cd78SMatthias Ringwald 
4839a19cd78SMatthias Ringwald             int u = 0, v = 0;
4849a19cd78SMatthias Ringwald             int k = 0, shl = 0;
4859a19cd78SMatthias Ringwald 
4869a19cd78SMatthias Ringwald             unsigned s = lc3_get_symbol(bits, lc3_spectrum_models + lut[k]);
4879a19cd78SMatthias Ringwald 
4889a19cd78SMatthias Ringwald             if (lsb_mode && s >= 16) {
4899a19cd78SMatthias Ringwald                 s = lc3_get_symbol(bits, lc3_spectrum_models + lut[++k]);
4909a19cd78SMatthias Ringwald                 shl++;
4919a19cd78SMatthias Ringwald             }
4929a19cd78SMatthias Ringwald 
4939a19cd78SMatthias Ringwald             for ( ; s >= 16 && shl < 14; shl++) {
4949a19cd78SMatthias Ringwald                 u |= lc3_get_bit(bits) << shl;
4959a19cd78SMatthias Ringwald                 v |= lc3_get_bit(bits) << shl;
4969a19cd78SMatthias Ringwald 
4979a19cd78SMatthias Ringwald                 k += (k < 3);
4989a19cd78SMatthias Ringwald                 s  = lc3_get_symbol(bits, lc3_spectrum_models + lut[k]);
4999a19cd78SMatthias Ringwald             }
5009a19cd78SMatthias Ringwald 
5019a19cd78SMatthias Ringwald             if (s >= 16)
5029a19cd78SMatthias Ringwald                 return -1;
5039a19cd78SMatthias Ringwald 
5049a19cd78SMatthias Ringwald             /* --- MSB & sign values --- */
5059a19cd78SMatthias Ringwald 
5069a19cd78SMatthias Ringwald             int a = s % 4;
5079a19cd78SMatthias Ringwald             int b = s / 4;
5089a19cd78SMatthias Ringwald 
5099a19cd78SMatthias Ringwald             u |= a << shl;
5109a19cd78SMatthias Ringwald             v |= b << shl;
5119a19cd78SMatthias Ringwald 
5129a19cd78SMatthias Ringwald             xq[i  ] = u && lc3_get_bit(bits) ? -u : u;
5139a19cd78SMatthias Ringwald             xq[i+1] = v && lc3_get_bit(bits) ? -v : v;
5149a19cd78SMatthias Ringwald 
5159a19cd78SMatthias Ringwald             *nf_seed = (*nf_seed + u * i + v * (i+1)) & 0xffff;
5169a19cd78SMatthias Ringwald 
5179a19cd78SMatthias Ringwald             /* --- Update state --- */
5189a19cd78SMatthias Ringwald 
5199a19cd78SMatthias Ringwald             state = (state << 4) + (k > 1 ? 12 + k : 1 + (a + b) * (k + 1));
5209a19cd78SMatthias Ringwald         }
5219a19cd78SMatthias Ringwald     }
5229a19cd78SMatthias Ringwald 
5239a19cd78SMatthias Ringwald     return 0;
5249a19cd78SMatthias Ringwald }
5259a19cd78SMatthias Ringwald 
5269a19cd78SMatthias Ringwald /**
5279a19cd78SMatthias Ringwald  * Put residual bits of quantization
5289a19cd78SMatthias Ringwald  * bits            Bitstream context
5299a19cd78SMatthias Ringwald  * nbits           Maximum number of bits to output
530*4930cef6SMatthias Ringwald  * x, n            Spectral quantized, and count of significants
5319a19cd78SMatthias Ringwald  * xf              Scaled spectral coefficients
532*4930cef6SMatthias Ringwald  *
533*4930cef6SMatthias Ringwald  * The spectral coefficients `x` storage is :
534*4930cef6SMatthias Ringwald  *   b0       0:positive or zero  1:negative
535*4930cef6SMatthias Ringwald  *   b15..b1  Absolute value
5369a19cd78SMatthias Ringwald  */
537*4930cef6SMatthias Ringwald LC3_HOT static void put_residual(
538*4930cef6SMatthias Ringwald     lc3_bits_t *bits, int nbits, const uint16_t *x, int n, const float *xf)
5399a19cd78SMatthias Ringwald {
5409a19cd78SMatthias Ringwald     for (int i = 0; i < n && nbits > 0; i++) {
5419a19cd78SMatthias Ringwald 
542*4930cef6SMatthias Ringwald         if (x[i] == 0)
5439a19cd78SMatthias Ringwald             continue;
5449a19cd78SMatthias Ringwald 
545*4930cef6SMatthias Ringwald         float xq = x[i] & 1 ? -(x[i] >> 1) : (x[i] >> 1);
546*4930cef6SMatthias Ringwald 
547*4930cef6SMatthias Ringwald         lc3_put_bit(bits, xf[i] >= xq);
5489a19cd78SMatthias Ringwald         nbits--;
5499a19cd78SMatthias Ringwald     }
5509a19cd78SMatthias Ringwald }
5519a19cd78SMatthias Ringwald 
5529a19cd78SMatthias Ringwald /**
5539a19cd78SMatthias Ringwald  * Get residual bits of quantization
5549a19cd78SMatthias Ringwald  * bits            Bitstream context
5559a19cd78SMatthias Ringwald  * nbits           Maximum number of bits to output
5569a19cd78SMatthias Ringwald  * x, nq           Spectral quantized, and count of significants
5579a19cd78SMatthias Ringwald  */
558*4930cef6SMatthias Ringwald LC3_HOT static void get_residual(
559*4930cef6SMatthias Ringwald     lc3_bits_t *bits, int nbits, float *x, int nq)
5609a19cd78SMatthias Ringwald {
5619a19cd78SMatthias Ringwald     for (int i = 0; i < nq && nbits > 0; i++) {
5629a19cd78SMatthias Ringwald 
5639a19cd78SMatthias Ringwald         if (x[i] == 0)
5649a19cd78SMatthias Ringwald             continue;
5659a19cd78SMatthias Ringwald 
5669a19cd78SMatthias Ringwald         if (lc3_get_bit(bits) == 0)
5679a19cd78SMatthias Ringwald             x[i] -= x[i] < 0 ? 5.f/16 : 3.f/16;
5689a19cd78SMatthias Ringwald         else
5699a19cd78SMatthias Ringwald             x[i] += x[i] > 0 ? 5.f/16 : 3.f/16;
5709a19cd78SMatthias Ringwald 
5719a19cd78SMatthias Ringwald         nbits--;
5729a19cd78SMatthias Ringwald     }
5739a19cd78SMatthias Ringwald }
5749a19cd78SMatthias Ringwald 
5759a19cd78SMatthias Ringwald /**
5769a19cd78SMatthias Ringwald  * Put LSB values of quantized spectrum values
5779a19cd78SMatthias Ringwald  * bits            Bitstream context
5789a19cd78SMatthias Ringwald  * nbits           Maximum number of bits to output
5799a19cd78SMatthias Ringwald  * x, n            Spectral quantized, and count of significants
580*4930cef6SMatthias Ringwald  *
581*4930cef6SMatthias Ringwald  * The spectral coefficients `x` storage is :
582*4930cef6SMatthias Ringwald  *   b0       0:positive or zero  1:negative
583*4930cef6SMatthias Ringwald  *   b15..b1  Absolute value
5849a19cd78SMatthias Ringwald  */
585*4930cef6SMatthias Ringwald LC3_HOT static void put_lsb(
586*4930cef6SMatthias Ringwald     lc3_bits_t *bits, int nbits, const uint16_t *x, int n)
5879a19cd78SMatthias Ringwald {
5889a19cd78SMatthias Ringwald     for (int i = 0; i < n && nbits > 0; i += 2) {
589*4930cef6SMatthias Ringwald         uint16_t a = x[i] >> 1, b = x[i+1] >> 1;
590*4930cef6SMatthias Ringwald         int a_neg = x[i] & 1, b_neg = x[i+1] & 1;
5919a19cd78SMatthias Ringwald 
5929a19cd78SMatthias Ringwald         if ((a | b) >> 2 == 0)
5939a19cd78SMatthias Ringwald             continue;
5949a19cd78SMatthias Ringwald 
5959a19cd78SMatthias Ringwald         if (nbits-- > 0)
5969a19cd78SMatthias Ringwald             lc3_put_bit(bits, a & 1);
5979a19cd78SMatthias Ringwald 
5989a19cd78SMatthias Ringwald         if (a == 1 && nbits-- > 0)
5999a19cd78SMatthias Ringwald             lc3_put_bit(bits, a_neg);
6009a19cd78SMatthias Ringwald 
6019a19cd78SMatthias Ringwald         if (nbits-- > 0)
6029a19cd78SMatthias Ringwald             lc3_put_bit(bits, b & 1);
6039a19cd78SMatthias Ringwald 
6049a19cd78SMatthias Ringwald         if (b == 1 && nbits-- > 0)
6059a19cd78SMatthias Ringwald             lc3_put_bit(bits, b_neg);
6069a19cd78SMatthias Ringwald     }
6079a19cd78SMatthias Ringwald }
6089a19cd78SMatthias Ringwald 
6099a19cd78SMatthias Ringwald /**
6109a19cd78SMatthias Ringwald  * Get LSB values of quantized spectrum values
6119a19cd78SMatthias Ringwald  * bits            Bitstream context
6129a19cd78SMatthias Ringwald  * nbits           Maximum number of bits to output
6139a19cd78SMatthias Ringwald  * x, nq           Spectral quantized, and count of significants
6149a19cd78SMatthias Ringwald  * nf_seed         Update the noise factor seed according
6159a19cd78SMatthias Ringwald  */
616*4930cef6SMatthias Ringwald LC3_HOT static void get_lsb(lc3_bits_t *bits,
6179a19cd78SMatthias Ringwald     int nbits, float *x, int nq, uint16_t *nf_seed)
6189a19cd78SMatthias Ringwald {
6199a19cd78SMatthias Ringwald     for (int i = 0; i < nq && nbits > 0; i += 2) {
6209a19cd78SMatthias Ringwald 
6219a19cd78SMatthias Ringwald         float a = fabsf(x[i]), b = fabsf(x[i+1]);
6229a19cd78SMatthias Ringwald 
6239a19cd78SMatthias Ringwald         if (fmaxf(a, b) < 4)
6249a19cd78SMatthias Ringwald             continue;
6259a19cd78SMatthias Ringwald 
6269a19cd78SMatthias Ringwald         if (nbits-- > 0 && lc3_get_bit(bits)) {
6279a19cd78SMatthias Ringwald             if (a) {
6289a19cd78SMatthias Ringwald                 x[i] += x[i] < 0 ? -1 : 1;
6299a19cd78SMatthias Ringwald                 *nf_seed = (*nf_seed + i) & 0xffff;
6309a19cd78SMatthias Ringwald             } else if (nbits-- > 0) {
6319a19cd78SMatthias Ringwald                 x[i] = lc3_get_bit(bits) ? -1 : 1;
6329a19cd78SMatthias Ringwald                 *nf_seed = (*nf_seed + i) & 0xffff;
6339a19cd78SMatthias Ringwald             }
6349a19cd78SMatthias Ringwald         }
6359a19cd78SMatthias Ringwald 
6369a19cd78SMatthias Ringwald         if (nbits-- > 0 && lc3_get_bit(bits)) {
6379a19cd78SMatthias Ringwald             if (b) {
6389a19cd78SMatthias Ringwald                 x[i+1] += x[i+1] < 0 ? -1 : 1;
6399a19cd78SMatthias Ringwald                 *nf_seed = (*nf_seed + i+1) & 0xffff;
6409a19cd78SMatthias Ringwald             } else if (nbits-- > 0) {
6419a19cd78SMatthias Ringwald                 x[i+1] = lc3_get_bit(bits) ? -1 : 1;
6429a19cd78SMatthias Ringwald                 *nf_seed = (*nf_seed + i+1) & 0xffff;
6439a19cd78SMatthias Ringwald             }
6449a19cd78SMatthias Ringwald         }
6459a19cd78SMatthias Ringwald     }
6469a19cd78SMatthias Ringwald }
6479a19cd78SMatthias Ringwald 
6489a19cd78SMatthias Ringwald 
6499a19cd78SMatthias Ringwald /* ----------------------------------------------------------------------------
6509a19cd78SMatthias Ringwald  *  Noise coding
6519a19cd78SMatthias Ringwald  * -------------------------------------------------------------------------- */
6529a19cd78SMatthias Ringwald 
6539a19cd78SMatthias Ringwald /**
6549a19cd78SMatthias Ringwald  * Estimate noise level
6559a19cd78SMatthias Ringwald  * dt, bw          Duration and bandwidth of the frame
6569a19cd78SMatthias Ringwald  * xq, nq          Quantized spectral coefficients
6579a19cd78SMatthias Ringwald  * x               Quantization scaled spectrum coefficients
6589a19cd78SMatthias Ringwald  * return          Noise factor (0 to 7)
659*4930cef6SMatthias Ringwald  *
660*4930cef6SMatthias Ringwald  * The spectral coefficients `x` storage is :
661*4930cef6SMatthias Ringwald  *   b0       0:positive or zero  1:negative
662*4930cef6SMatthias Ringwald  *   b15..b1  Absolute value
6639a19cd78SMatthias Ringwald  */
664*4930cef6SMatthias Ringwald LC3_HOT static int estimate_noise(enum lc3_dt dt, enum lc3_bandwidth bw,
665*4930cef6SMatthias Ringwald     const uint16_t *xq, int nq, const float *x)
6669a19cd78SMatthias Ringwald {
6679a19cd78SMatthias Ringwald     int bw_stop = (dt == LC3_DT_7M5 ? 60 : 80) * (1 + bw);
6689a19cd78SMatthias Ringwald     int w = 2 + dt;
6699a19cd78SMatthias Ringwald 
6709a19cd78SMatthias Ringwald     float sum = 0;
6719a19cd78SMatthias Ringwald     int i, n = 0, z = 0;
6729a19cd78SMatthias Ringwald 
6739a19cd78SMatthias Ringwald     for (i = 6*(3 + dt) - w; i < LC3_MIN(nq, bw_stop); i++) {
6749a19cd78SMatthias Ringwald         z = xq[i] ? 0 : z + 1;
6759a19cd78SMatthias Ringwald         if (z > 2*w)
676*4930cef6SMatthias Ringwald             sum += fabsf(x[i - w]), n++;
6779a19cd78SMatthias Ringwald     }
6789a19cd78SMatthias Ringwald 
6799a19cd78SMatthias Ringwald     for ( ; i < bw_stop + w; i++)
6809a19cd78SMatthias Ringwald         if (++z > 2*w)
681*4930cef6SMatthias Ringwald             sum += fabsf(x[i - w]), n++;
6829a19cd78SMatthias Ringwald 
6839a19cd78SMatthias Ringwald     int nf = n ? 8 - (int)((16 * sum) / n + 0.5f) : 0;
6849a19cd78SMatthias Ringwald 
6859a19cd78SMatthias Ringwald     return LC3_CLIP(nf, 0, 7);
6869a19cd78SMatthias Ringwald }
6879a19cd78SMatthias Ringwald 
6889a19cd78SMatthias Ringwald /**
6899a19cd78SMatthias Ringwald  * Noise filling
6909a19cd78SMatthias Ringwald  * dt, bw          Duration and bandwidth of the frame
6919a19cd78SMatthias Ringwald  * nf, nf_seed     The noise factor and pseudo-random seed
6929a19cd78SMatthias Ringwald  * g               Quantization gain
6939a19cd78SMatthias Ringwald  * x, nq           Spectral quantized, and count of significants
6949a19cd78SMatthias Ringwald  */
695*4930cef6SMatthias Ringwald LC3_HOT static void fill_noise(enum lc3_dt dt, enum lc3_bandwidth bw,
6969a19cd78SMatthias Ringwald     int nf, uint16_t nf_seed, float g, float *x, int nq)
6979a19cd78SMatthias Ringwald {
6989a19cd78SMatthias Ringwald     int bw_stop = (dt == LC3_DT_7M5 ? 60 : 80) * (1 + bw);
6999a19cd78SMatthias Ringwald     int w = 2 + dt;
7009a19cd78SMatthias Ringwald 
7019a19cd78SMatthias Ringwald     float s = g * (float)(8 - nf) / 16;
7029a19cd78SMatthias Ringwald     int i, z = 0;
7039a19cd78SMatthias Ringwald 
7049a19cd78SMatthias Ringwald     for (i = 6*(3 + dt) - w; i < LC3_MIN(nq, bw_stop); i++) {
7059a19cd78SMatthias Ringwald         z = x[i] ? 0 : z + 1;
7069a19cd78SMatthias Ringwald         if (z > 2*w) {
7079a19cd78SMatthias Ringwald             nf_seed = (13849 + nf_seed*31821) & 0xffff;
7089a19cd78SMatthias Ringwald             x[i - w] = nf_seed & 0x8000 ? -s : s;
7099a19cd78SMatthias Ringwald         }
7109a19cd78SMatthias Ringwald     }
7119a19cd78SMatthias Ringwald 
7129a19cd78SMatthias Ringwald     for ( ; i < bw_stop + w; i++)
7139a19cd78SMatthias Ringwald         if (++z > 2*w) {
7149a19cd78SMatthias Ringwald             nf_seed = (13849 + nf_seed*31821) & 0xffff;
7159a19cd78SMatthias Ringwald             x[i - w] = nf_seed & 0x8000 ? -s : s;
7169a19cd78SMatthias Ringwald         }
7179a19cd78SMatthias Ringwald }
7189a19cd78SMatthias Ringwald 
7199a19cd78SMatthias Ringwald /**
7209a19cd78SMatthias Ringwald  * Put noise factor
7219a19cd78SMatthias Ringwald  * bits            Bitstream context
7229a19cd78SMatthias Ringwald  * nf              Noise factor (0 to 7)
7239a19cd78SMatthias Ringwald  */
7249a19cd78SMatthias Ringwald static void put_noise_factor(lc3_bits_t *bits, int nf)
7259a19cd78SMatthias Ringwald {
7269a19cd78SMatthias Ringwald     lc3_put_bits(bits, nf, 3);
7279a19cd78SMatthias Ringwald }
7289a19cd78SMatthias Ringwald 
7299a19cd78SMatthias Ringwald /**
7309a19cd78SMatthias Ringwald  * Get noise factor
7319a19cd78SMatthias Ringwald  * bits            Bitstream context
7329a19cd78SMatthias Ringwald  * return          Noise factor (0 to 7)
7339a19cd78SMatthias Ringwald  */
7349a19cd78SMatthias Ringwald static int get_noise_factor(lc3_bits_t *bits)
7359a19cd78SMatthias Ringwald {
7369a19cd78SMatthias Ringwald     return lc3_get_bits(bits, 3);
7379a19cd78SMatthias Ringwald }
7389a19cd78SMatthias Ringwald 
7399a19cd78SMatthias Ringwald 
7409a19cd78SMatthias Ringwald /* ----------------------------------------------------------------------------
7419a19cd78SMatthias Ringwald  *  Encoding
7429a19cd78SMatthias Ringwald  * -------------------------------------------------------------------------- */
7439a19cd78SMatthias Ringwald 
7449a19cd78SMatthias Ringwald /**
7459a19cd78SMatthias Ringwald  * Bit consumption of the number of coded coefficients
7469a19cd78SMatthias Ringwald  * dt, sr          Duration, samplerate of the frame
7479a19cd78SMatthias Ringwald  * return          Bit consumpution of the number of coded coefficients
7489a19cd78SMatthias Ringwald  */
7499a19cd78SMatthias Ringwald static int get_nbits_nq(enum lc3_dt dt, enum lc3_srate sr)
7509a19cd78SMatthias Ringwald {
7519a19cd78SMatthias Ringwald     int ne = LC3_NE(dt, sr);
7529a19cd78SMatthias Ringwald     return 4 + (ne > 32) + (ne > 64) + (ne > 128) + (ne > 256);
7539a19cd78SMatthias Ringwald }
7549a19cd78SMatthias Ringwald 
7559a19cd78SMatthias Ringwald /**
7569a19cd78SMatthias Ringwald  * Bit consumption of the arithmetic coder
7579a19cd78SMatthias Ringwald  * dt, sr, nbytes  Duration, samplerate and size of the frame
7589a19cd78SMatthias Ringwald  * return          Bit consumption of bitstream data
7599a19cd78SMatthias Ringwald  */
7609a19cd78SMatthias Ringwald static int get_nbits_ac(enum lc3_dt dt, enum lc3_srate sr, int nbytes)
7619a19cd78SMatthias Ringwald {
7629a19cd78SMatthias Ringwald     return get_nbits_nq(dt, sr) + 3 + LC3_MIN((nbytes-1) / 160, 2);
7639a19cd78SMatthias Ringwald }
7649a19cd78SMatthias Ringwald 
7659a19cd78SMatthias Ringwald /**
7669a19cd78SMatthias Ringwald  * Spectrum analysis
7679a19cd78SMatthias Ringwald  */
7689a19cd78SMatthias Ringwald void lc3_spec_analyze(enum lc3_dt dt, enum lc3_srate sr,
7699a19cd78SMatthias Ringwald     int nbytes, bool pitch, const lc3_tns_data_t *tns,
7709a19cd78SMatthias Ringwald     struct lc3_spec_analysis *spec, float *x,
771*4930cef6SMatthias Ringwald     uint16_t *xq, struct lc3_spec_side *side)
7729a19cd78SMatthias Ringwald {
7739a19cd78SMatthias Ringwald     bool reset_off;
7749a19cd78SMatthias Ringwald 
7759a19cd78SMatthias Ringwald     /* --- Bit budget --- */
7769a19cd78SMatthias Ringwald 
7779a19cd78SMatthias Ringwald     const int nbits_gain = 8;
7789a19cd78SMatthias Ringwald     const int nbits_nf = 3;
7799a19cd78SMatthias Ringwald 
7809a19cd78SMatthias Ringwald     int nbits_budget = 8*nbytes - get_nbits_ac(dt, sr, nbytes) -
7819a19cd78SMatthias Ringwald         lc3_bwdet_get_nbits(sr) - lc3_ltpf_get_nbits(pitch) -
7829a19cd78SMatthias Ringwald         lc3_sns_get_nbits() - lc3_tns_get_nbits(tns) - nbits_gain - nbits_nf;
7839a19cd78SMatthias Ringwald 
7849a19cd78SMatthias Ringwald     /* --- Global gain --- */
7859a19cd78SMatthias Ringwald 
7869a19cd78SMatthias Ringwald     float nbits_off = spec->nbits_off + spec->nbits_spare;
7879a19cd78SMatthias Ringwald     nbits_off = fminf(fmaxf(nbits_off, -40), 40);
788*4930cef6SMatthias Ringwald     nbits_off = 0.8f * spec->nbits_off + 0.2f * nbits_off;
7899a19cd78SMatthias Ringwald 
7909a19cd78SMatthias Ringwald     int g_off = resolve_gain_offset(sr, nbytes);
7919a19cd78SMatthias Ringwald 
7929a19cd78SMatthias Ringwald     int g_int = estimate_gain(dt, sr,
7939a19cd78SMatthias Ringwald         x, nbits_budget, nbits_off, g_off, &reset_off);
7949a19cd78SMatthias Ringwald 
7959a19cd78SMatthias Ringwald     /* --- Quantization --- */
7969a19cd78SMatthias Ringwald 
7979a19cd78SMatthias Ringwald     quantize(dt, sr, g_int, x, xq, &side->nq);
7989a19cd78SMatthias Ringwald 
7999a19cd78SMatthias Ringwald     int nbits = compute_nbits(dt, sr, nbytes, xq, &side->nq, 0, NULL);
8009a19cd78SMatthias Ringwald 
8019a19cd78SMatthias Ringwald     spec->nbits_off = reset_off ? 0 : nbits_off;
8029a19cd78SMatthias Ringwald     spec->nbits_spare = reset_off ? 0 : nbits_budget - nbits;
8039a19cd78SMatthias Ringwald 
8049a19cd78SMatthias Ringwald     /* --- Adjust gain and requantize --- */
8059a19cd78SMatthias Ringwald 
8069a19cd78SMatthias Ringwald     int g_adj = adjust_gain(sr, g_int + g_off, nbits, nbits_budget);
8079a19cd78SMatthias Ringwald 
8089a19cd78SMatthias Ringwald     if (g_adj)
8099a19cd78SMatthias Ringwald         quantize(dt, sr, g_adj, x, xq, &side->nq);
8109a19cd78SMatthias Ringwald 
8119a19cd78SMatthias Ringwald     side->g_idx = g_int + g_adj + g_off;
8129a19cd78SMatthias Ringwald     nbits = compute_nbits(dt, sr, nbytes,
8139a19cd78SMatthias Ringwald         xq, &side->nq, nbits_budget, &side->lsb_mode);
8149a19cd78SMatthias Ringwald }
8159a19cd78SMatthias Ringwald 
8169a19cd78SMatthias Ringwald /**
8179a19cd78SMatthias Ringwald  * Put spectral quantization side data
8189a19cd78SMatthias Ringwald  */
8199a19cd78SMatthias Ringwald void lc3_spec_put_side(lc3_bits_t *bits,
8209a19cd78SMatthias Ringwald     enum lc3_dt dt, enum lc3_srate sr, const struct lc3_spec_side *side)
8219a19cd78SMatthias Ringwald {
8229a19cd78SMatthias Ringwald     int nbits_nq = get_nbits_nq(dt, sr);
8239a19cd78SMatthias Ringwald 
8249a19cd78SMatthias Ringwald     lc3_put_bits(bits, LC3_MAX(side->nq >> 1, 1) - 1, nbits_nq);
8259a19cd78SMatthias Ringwald     lc3_put_bits(bits, side->lsb_mode, 1);
8269a19cd78SMatthias Ringwald     lc3_put_bits(bits, side->g_idx, 8);
8279a19cd78SMatthias Ringwald }
8289a19cd78SMatthias Ringwald 
8299a19cd78SMatthias Ringwald /**
8309a19cd78SMatthias Ringwald  * Encode spectral coefficients
8319a19cd78SMatthias Ringwald  */
8329a19cd78SMatthias Ringwald void lc3_spec_encode(lc3_bits_t *bits,
8339a19cd78SMatthias Ringwald     enum lc3_dt dt, enum lc3_srate sr, enum lc3_bandwidth bw, int nbytes,
834*4930cef6SMatthias Ringwald     const uint16_t *xq, const lc3_spec_side_t *side, const float *x)
8359a19cd78SMatthias Ringwald {
8369a19cd78SMatthias Ringwald     bool lsb_mode = side->lsb_mode;
8379a19cd78SMatthias Ringwald     int nq = side->nq;
8389a19cd78SMatthias Ringwald 
8399a19cd78SMatthias Ringwald     put_noise_factor(bits, estimate_noise(dt, bw, xq, nq, x));
8409a19cd78SMatthias Ringwald 
8419a19cd78SMatthias Ringwald     put_quantized(bits, dt, sr, nbytes, xq, nq, lsb_mode);
8429a19cd78SMatthias Ringwald 
8439a19cd78SMatthias Ringwald     int nbits_left = lc3_get_bits_left(bits);
8449a19cd78SMatthias Ringwald 
8459a19cd78SMatthias Ringwald     if (lsb_mode)
8469a19cd78SMatthias Ringwald         put_lsb(bits, nbits_left, xq, nq);
8479a19cd78SMatthias Ringwald     else
8489a19cd78SMatthias Ringwald         put_residual(bits, nbits_left, xq, nq, x);
8499a19cd78SMatthias Ringwald }
8509a19cd78SMatthias Ringwald 
8519a19cd78SMatthias Ringwald 
8529a19cd78SMatthias Ringwald /* ----------------------------------------------------------------------------
8539a19cd78SMatthias Ringwald  *  Decoding
8549a19cd78SMatthias Ringwald  * -------------------------------------------------------------------------- */
8559a19cd78SMatthias Ringwald 
8569a19cd78SMatthias Ringwald /**
8579a19cd78SMatthias Ringwald  * Get spectral quantization side data
8589a19cd78SMatthias Ringwald  */
8599a19cd78SMatthias Ringwald int lc3_spec_get_side(lc3_bits_t *bits,
8609a19cd78SMatthias Ringwald     enum lc3_dt dt, enum lc3_srate sr, struct lc3_spec_side *side)
8619a19cd78SMatthias Ringwald {
8629a19cd78SMatthias Ringwald     int nbits_nq = get_nbits_nq(dt, sr);
8639a19cd78SMatthias Ringwald     int ne = LC3_NE(dt, sr);
8649a19cd78SMatthias Ringwald 
8659a19cd78SMatthias Ringwald     side->nq = (lc3_get_bits(bits, nbits_nq) + 1) << 1;
8669a19cd78SMatthias Ringwald     side->lsb_mode = lc3_get_bit(bits);
8679a19cd78SMatthias Ringwald     side->g_idx = lc3_get_bits(bits, 8);
8689a19cd78SMatthias Ringwald 
8699a19cd78SMatthias Ringwald     return side->nq > ne ? (side->nq = ne), -1 : 0;
8709a19cd78SMatthias Ringwald }
8719a19cd78SMatthias Ringwald 
8729a19cd78SMatthias Ringwald /**
8739a19cd78SMatthias Ringwald  * Decode spectral coefficients
8749a19cd78SMatthias Ringwald  */
8759a19cd78SMatthias Ringwald int lc3_spec_decode(lc3_bits_t *bits,
8769a19cd78SMatthias Ringwald     enum lc3_dt dt, enum lc3_srate sr, enum lc3_bandwidth bw,
8779a19cd78SMatthias Ringwald     int nbytes, const lc3_spec_side_t *side, float *x)
8789a19cd78SMatthias Ringwald {
8799a19cd78SMatthias Ringwald     bool lsb_mode = side->lsb_mode;
8809a19cd78SMatthias Ringwald     int nq = side->nq;
8819a19cd78SMatthias Ringwald     int ret = 0;
8829a19cd78SMatthias Ringwald 
8839a19cd78SMatthias Ringwald     int nf = get_noise_factor(bits);
8849a19cd78SMatthias Ringwald     uint16_t nf_seed;
8859a19cd78SMatthias Ringwald 
8869a19cd78SMatthias Ringwald     if ((ret = get_quantized(bits, dt, sr, nbytes,
8879a19cd78SMatthias Ringwald                     nq, lsb_mode, x, &nf_seed)) < 0)
8889a19cd78SMatthias Ringwald         return ret;
8899a19cd78SMatthias Ringwald 
8909a19cd78SMatthias Ringwald     int nbits_left = lc3_get_bits_left(bits);
8919a19cd78SMatthias Ringwald 
8929a19cd78SMatthias Ringwald     if (lsb_mode)
8939a19cd78SMatthias Ringwald         get_lsb(bits, nbits_left, x, nq, &nf_seed);
8949a19cd78SMatthias Ringwald     else
8959a19cd78SMatthias Ringwald         get_residual(bits, nbits_left, x, nq);
8969a19cd78SMatthias Ringwald 
8979a19cd78SMatthias Ringwald     int g_int = side->g_idx - resolve_gain_offset(sr, nbytes);
8989a19cd78SMatthias Ringwald     float g = unquantize(dt, sr, g_int, x, nq);
8999a19cd78SMatthias Ringwald 
9009a19cd78SMatthias Ringwald     if (nq > 2 || x[0] || x[1] || side->g_idx > 0 || nf < 7)
9019a19cd78SMatthias Ringwald         fill_noise(dt, bw, nf, nf_seed, g, x, nq);
9029a19cd78SMatthias Ringwald 
9039a19cd78SMatthias Ringwald     return 0;
9049a19cd78SMatthias Ringwald }
905