19a19cd78SMatthias Ringwald /******************************************************************************
29a19cd78SMatthias Ringwald *
34930cef6SMatthias 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 */
resolve_gain_offset(enum lc3_srate sr,int nbytes)339a19cd78SMatthias Ringwald static int resolve_gain_offset(enum lc3_srate sr, int nbytes)
349a19cd78SMatthias Ringwald {
35*6897da5cSDirk Helbig int sr_ind = lc3_hr(sr) ? 4 + (sr - LC3_SRATE_48K_HR) : sr;
36*6897da5cSDirk Helbig
37*6897da5cSDirk Helbig int g_off = (nbytes * 8) / (10 * (1 + sr_ind));
38*6897da5cSDirk Helbig return LC3_MIN(sr >= LC3_SRATE_96K_HR ? 181 : 255,
39*6897da5cSDirk Helbig 105 + 5*(1 + sr_ind) + LC3_MIN(g_off, 115));
40*6897da5cSDirk Helbig }
41*6897da5cSDirk Helbig
42*6897da5cSDirk Helbig /**
43*6897da5cSDirk Helbig * Unquantize gain
44*6897da5cSDirk Helbig * g_int Quantization gain value
45*6897da5cSDirk Helbig * return Unquantized gain value
46*6897da5cSDirk Helbig */
unquantize_gain(int g_int)47*6897da5cSDirk Helbig static float unquantize_gain(int g_int)
48*6897da5cSDirk Helbig {
49*6897da5cSDirk Helbig /* Unquantization gain table :
50*6897da5cSDirk Helbig * G[i] = 10 ^ (i / 28) , i = [0..27] */
51*6897da5cSDirk Helbig
52*6897da5cSDirk Helbig static const float iq_table[] = {
53*6897da5cSDirk Helbig 1.00000000e+00, 1.08571112e+00, 1.17876863e+00, 1.27980221e+00,
54*6897da5cSDirk Helbig 1.38949549e+00, 1.50859071e+00, 1.63789371e+00, 1.77827941e+00,
55*6897da5cSDirk Helbig 1.93069773e+00, 2.09617999e+00, 2.27584593e+00, 2.47091123e+00,
56*6897da5cSDirk Helbig 2.68269580e+00, 2.91263265e+00, 3.16227766e+00, 3.43332002e+00,
57*6897da5cSDirk Helbig 3.72759372e+00, 4.04708995e+00, 4.39397056e+00, 4.77058270e+00,
58*6897da5cSDirk Helbig 5.17947468e+00, 5.62341325e+00, 6.10540230e+00, 6.62870316e+00,
59*6897da5cSDirk Helbig 7.19685673e+00, 7.81370738e+00, 8.48342898e+00, 9.21055318e+00
60*6897da5cSDirk Helbig };
61*6897da5cSDirk Helbig
62*6897da5cSDirk Helbig float g = 1.f;
63*6897da5cSDirk Helbig
64*6897da5cSDirk Helbig for ( ; g_int < 0; g_int += 28, g *= 0.1f);
65*6897da5cSDirk Helbig for ( ; g_int >= 28; g_int -= 28, g *= 10.f);
66*6897da5cSDirk Helbig
67*6897da5cSDirk Helbig return g * iq_table[g_int];
689a19cd78SMatthias Ringwald }
699a19cd78SMatthias Ringwald
709a19cd78SMatthias Ringwald /**
719a19cd78SMatthias Ringwald * Global Gain Estimation
729a19cd78SMatthias Ringwald * dt, sr Duration and samplerate of the frame
739a19cd78SMatthias Ringwald * x Spectral coefficients
74*6897da5cSDirk Helbig * nbytes Size of the frame
759a19cd78SMatthias Ringwald * nbits_budget Number of bits available coding the spectrum
769a19cd78SMatthias Ringwald * nbits_off Offset on the available bits, temporarily smoothed
779a19cd78SMatthias Ringwald * g_off Gain index offset
789a19cd78SMatthias Ringwald * reset_off Return True when the nbits_off must be reset
79*6897da5cSDirk Helbig * g_min Return lower bound of quantized gain value
809a19cd78SMatthias Ringwald * return The quantized gain value
819a19cd78SMatthias Ringwald */
estimate_gain(enum lc3_dt dt,enum lc3_srate sr,const float * x,int nbytes,int nbits_budget,float nbits_off,int g_off,bool * reset_off,int * g_min)824930cef6SMatthias Ringwald LC3_HOT static int estimate_gain(
839a19cd78SMatthias Ringwald enum lc3_dt dt, enum lc3_srate sr, const float *x,
84*6897da5cSDirk Helbig int nbytes, int nbits_budget, float nbits_off, int g_off,
85*6897da5cSDirk Helbig bool *reset_off, int *g_min)
869a19cd78SMatthias Ringwald {
87*6897da5cSDirk Helbig int n4 = lc3_ne(dt, sr) / 4;
88*6897da5cSDirk Helbig union { float f; int32_t q16; } e[LC3_MAX_NE / 4];
89*6897da5cSDirk Helbig
90*6897da5cSDirk Helbig /* --- Signal adaptative noise floor --- */
91*6897da5cSDirk Helbig
92*6897da5cSDirk Helbig int reg_bits = 0;
93*6897da5cSDirk Helbig float low_bits = 0;
94*6897da5cSDirk Helbig
95*6897da5cSDirk Helbig if (lc3_hr(sr)) {
96*6897da5cSDirk Helbig int reg_c = (const int [LC3_NUM_DT][LC3_NUM_SRATE - LC3_SRATE_48K_HR]){
97*6897da5cSDirk Helbig [LC3_DT_2M5] = { -6, -6 },
98*6897da5cSDirk Helbig [LC3_DT_5M ] = { 0, 0 },
99*6897da5cSDirk Helbig [LC3_DT_10M] = { 2, 5 }
100*6897da5cSDirk Helbig }[dt][sr - LC3_SRATE_48K_HR];
101*6897da5cSDirk Helbig
102*6897da5cSDirk Helbig reg_bits = (8*nbytes * 4) / (125 * (1 + dt));
103*6897da5cSDirk Helbig reg_bits = LC3_CLIP(reg_bits + reg_c, 6, 23);
104*6897da5cSDirk Helbig
105*6897da5cSDirk Helbig float m0 = 1e-5f, m1 = 1e-5f, k = 0;
106*6897da5cSDirk Helbig
107*6897da5cSDirk Helbig for (int i = 0; i < n4; i++) {
108*6897da5cSDirk Helbig m0 += fabsf(x[4*i + 0]), m1 += fabsf(x[4*i + 0]) * k++;
109*6897da5cSDirk Helbig m0 += fabsf(x[4*i + 1]), m1 += fabsf(x[4*i + 1]) * k++;
110*6897da5cSDirk Helbig m0 += fabsf(x[4*i + 2]), m1 += fabsf(x[4*i + 2]) * k++;
111*6897da5cSDirk Helbig m0 += fabsf(x[4*i + 3]), m1 += fabsf(x[4*i + 3]) * k++;
112*6897da5cSDirk Helbig }
113*6897da5cSDirk Helbig
114*6897da5cSDirk Helbig int m = roundf((1.6f * m0) / ((1 + dt) * m1));
115*6897da5cSDirk Helbig low_bits = 8 - LC3_MIN(m, 8);
116*6897da5cSDirk Helbig }
1179a19cd78SMatthias Ringwald
1184930cef6SMatthias Ringwald /* --- Energy (dB) by 4 MDCT blocks --- */
1199a19cd78SMatthias Ringwald
1204930cef6SMatthias Ringwald float x2_max = 0;
1219a19cd78SMatthias Ringwald
122*6897da5cSDirk Helbig for (int i = 0; i < n4; i++) {
123*6897da5cSDirk Helbig float x0 = x[4*i + 0] * x[4*i + 0];
124*6897da5cSDirk Helbig float x1 = x[4*i + 1] * x[4*i + 1];
125*6897da5cSDirk Helbig float x2 = x[4*i + 2] * x[4*i + 2];
126*6897da5cSDirk Helbig float x3 = x[4*i + 3] * x[4*i + 3];
1279a19cd78SMatthias Ringwald
1284930cef6SMatthias Ringwald x2_max = fmaxf(x2_max, x0);
1294930cef6SMatthias Ringwald x2_max = fmaxf(x2_max, x1);
1304930cef6SMatthias Ringwald x2_max = fmaxf(x2_max, x2);
1314930cef6SMatthias Ringwald x2_max = fmaxf(x2_max, x3);
1329a19cd78SMatthias Ringwald
133*6897da5cSDirk Helbig e[i].f = x0 + x1 + x2 + x3;
1349a19cd78SMatthias Ringwald }
1359a19cd78SMatthias Ringwald
136*6897da5cSDirk Helbig float x_max = sqrtf(x2_max);
137*6897da5cSDirk Helbig float nf = lc3_hr(sr) ?
138*6897da5cSDirk Helbig lc3_ldexpf(x_max, -reg_bits) * lc3_exp2f(-low_bits) : 0;
139*6897da5cSDirk Helbig
140*6897da5cSDirk Helbig for (int i = 0; i < n4; i++)
141*6897da5cSDirk Helbig e[i].q16 = lc3_db_q16(fmaxf(e[i].f + nf, 1e-10f));
142*6897da5cSDirk Helbig
1439a19cd78SMatthias Ringwald /* --- Determine gain index --- */
1449a19cd78SMatthias Ringwald
1459a19cd78SMatthias Ringwald int nbits = nbits_budget + nbits_off + 0.5f;
1469a19cd78SMatthias Ringwald int g_int = 255 - g_off;
1479a19cd78SMatthias Ringwald
1484930cef6SMatthias Ringwald const int k_20_28 = 20.f/28 * 0x1p16f + 0.5f;
1494930cef6SMatthias Ringwald const int k_2u7 = 2.7f * 0x1p16f + 0.5f;
1504930cef6SMatthias Ringwald const int k_1u4 = 1.4f * 0x1p16f + 0.5f;
1519a19cd78SMatthias Ringwald
152*6897da5cSDirk Helbig for (int i = 128, j, j0 = n4-1, j1 ; i > 0; i >>= 1) {
1534930cef6SMatthias Ringwald int gn = (g_int - i) * k_20_28;
1544930cef6SMatthias Ringwald int v = 0;
1559a19cd78SMatthias Ringwald
156*6897da5cSDirk Helbig for (j = j0; j >= 0 && e[j].q16 < gn; j--);
1579a19cd78SMatthias Ringwald
1584930cef6SMatthias Ringwald for (j1 = j; j >= 0; j--) {
159*6897da5cSDirk Helbig int e_diff = e[j].q16 - gn;
1609a19cd78SMatthias Ringwald
1614930cef6SMatthias Ringwald v += e_diff < 0 ? k_2u7 :
1624930cef6SMatthias Ringwald e_diff < 43 << 16 ? e_diff + ( 7 << 16)
1634930cef6SMatthias Ringwald : 2*e_diff - (36 << 16);
1649a19cd78SMatthias Ringwald }
1659a19cd78SMatthias Ringwald
1664930cef6SMatthias Ringwald if (v > nbits * k_1u4)
1674930cef6SMatthias Ringwald j0 = j1;
1684930cef6SMatthias Ringwald else
1694930cef6SMatthias Ringwald g_int = g_int - i;
1709a19cd78SMatthias Ringwald }
1719a19cd78SMatthias Ringwald
1729a19cd78SMatthias Ringwald /* --- Limit gain index --- */
1739a19cd78SMatthias Ringwald
174*6897da5cSDirk Helbig float x_lim = lc3_hr(sr) ? 0x7fffp8f : 0x7fffp0f;
1759a19cd78SMatthias Ringwald
176*6897da5cSDirk Helbig *g_min = 255 - g_off;
177*6897da5cSDirk Helbig for (int i = 128 ; i > 0; i >>= 1)
178*6897da5cSDirk Helbig if (x_lim * unquantize_gain(*g_min - i) > x_max)
179*6897da5cSDirk Helbig *g_min -= i;
180*6897da5cSDirk Helbig
181*6897da5cSDirk Helbig *reset_off = g_int < *g_min || x_max == 0;
1829a19cd78SMatthias Ringwald if (*reset_off)
183*6897da5cSDirk Helbig g_int = *g_min;
1849a19cd78SMatthias Ringwald
1859a19cd78SMatthias Ringwald return g_int;
1869a19cd78SMatthias Ringwald }
1879a19cd78SMatthias Ringwald
1889a19cd78SMatthias Ringwald /**
1899a19cd78SMatthias Ringwald * Global Gain Adjustment
190*6897da5cSDirk Helbig * dt, sr Duration and samplerate of the frame
1919a19cd78SMatthias Ringwald * g_idx The estimated quantized gain index
1929a19cd78SMatthias Ringwald * nbits Computed number of bits coding the spectrum
1939a19cd78SMatthias Ringwald * nbits_budget Number of bits available for coding the spectrum
194*6897da5cSDirk Helbig * g_idx_min Minimum gain index value
1959a19cd78SMatthias Ringwald * return Gain adjust value (-1 to 2)
1969a19cd78SMatthias Ringwald */
adjust_gain(enum lc3_dt dt,enum lc3_srate sr,int g_idx,int nbits,int nbits_budget,int g_idx_min)1974930cef6SMatthias Ringwald LC3_HOT static int adjust_gain(
198*6897da5cSDirk Helbig enum lc3_dt dt, enum lc3_srate sr,
199*6897da5cSDirk Helbig int g_idx, int nbits, int nbits_budget, int g_idx_min)
2009a19cd78SMatthias Ringwald {
2019a19cd78SMatthias Ringwald /* --- Compute delta threshold --- */
2029a19cd78SMatthias Ringwald
2039a19cd78SMatthias Ringwald const int *t = (const int [LC3_NUM_SRATE][3]){
2049a19cd78SMatthias Ringwald { 80, 500, 850 }, { 230, 1025, 1700 }, { 380, 1550, 2550 },
205*6897da5cSDirk Helbig { 530, 2075, 3400 }, { 680, 2600, 4250 },
206*6897da5cSDirk Helbig { 680, 2600, 4250 }, { 830, 3125, 5100 }
2079a19cd78SMatthias Ringwald }[sr];
2089a19cd78SMatthias Ringwald
2099a19cd78SMatthias Ringwald int delta, den = 48;
2109a19cd78SMatthias Ringwald
2119a19cd78SMatthias Ringwald if (nbits < t[0]) {
2129a19cd78SMatthias Ringwald delta = 3*(nbits + 48);
2139a19cd78SMatthias Ringwald
2149a19cd78SMatthias Ringwald } else if (nbits < t[1]) {
2159a19cd78SMatthias Ringwald int n0 = 3*(t[0] + 48), range = t[1] - t[0];
2169a19cd78SMatthias Ringwald delta = n0 * range + (nbits - t[0]) * (t[1] - n0);
2179a19cd78SMatthias Ringwald den *= range;
2189a19cd78SMatthias Ringwald
2199a19cd78SMatthias Ringwald } else {
2209a19cd78SMatthias Ringwald delta = LC3_MIN(nbits, t[2]);
2219a19cd78SMatthias Ringwald }
2229a19cd78SMatthias Ringwald
2239a19cd78SMatthias Ringwald delta = (delta + den/2) / den;
2249a19cd78SMatthias Ringwald
2259a19cd78SMatthias Ringwald /* --- Adjust gain --- */
2269a19cd78SMatthias Ringwald
227*6897da5cSDirk Helbig if (lc3_hr(sr) && nbits > nbits_budget) {
228*6897da5cSDirk Helbig int factor = 1 + (dt <= LC3_DT_5M) +
229*6897da5cSDirk Helbig (dt <= LC3_DT_2M5) * (1 + (nbits >= 520));
2309a19cd78SMatthias Ringwald
231*6897da5cSDirk Helbig int g_incr = factor + (factor * (nbits - nbits_budget)) / delta;
232*6897da5cSDirk Helbig return LC3_MIN(g_idx + g_incr, 255) - g_idx;
233*6897da5cSDirk Helbig }
234*6897da5cSDirk Helbig
235*6897da5cSDirk Helbig if (!lc3_hr(sr) && nbits < nbits_budget - (delta + 2))
236*6897da5cSDirk Helbig return -(g_idx > g_idx_min);
237*6897da5cSDirk Helbig
238*6897da5cSDirk Helbig if (!lc3_hr(sr) && nbits > nbits_budget)
2399a19cd78SMatthias Ringwald return (g_idx < 255) + (g_idx < 254 && nbits >= nbits_budget + delta);
2409a19cd78SMatthias Ringwald
2419a19cd78SMatthias Ringwald return 0;
2429a19cd78SMatthias Ringwald }
2439a19cd78SMatthias Ringwald
2449a19cd78SMatthias Ringwald /**
2459a19cd78SMatthias Ringwald * Spectrum quantization
2469a19cd78SMatthias Ringwald * dt, sr Duration and samplerate of the frame
2479a19cd78SMatthias Ringwald * g_int Quantization gain value
2489a19cd78SMatthias Ringwald * x Spectral coefficients, scaled as output
249*6897da5cSDirk Helbig * n Return count of significants
2509a19cd78SMatthias Ringwald */
quantize(enum lc3_dt dt,enum lc3_srate sr,int g_int,float * x,int * n)251*6897da5cSDirk Helbig LC3_HOT static void quantize(
252*6897da5cSDirk Helbig enum lc3_dt dt, enum lc3_srate sr, int g_int, float *x, int *n)
2539a19cd78SMatthias Ringwald {
254*6897da5cSDirk Helbig float g_inv = unquantize_gain(-g_int);
255*6897da5cSDirk Helbig int ne = lc3_ne(dt, sr);
2569a19cd78SMatthias Ringwald
257*6897da5cSDirk Helbig *n = ne;
2589a19cd78SMatthias Ringwald
2599a19cd78SMatthias Ringwald for (int i = 0; i < ne; i += 2) {
260*6897da5cSDirk Helbig float xq_min = lc3_hr(sr) ? 0.5f : 10.f/16;
2619a19cd78SMatthias Ringwald
2629a19cd78SMatthias Ringwald x[i+0] *= g_inv;
2639a19cd78SMatthias Ringwald x[i+1] *= g_inv;
2644930cef6SMatthias Ringwald
265*6897da5cSDirk Helbig *n = fabsf(x[i+0]) >= xq_min ||
266*6897da5cSDirk Helbig fabsf(x[i+1]) >= xq_min ? ne : *n - 2;
2679a19cd78SMatthias Ringwald }
2689a19cd78SMatthias Ringwald }
2699a19cd78SMatthias Ringwald
2709a19cd78SMatthias Ringwald /**
2719a19cd78SMatthias Ringwald * Spectrum quantization inverse
2729a19cd78SMatthias Ringwald * dt, sr Duration and samplerate of the frame
2739a19cd78SMatthias Ringwald * g_int Quantization gain value
2749a19cd78SMatthias Ringwald * x, nq Spectral quantized, and count of significants
2759a19cd78SMatthias Ringwald * return Unquantized gain value
2769a19cd78SMatthias Ringwald */
unquantize(enum lc3_dt dt,enum lc3_srate sr,int g_int,float * x,int nq)277*6897da5cSDirk Helbig LC3_HOT static float unquantize(
278*6897da5cSDirk Helbig enum lc3_dt dt, enum lc3_srate sr,
2799a19cd78SMatthias Ringwald int g_int, float *x, int nq)
2809a19cd78SMatthias Ringwald {
2819a19cd78SMatthias Ringwald float g = unquantize_gain(g_int);
282*6897da5cSDirk Helbig int i, ne = lc3_ne(dt, sr);
2839a19cd78SMatthias Ringwald
2849a19cd78SMatthias Ringwald for (i = 0; i < nq; i++)
2859a19cd78SMatthias Ringwald x[i] = x[i] * g;
2869a19cd78SMatthias Ringwald
2879a19cd78SMatthias Ringwald for ( ; i < ne; i++)
2889a19cd78SMatthias Ringwald x[i] = 0;
2899a19cd78SMatthias Ringwald
2909a19cd78SMatthias Ringwald return g;
2919a19cd78SMatthias Ringwald }
2929a19cd78SMatthias Ringwald
2939a19cd78SMatthias Ringwald
2949a19cd78SMatthias Ringwald /* ----------------------------------------------------------------------------
2959a19cd78SMatthias Ringwald * Spectrum coding
2969a19cd78SMatthias Ringwald * -------------------------------------------------------------------------- */
2979a19cd78SMatthias Ringwald
2989a19cd78SMatthias Ringwald /**
299*6897da5cSDirk Helbig * Resolve High-bitrate and LSB modes according size of the frame
3009a19cd78SMatthias Ringwald * sr, nbytes Samplerate and size of the frame
301*6897da5cSDirk Helbig * p_lsb_mode True when LSB mode allowed, when not NULL
3029a19cd78SMatthias Ringwald * return True when High-Rate mode enabled
3039a19cd78SMatthias Ringwald */
resolve_modes(enum lc3_srate sr,int nbytes,bool * p_lsb_mode)304*6897da5cSDirk Helbig static bool resolve_modes(enum lc3_srate sr, int nbytes, bool *p_lsb_mode)
3059a19cd78SMatthias Ringwald {
306*6897da5cSDirk Helbig int sr_ind = lc3_hr(sr) ? 4 + (sr - LC3_SRATE_48K_HR) : sr;
307*6897da5cSDirk Helbig
308*6897da5cSDirk Helbig if (p_lsb_mode)
309*6897da5cSDirk Helbig *p_lsb_mode = (nbytes >= 20 * (3 + sr_ind)) && (sr < LC3_SRATE_96K_HR);
310*6897da5cSDirk Helbig
311*6897da5cSDirk Helbig return (nbytes > 20 * (1 + sr_ind)) && (sr < LC3_SRATE_96K_HR);
3129a19cd78SMatthias Ringwald }
3139a19cd78SMatthias Ringwald
3149a19cd78SMatthias Ringwald /**
3159a19cd78SMatthias Ringwald * Bit consumption
3169a19cd78SMatthias Ringwald * dt, sr, nbytes Duration, samplerate and size of the frame
3179a19cd78SMatthias Ringwald * x Spectral quantized coefficients
3189a19cd78SMatthias Ringwald * n Count of significant coefficients, updated on truncation
3199a19cd78SMatthias Ringwald * nbits_budget Truncate to stay in budget, when not zero
3209a19cd78SMatthias Ringwald * p_lsb_mode Return True when LSB's are not AC coded, or NULL
3219a19cd78SMatthias Ringwald * return The number of bits coding the spectrum
3229a19cd78SMatthias Ringwald */
compute_nbits(enum lc3_dt dt,enum lc3_srate sr,int nbytes,const float * x,int * n,int nbits_budget,bool * p_lsb_mode)3234930cef6SMatthias Ringwald LC3_HOT static int compute_nbits(
3249a19cd78SMatthias Ringwald enum lc3_dt dt, enum lc3_srate sr, int nbytes,
325*6897da5cSDirk Helbig const float *x, int *n, int nbits_budget, bool *p_lsb_mode)
3269a19cd78SMatthias Ringwald {
327*6897da5cSDirk Helbig bool lsb_mode, high_rate = resolve_modes(sr, nbytes, &lsb_mode);
328*6897da5cSDirk Helbig int ne = lc3_ne(dt, sr);
3299a19cd78SMatthias Ringwald
3309a19cd78SMatthias Ringwald /* --- Loop on quantized coefficients --- */
3319a19cd78SMatthias Ringwald
3329a19cd78SMatthias Ringwald int nbits = 0, nbits_lsb = 0;
3339a19cd78SMatthias Ringwald uint8_t state = 0;
3349a19cd78SMatthias Ringwald
3359a19cd78SMatthias Ringwald int nbits_end = 0;
3369a19cd78SMatthias Ringwald int n_end = 0;
3379a19cd78SMatthias Ringwald
3389a19cd78SMatthias Ringwald nbits_budget = nbits_budget ? nbits_budget * 2048 : INT_MAX;
3399a19cd78SMatthias Ringwald
3409a19cd78SMatthias Ringwald for (int i = 0, h = 0; h < 2; h++) {
3419a19cd78SMatthias Ringwald const uint8_t (*lut_coeff)[4] = lc3_spectrum_lookup[high_rate][h];
3429a19cd78SMatthias Ringwald
3439a19cd78SMatthias Ringwald for ( ; i < LC3_MIN(*n, (ne + 2) >> (1 - h))
3449a19cd78SMatthias Ringwald && nbits <= nbits_budget; i += 2) {
3459a19cd78SMatthias Ringwald
346*6897da5cSDirk Helbig float xq_off = lc3_hr(sr) ? 0.5f : 6.f/16;
347*6897da5cSDirk Helbig uint32_t a = fabsf(x[i+0]) + xq_off;
348*6897da5cSDirk Helbig uint32_t b = fabsf(x[i+1]) + xq_off;
349*6897da5cSDirk Helbig
3509a19cd78SMatthias Ringwald const uint8_t *lut = lut_coeff[state];
3519a19cd78SMatthias Ringwald
3529a19cd78SMatthias Ringwald /* --- Sign values --- */
3539a19cd78SMatthias Ringwald
354*6897da5cSDirk Helbig int s = (a != 0) + (b != 0);
3559a19cd78SMatthias Ringwald nbits += s * 2048;
3569a19cd78SMatthias Ringwald
3579a19cd78SMatthias Ringwald /* --- LSB values Reduce to 2*2 bits MSB values ---
3589a19cd78SMatthias Ringwald * Reduce to 2x2 bits MSB values. The LSB's pair are arithmetic
3599a19cd78SMatthias Ringwald * coded with an escape code followed by 1 bit for each values.
3609a19cd78SMatthias Ringwald * The LSB mode does not arthmetic code the first LSB,
3619a19cd78SMatthias Ringwald * add the sign of the LSB when one of pair was at value 1 */
3629a19cd78SMatthias Ringwald
363*6897da5cSDirk Helbig uint32_t m = (a | b) >> 2;
364*6897da5cSDirk Helbig unsigned k = 0;
3659a19cd78SMatthias Ringwald
3669a19cd78SMatthias Ringwald if (m) {
3674930cef6SMatthias Ringwald
3689a19cd78SMatthias Ringwald if (lsb_mode) {
3699a19cd78SMatthias Ringwald nbits += lc3_spectrum_bits[lut[k++]][16] - 2*2048;
3709a19cd78SMatthias Ringwald nbits_lsb += 2 + (a == 1) + (b == 1);
3719a19cd78SMatthias Ringwald }
3729a19cd78SMatthias Ringwald
3739a19cd78SMatthias Ringwald for (m >>= lsb_mode; m; m >>= 1, k++)
3749a19cd78SMatthias Ringwald nbits += lc3_spectrum_bits[lut[LC3_MIN(k, 3)]][16];
3759a19cd78SMatthias Ringwald
3769a19cd78SMatthias Ringwald nbits += k * 2*2048;
3779a19cd78SMatthias Ringwald a >>= k;
3789a19cd78SMatthias Ringwald b >>= k;
3799a19cd78SMatthias Ringwald
3809a19cd78SMatthias Ringwald k = LC3_MIN(k, 3);
3819a19cd78SMatthias Ringwald }
3829a19cd78SMatthias Ringwald
3839a19cd78SMatthias Ringwald /* --- MSB values --- */
3849a19cd78SMatthias Ringwald
3859a19cd78SMatthias Ringwald nbits += lc3_spectrum_bits[lut[k]][a + 4*b];
3869a19cd78SMatthias Ringwald
3879a19cd78SMatthias Ringwald /* --- Update state --- */
3889a19cd78SMatthias Ringwald
3899a19cd78SMatthias Ringwald if (s && nbits <= nbits_budget) {
3909a19cd78SMatthias Ringwald n_end = i + 2;
3919a19cd78SMatthias Ringwald nbits_end = nbits;
3929a19cd78SMatthias Ringwald }
3939a19cd78SMatthias Ringwald
3949a19cd78SMatthias Ringwald state = (state << 4) + (k > 1 ? 12 + k : 1 + (a + b) * (k + 1));
3959a19cd78SMatthias Ringwald }
3969a19cd78SMatthias Ringwald }
3979a19cd78SMatthias Ringwald
3989a19cd78SMatthias Ringwald /* --- Return --- */
3999a19cd78SMatthias Ringwald
4009a19cd78SMatthias Ringwald *n = n_end;
4019a19cd78SMatthias Ringwald
4029a19cd78SMatthias Ringwald if (p_lsb_mode)
4039a19cd78SMatthias Ringwald *p_lsb_mode = lsb_mode &&
4049a19cd78SMatthias Ringwald nbits_end + nbits_lsb * 2048 > nbits_budget;
4059a19cd78SMatthias Ringwald
4069a19cd78SMatthias Ringwald if (nbits_budget >= INT_MAX)
4079a19cd78SMatthias Ringwald nbits_end += nbits_lsb * 2048;
4089a19cd78SMatthias Ringwald
4099a19cd78SMatthias Ringwald return (nbits_end + 2047) / 2048;
4109a19cd78SMatthias Ringwald }
4119a19cd78SMatthias Ringwald
4129a19cd78SMatthias Ringwald /**
4139a19cd78SMatthias Ringwald * Put quantized spectrum
4149a19cd78SMatthias Ringwald * bits Bitstream context
4159a19cd78SMatthias Ringwald * dt, sr, nbytes Duration, samplerate and size of the frame
416*6897da5cSDirk Helbig * x Spectral quantized coefficients
4179a19cd78SMatthias Ringwald * nq, lsb_mode Count of significants, and LSB discard indication
4189a19cd78SMatthias Ringwald */
put_quantized(lc3_bits_t * bits,enum lc3_dt dt,enum lc3_srate sr,int nbytes,const float * x,int nq,bool lsb_mode)4194930cef6SMatthias Ringwald LC3_HOT static void put_quantized(lc3_bits_t *bits,
4209a19cd78SMatthias Ringwald enum lc3_dt dt, enum lc3_srate sr, int nbytes,
421*6897da5cSDirk Helbig const float *x, int nq, bool lsb_mode)
4229a19cd78SMatthias Ringwald {
423*6897da5cSDirk Helbig bool high_rate = resolve_modes(sr, nbytes, NULL);
424*6897da5cSDirk Helbig int ne = lc3_ne(dt, sr);
4259a19cd78SMatthias Ringwald
4269a19cd78SMatthias Ringwald /* --- Loop on quantized coefficients --- */
4279a19cd78SMatthias Ringwald
4289a19cd78SMatthias Ringwald uint8_t state = 0;
4299a19cd78SMatthias Ringwald
4309a19cd78SMatthias Ringwald for (int i = 0, h = 0; h < 2; h++) {
4319a19cd78SMatthias Ringwald const uint8_t (*lut_coeff)[4] = lc3_spectrum_lookup[high_rate][h];
4329a19cd78SMatthias Ringwald
4339a19cd78SMatthias Ringwald for ( ; i < LC3_MIN(nq, (ne + 2) >> (1 - h)); i += 2) {
4349a19cd78SMatthias Ringwald
435*6897da5cSDirk Helbig float xq_off = lc3_hr(sr) ? 0.5f : 6.f/16;
436*6897da5cSDirk Helbig uint32_t a = fabsf(x[i+0]) + xq_off;
437*6897da5cSDirk Helbig uint32_t b = fabsf(x[i+1]) + xq_off;
438*6897da5cSDirk Helbig
4399a19cd78SMatthias Ringwald const uint8_t *lut = lut_coeff[state];
4409a19cd78SMatthias Ringwald
4419a19cd78SMatthias Ringwald /* --- LSB values Reduce to 2*2 bits MSB values ---
4429a19cd78SMatthias Ringwald * Reduce to 2x2 bits MSB values. The LSB's pair are arithmetic
4439a19cd78SMatthias Ringwald * coded with an escape code and 1 bits for each values.
4449a19cd78SMatthias Ringwald * The LSB mode discard the first LSB (at this step) */
4459a19cd78SMatthias Ringwald
446*6897da5cSDirk Helbig uint32_t m = (a | b) >> 2;
447*6897da5cSDirk Helbig unsigned k = 0, shr = 0;
4489a19cd78SMatthias Ringwald
4499a19cd78SMatthias Ringwald if (m) {
4509a19cd78SMatthias Ringwald
4519a19cd78SMatthias Ringwald if (lsb_mode)
4529a19cd78SMatthias Ringwald lc3_put_symbol(bits,
4539a19cd78SMatthias Ringwald lc3_spectrum_models + lut[k++], 16);
4549a19cd78SMatthias Ringwald
4559a19cd78SMatthias Ringwald for (m >>= lsb_mode; m; m >>= 1, k++) {
4569a19cd78SMatthias Ringwald lc3_put_bit(bits, (a >> k) & 1);
4579a19cd78SMatthias Ringwald lc3_put_bit(bits, (b >> k) & 1);
4589a19cd78SMatthias Ringwald lc3_put_symbol(bits,
4599a19cd78SMatthias Ringwald lc3_spectrum_models + lut[LC3_MIN(k, 3)], 16);
4609a19cd78SMatthias Ringwald }
4619a19cd78SMatthias Ringwald
4629a19cd78SMatthias Ringwald a >>= lsb_mode;
4639a19cd78SMatthias Ringwald b >>= lsb_mode;
4649a19cd78SMatthias Ringwald
4659a19cd78SMatthias Ringwald shr = k - lsb_mode;
4669a19cd78SMatthias Ringwald k = LC3_MIN(k, 3);
4679a19cd78SMatthias Ringwald }
4689a19cd78SMatthias Ringwald
4699a19cd78SMatthias Ringwald /* --- Sign values --- */
4709a19cd78SMatthias Ringwald
471*6897da5cSDirk Helbig if (a) lc3_put_bit(bits, x[i+0] < 0);
472*6897da5cSDirk Helbig if (b) lc3_put_bit(bits, x[i+1] < 0);
4739a19cd78SMatthias Ringwald
4749a19cd78SMatthias Ringwald /* --- MSB values --- */
4759a19cd78SMatthias Ringwald
4769a19cd78SMatthias Ringwald a >>= shr;
4779a19cd78SMatthias Ringwald b >>= shr;
4789a19cd78SMatthias Ringwald
4799a19cd78SMatthias Ringwald lc3_put_symbol(bits, lc3_spectrum_models + lut[k], a + 4*b);
4809a19cd78SMatthias Ringwald
4819a19cd78SMatthias Ringwald /* --- Update state --- */
4829a19cd78SMatthias Ringwald
4839a19cd78SMatthias Ringwald state = (state << 4) + (k > 1 ? 12 + k : 1 + (a + b) * (k + 1));
4849a19cd78SMatthias Ringwald }
4859a19cd78SMatthias Ringwald }
4869a19cd78SMatthias Ringwald }
4879a19cd78SMatthias Ringwald
4889a19cd78SMatthias Ringwald /**
4899a19cd78SMatthias Ringwald * Get quantized spectrum
4909a19cd78SMatthias Ringwald * bits Bitstream context
4919a19cd78SMatthias Ringwald * dt, sr, nbytes Duration, samplerate and size of the frame
4929a19cd78SMatthias Ringwald * nq, lsb_mode Count of significants, and LSB discard indication
493*6897da5cSDirk Helbig * x Return `nq` spectral quantized coefficients
4949a19cd78SMatthias Ringwald * nf_seed Return the noise factor seed associated
4959a19cd78SMatthias Ringwald * return 0: Ok -1: Invalid bitstream data
4969a19cd78SMatthias Ringwald */
get_quantized(lc3_bits_t * bits,enum lc3_dt dt,enum lc3_srate sr,int nbytes,int nq,bool lsb_mode,float * x,uint16_t * nf_seed)4974930cef6SMatthias Ringwald LC3_HOT static int get_quantized(lc3_bits_t *bits,
4989a19cd78SMatthias Ringwald enum lc3_dt dt, enum lc3_srate sr, int nbytes,
499*6897da5cSDirk Helbig int nq, bool lsb_mode, float *x, uint16_t *nf_seed)
5009a19cd78SMatthias Ringwald {
501*6897da5cSDirk Helbig bool high_rate = resolve_modes(sr, nbytes, NULL);
502*6897da5cSDirk Helbig int ne = lc3_ne(dt, sr);
5039a19cd78SMatthias Ringwald
5049a19cd78SMatthias Ringwald *nf_seed = 0;
5059a19cd78SMatthias Ringwald
5069a19cd78SMatthias Ringwald /* --- Loop on quantized coefficients --- */
5079a19cd78SMatthias Ringwald
5089a19cd78SMatthias Ringwald uint8_t state = 0;
5099a19cd78SMatthias Ringwald
5109a19cd78SMatthias Ringwald for (int i = 0, h = 0; h < 2; h++) {
5119a19cd78SMatthias Ringwald const uint8_t (*lut_coeff)[4] = lc3_spectrum_lookup[high_rate][h];
5129a19cd78SMatthias Ringwald
5139a19cd78SMatthias Ringwald for ( ; i < LC3_MIN(nq, (ne + 2) >> (1 - h)); i += 2) {
5149a19cd78SMatthias Ringwald
5159a19cd78SMatthias Ringwald const uint8_t *lut = lut_coeff[state];
516*6897da5cSDirk Helbig int max_shl = lc3_hr(sr) ? 22 : 14;
5179a19cd78SMatthias Ringwald
5189a19cd78SMatthias Ringwald /* --- LSB values ---
5199a19cd78SMatthias Ringwald * Until the symbol read indicates the escape value 16,
5209a19cd78SMatthias Ringwald * read an LSB bit for each values.
5219a19cd78SMatthias Ringwald * The LSB mode discard the first LSB (at this step) */
5229a19cd78SMatthias Ringwald
5239a19cd78SMatthias Ringwald int u = 0, v = 0;
5249a19cd78SMatthias Ringwald int k = 0, shl = 0;
5259a19cd78SMatthias Ringwald
5269a19cd78SMatthias Ringwald unsigned s = lc3_get_symbol(bits, lc3_spectrum_models + lut[k]);
5279a19cd78SMatthias Ringwald
5289a19cd78SMatthias Ringwald if (lsb_mode && s >= 16) {
5299a19cd78SMatthias Ringwald s = lc3_get_symbol(bits, lc3_spectrum_models + lut[++k]);
5309a19cd78SMatthias Ringwald shl++;
5319a19cd78SMatthias Ringwald }
5329a19cd78SMatthias Ringwald
533*6897da5cSDirk Helbig for ( ; s >= 16 && shl < max_shl; shl++) {
5349a19cd78SMatthias Ringwald u |= lc3_get_bit(bits) << shl;
5359a19cd78SMatthias Ringwald v |= lc3_get_bit(bits) << shl;
5369a19cd78SMatthias Ringwald
5379a19cd78SMatthias Ringwald k += (k < 3);
5389a19cd78SMatthias Ringwald s = lc3_get_symbol(bits, lc3_spectrum_models + lut[k]);
5399a19cd78SMatthias Ringwald }
5409a19cd78SMatthias Ringwald
5419a19cd78SMatthias Ringwald if (s >= 16)
5429a19cd78SMatthias Ringwald return -1;
5439a19cd78SMatthias Ringwald
5449a19cd78SMatthias Ringwald /* --- MSB & sign values --- */
5459a19cd78SMatthias Ringwald
5469a19cd78SMatthias Ringwald int a = s % 4;
5479a19cd78SMatthias Ringwald int b = s / 4;
5489a19cd78SMatthias Ringwald
5499a19cd78SMatthias Ringwald u |= a << shl;
5509a19cd78SMatthias Ringwald v |= b << shl;
5519a19cd78SMatthias Ringwald
552*6897da5cSDirk Helbig x[i+0] = u && lc3_get_bit(bits) ? -u : u;
553*6897da5cSDirk Helbig x[i+1] = v && lc3_get_bit(bits) ? -v : v;
5549a19cd78SMatthias Ringwald
555*6897da5cSDirk Helbig *nf_seed = (*nf_seed + (u & 0x7fff) * (i )
556*6897da5cSDirk Helbig + (v & 0x7fff) * (i+1)) & 0xffff;
5579a19cd78SMatthias Ringwald
5589a19cd78SMatthias Ringwald /* --- Update state --- */
5599a19cd78SMatthias Ringwald
5609a19cd78SMatthias Ringwald state = (state << 4) + (k > 1 ? 12 + k : 1 + (a + b) * (k + 1));
5619a19cd78SMatthias Ringwald }
5629a19cd78SMatthias Ringwald }
5639a19cd78SMatthias Ringwald
5649a19cd78SMatthias Ringwald return 0;
5659a19cd78SMatthias Ringwald }
5669a19cd78SMatthias Ringwald
5679a19cd78SMatthias Ringwald /**
5689a19cd78SMatthias Ringwald * Put residual bits of quantization
5699a19cd78SMatthias Ringwald * bits Bitstream context
5709a19cd78SMatthias Ringwald * nbits Maximum number of bits to output
571*6897da5cSDirk Helbig * hrmode High-Resolution mode
5724930cef6SMatthias Ringwald * x, n Spectral quantized, and count of significants
5739a19cd78SMatthias Ringwald */
put_residual(lc3_bits_t * bits,int nbits,bool hrmode,float * x,int n)574*6897da5cSDirk Helbig LC3_HOT static void put_residual(lc3_bits_t *bits,
575*6897da5cSDirk Helbig int nbits, bool hrmode, float *x, int n)
5769a19cd78SMatthias Ringwald {
577*6897da5cSDirk Helbig float xq_lim = hrmode ? 0.5f : 10.f/16;
578*6897da5cSDirk Helbig float xq_off = xq_lim / 2;
579*6897da5cSDirk Helbig
580*6897da5cSDirk Helbig for (int iter = 0; iter < (hrmode ? 20 : 1) && nbits > 0; iter++) {
5819a19cd78SMatthias Ringwald for (int i = 0; i < n && nbits > 0; i++) {
5829a19cd78SMatthias Ringwald
583*6897da5cSDirk Helbig float xr = fabsf(x[i]);
584*6897da5cSDirk Helbig if (xr < xq_lim)
5859a19cd78SMatthias Ringwald continue;
5869a19cd78SMatthias Ringwald
587*6897da5cSDirk Helbig bool b = (xr - truncf(xr) < xq_lim) ^ (x[i] < 0);
588*6897da5cSDirk Helbig lc3_put_bit(bits, b);
5899a19cd78SMatthias Ringwald nbits--;
590*6897da5cSDirk Helbig
591*6897da5cSDirk Helbig x[i] += b ? -xq_off : xq_off;
592*6897da5cSDirk Helbig }
593*6897da5cSDirk Helbig
594*6897da5cSDirk Helbig xq_off *= xq_lim;
5959a19cd78SMatthias Ringwald }
5969a19cd78SMatthias Ringwald }
5979a19cd78SMatthias Ringwald
5989a19cd78SMatthias Ringwald /**
5999a19cd78SMatthias Ringwald * Get residual bits of quantization
6009a19cd78SMatthias Ringwald * bits Bitstream context
6019a19cd78SMatthias Ringwald * nbits Maximum number of bits to output
602*6897da5cSDirk Helbig * hrmode High-Resolution mode
6039a19cd78SMatthias Ringwald * x, nq Spectral quantized, and count of significants
6049a19cd78SMatthias Ringwald */
get_residual(lc3_bits_t * bits,int nbits,bool hrmode,float * x,int n)605*6897da5cSDirk Helbig LC3_HOT static void get_residual(lc3_bits_t *bits,
606*6897da5cSDirk Helbig int nbits, bool hrmode, float *x, int n)
6079a19cd78SMatthias Ringwald {
608*6897da5cSDirk Helbig float xq_off_1 = hrmode ? 0.25f : 5.f/16;
609*6897da5cSDirk Helbig float xq_off_2 = hrmode ? 0.25f : 3.f/16;
610*6897da5cSDirk Helbig
611*6897da5cSDirk Helbig for (int iter = 0; iter < (hrmode ? 20 : 1) && nbits > 0; iter++) {
612*6897da5cSDirk Helbig for (int i = 0; i < n && nbits > 0; i++) {
6139a19cd78SMatthias Ringwald
6149a19cd78SMatthias Ringwald if (x[i] == 0)
6159a19cd78SMatthias Ringwald continue;
6169a19cd78SMatthias Ringwald
6179a19cd78SMatthias Ringwald if (lc3_get_bit(bits) == 0)
618*6897da5cSDirk Helbig x[i] -= x[i] < 0 ? xq_off_1 : xq_off_2;
6199a19cd78SMatthias Ringwald else
620*6897da5cSDirk Helbig x[i] += x[i] > 0 ? xq_off_1 : xq_off_2;
6219a19cd78SMatthias Ringwald
6229a19cd78SMatthias Ringwald nbits--;
6239a19cd78SMatthias Ringwald }
624*6897da5cSDirk Helbig
625*6897da5cSDirk Helbig xq_off_1 *= 0.5f;
626*6897da5cSDirk Helbig xq_off_2 *= 0.5f;
627*6897da5cSDirk Helbig }
6289a19cd78SMatthias Ringwald }
6299a19cd78SMatthias Ringwald
6309a19cd78SMatthias Ringwald /**
6319a19cd78SMatthias Ringwald * Put LSB values of quantized spectrum values
6329a19cd78SMatthias Ringwald * bits Bitstream context
6339a19cd78SMatthias Ringwald * nbits Maximum number of bits to output
634*6897da5cSDirk Helbig * hrmode High-Resolution mode
6359a19cd78SMatthias Ringwald * x, n Spectral quantized, and count of significants
6369a19cd78SMatthias Ringwald */
put_lsb(lc3_bits_t * bits,int nbits,bool hrmode,const float * x,int n)637*6897da5cSDirk Helbig LC3_HOT static void put_lsb(lc3_bits_t *bits,
638*6897da5cSDirk Helbig int nbits, bool hrmode, const float *x, int n)
6399a19cd78SMatthias Ringwald {
6409a19cd78SMatthias Ringwald for (int i = 0; i < n && nbits > 0; i += 2) {
641*6897da5cSDirk Helbig
642*6897da5cSDirk Helbig float xq_off = hrmode ? 0.5f : 6.f/16;
643*6897da5cSDirk Helbig uint32_t a = fabsf(x[i+0]) + xq_off;
644*6897da5cSDirk Helbig uint32_t b = fabsf(x[i+1]) + xq_off;
6459a19cd78SMatthias Ringwald
6469a19cd78SMatthias Ringwald if ((a | b) >> 2 == 0)
6479a19cd78SMatthias Ringwald continue;
6489a19cd78SMatthias Ringwald
6499a19cd78SMatthias Ringwald if (nbits-- > 0)
6509a19cd78SMatthias Ringwald lc3_put_bit(bits, a & 1);
6519a19cd78SMatthias Ringwald
6529a19cd78SMatthias Ringwald if (a == 1 && nbits-- > 0)
653*6897da5cSDirk Helbig lc3_put_bit(bits, x[i+0] < 0);
6549a19cd78SMatthias Ringwald
6559a19cd78SMatthias Ringwald if (nbits-- > 0)
6569a19cd78SMatthias Ringwald lc3_put_bit(bits, b & 1);
6579a19cd78SMatthias Ringwald
6589a19cd78SMatthias Ringwald if (b == 1 && nbits-- > 0)
659*6897da5cSDirk Helbig lc3_put_bit(bits, x[i+1] < 0);
6609a19cd78SMatthias Ringwald }
6619a19cd78SMatthias Ringwald }
6629a19cd78SMatthias Ringwald
6639a19cd78SMatthias Ringwald /**
6649a19cd78SMatthias Ringwald * Get LSB values of quantized spectrum values
6659a19cd78SMatthias Ringwald * bits Bitstream context
6669a19cd78SMatthias Ringwald * nbits Maximum number of bits to output
6679a19cd78SMatthias Ringwald * x, nq Spectral quantized, and count of significants
6689a19cd78SMatthias Ringwald * nf_seed Update the noise factor seed according
6699a19cd78SMatthias Ringwald */
get_lsb(lc3_bits_t * bits,int nbits,float * x,int nq,uint16_t * nf_seed)6704930cef6SMatthias Ringwald LC3_HOT static void get_lsb(lc3_bits_t *bits,
6719a19cd78SMatthias Ringwald int nbits, float *x, int nq, uint16_t *nf_seed)
6729a19cd78SMatthias Ringwald {
6739a19cd78SMatthias Ringwald for (int i = 0; i < nq && nbits > 0; i += 2) {
6749a19cd78SMatthias Ringwald
6759a19cd78SMatthias Ringwald float a = fabsf(x[i]), b = fabsf(x[i+1]);
6769a19cd78SMatthias Ringwald
6779a19cd78SMatthias Ringwald if (fmaxf(a, b) < 4)
6789a19cd78SMatthias Ringwald continue;
6799a19cd78SMatthias Ringwald
6809a19cd78SMatthias Ringwald if (nbits-- > 0 && lc3_get_bit(bits)) {
6819a19cd78SMatthias Ringwald if (a) {
6829a19cd78SMatthias Ringwald x[i] += x[i] < 0 ? -1 : 1;
6839a19cd78SMatthias Ringwald *nf_seed = (*nf_seed + i) & 0xffff;
6849a19cd78SMatthias Ringwald } else if (nbits-- > 0) {
6859a19cd78SMatthias Ringwald x[i] = lc3_get_bit(bits) ? -1 : 1;
6869a19cd78SMatthias Ringwald *nf_seed = (*nf_seed + i) & 0xffff;
6879a19cd78SMatthias Ringwald }
6889a19cd78SMatthias Ringwald }
6899a19cd78SMatthias Ringwald
6909a19cd78SMatthias Ringwald if (nbits-- > 0 && lc3_get_bit(bits)) {
6919a19cd78SMatthias Ringwald if (b) {
6929a19cd78SMatthias Ringwald x[i+1] += x[i+1] < 0 ? -1 : 1;
6939a19cd78SMatthias Ringwald *nf_seed = (*nf_seed + i+1) & 0xffff;
6949a19cd78SMatthias Ringwald } else if (nbits-- > 0) {
6959a19cd78SMatthias Ringwald x[i+1] = lc3_get_bit(bits) ? -1 : 1;
6969a19cd78SMatthias Ringwald *nf_seed = (*nf_seed + i+1) & 0xffff;
6979a19cd78SMatthias Ringwald }
6989a19cd78SMatthias Ringwald }
6999a19cd78SMatthias Ringwald }
7009a19cd78SMatthias Ringwald }
7019a19cd78SMatthias Ringwald
7029a19cd78SMatthias Ringwald
7039a19cd78SMatthias Ringwald /* ----------------------------------------------------------------------------
7049a19cd78SMatthias Ringwald * Noise coding
7059a19cd78SMatthias Ringwald * -------------------------------------------------------------------------- */
7069a19cd78SMatthias Ringwald
7079a19cd78SMatthias Ringwald /**
7089a19cd78SMatthias Ringwald * Estimate noise level
7099a19cd78SMatthias Ringwald * dt, bw Duration and bandwidth of the frame
710*6897da5cSDirk Helbig * hrmode High-Resolution mode
711*6897da5cSDirk Helbig * x, n Spectral quantized, and count of significants
7129a19cd78SMatthias Ringwald * return Noise factor (0 to 7)
7139a19cd78SMatthias Ringwald */
estimate_noise(enum lc3_dt dt,enum lc3_bandwidth bw,bool hrmode,const float * x,int n)714*6897da5cSDirk Helbig LC3_HOT static int estimate_noise(
715*6897da5cSDirk Helbig enum lc3_dt dt, enum lc3_bandwidth bw, bool hrmode, const float *x, int n)
7169a19cd78SMatthias Ringwald {
717*6897da5cSDirk Helbig int bw_stop = lc3_ne(dt, (enum lc3_srate)LC3_MIN(bw, LC3_BANDWIDTH_FB));
718*6897da5cSDirk Helbig int w = 1 + (dt >= LC3_DT_7M5) + (dt>= LC3_DT_10M);
7199a19cd78SMatthias Ringwald
720*6897da5cSDirk Helbig float xq_lim = hrmode ? 0.5f : 10.f/16;
7219a19cd78SMatthias Ringwald float sum = 0;
722*6897da5cSDirk Helbig int i, ns = 0, z = 0;
7239a19cd78SMatthias Ringwald
724*6897da5cSDirk Helbig for (i = 6 * (1 + dt) - w; i < LC3_MIN(n, bw_stop); i++) {
725*6897da5cSDirk Helbig z = fabsf(x[i]) < xq_lim ? z + 1 : 0;
7269a19cd78SMatthias Ringwald if (z > 2*w)
727*6897da5cSDirk Helbig sum += fabsf(x[i - w]), ns++;
7289a19cd78SMatthias Ringwald }
7299a19cd78SMatthias Ringwald
7309a19cd78SMatthias Ringwald for ( ; i < bw_stop + w; i++)
7319a19cd78SMatthias Ringwald if (++z > 2*w)
732*6897da5cSDirk Helbig sum += fabsf(x[i - w]), ns++;
7339a19cd78SMatthias Ringwald
734*6897da5cSDirk Helbig int nf = ns ? 8 - (int)((16 * sum) / ns + 0.5f) : 8;
7359a19cd78SMatthias Ringwald
7369a19cd78SMatthias Ringwald return LC3_CLIP(nf, 0, 7);
7379a19cd78SMatthias Ringwald }
7389a19cd78SMatthias Ringwald
7399a19cd78SMatthias Ringwald /**
7409a19cd78SMatthias Ringwald * Noise filling
7419a19cd78SMatthias Ringwald * dt, bw Duration and bandwidth of the frame
7429a19cd78SMatthias Ringwald * nf, nf_seed The noise factor and pseudo-random seed
7439a19cd78SMatthias Ringwald * g Quantization gain
7449a19cd78SMatthias Ringwald * x, nq Spectral quantized, and count of significants
7459a19cd78SMatthias Ringwald */
fill_noise(enum lc3_dt dt,enum lc3_bandwidth bw,int nf,uint16_t nf_seed,float g,float * x,int nq)7464930cef6SMatthias Ringwald LC3_HOT static void fill_noise(enum lc3_dt dt, enum lc3_bandwidth bw,
7479a19cd78SMatthias Ringwald int nf, uint16_t nf_seed, float g, float *x, int nq)
7489a19cd78SMatthias Ringwald {
749*6897da5cSDirk Helbig int bw_stop = lc3_ne(dt, (enum lc3_srate)LC3_MIN(bw, LC3_BANDWIDTH_FB));
750*6897da5cSDirk Helbig int w = 1 + (dt >= LC3_DT_7M5) + (dt>= LC3_DT_10M);
7519a19cd78SMatthias Ringwald
7529a19cd78SMatthias Ringwald float s = g * (float)(8 - nf) / 16;
7539a19cd78SMatthias Ringwald int i, z = 0;
7549a19cd78SMatthias Ringwald
755*6897da5cSDirk Helbig for (i = 6 * (1 + dt) - w; i < LC3_MIN(nq, bw_stop); i++) {
7569a19cd78SMatthias Ringwald z = x[i] ? 0 : z + 1;
7579a19cd78SMatthias Ringwald if (z > 2*w) {
7589a19cd78SMatthias Ringwald nf_seed = (13849 + nf_seed*31821) & 0xffff;
7599a19cd78SMatthias Ringwald x[i - w] = nf_seed & 0x8000 ? -s : s;
7609a19cd78SMatthias Ringwald }
7619a19cd78SMatthias Ringwald }
7629a19cd78SMatthias Ringwald
7639a19cd78SMatthias Ringwald for ( ; i < bw_stop + w; i++)
7649a19cd78SMatthias Ringwald if (++z > 2*w) {
7659a19cd78SMatthias Ringwald nf_seed = (13849 + nf_seed*31821) & 0xffff;
7669a19cd78SMatthias Ringwald x[i - w] = nf_seed & 0x8000 ? -s : s;
7679a19cd78SMatthias Ringwald }
7689a19cd78SMatthias Ringwald }
7699a19cd78SMatthias Ringwald
7709a19cd78SMatthias Ringwald /**
7719a19cd78SMatthias Ringwald * Put noise factor
7729a19cd78SMatthias Ringwald * bits Bitstream context
7739a19cd78SMatthias Ringwald * nf Noise factor (0 to 7)
7749a19cd78SMatthias Ringwald */
put_noise_factor(lc3_bits_t * bits,int nf)7759a19cd78SMatthias Ringwald static void put_noise_factor(lc3_bits_t *bits, int nf)
7769a19cd78SMatthias Ringwald {
7779a19cd78SMatthias Ringwald lc3_put_bits(bits, nf, 3);
7789a19cd78SMatthias Ringwald }
7799a19cd78SMatthias Ringwald
7809a19cd78SMatthias Ringwald /**
7819a19cd78SMatthias Ringwald * Get noise factor
7829a19cd78SMatthias Ringwald * bits Bitstream context
7839a19cd78SMatthias Ringwald * return Noise factor (0 to 7)
7849a19cd78SMatthias Ringwald */
get_noise_factor(lc3_bits_t * bits)7859a19cd78SMatthias Ringwald static int get_noise_factor(lc3_bits_t *bits)
7869a19cd78SMatthias Ringwald {
7879a19cd78SMatthias Ringwald return lc3_get_bits(bits, 3);
7889a19cd78SMatthias Ringwald }
7899a19cd78SMatthias Ringwald
7909a19cd78SMatthias Ringwald
7919a19cd78SMatthias Ringwald /* ----------------------------------------------------------------------------
7929a19cd78SMatthias Ringwald * Encoding
7939a19cd78SMatthias Ringwald * -------------------------------------------------------------------------- */
7949a19cd78SMatthias Ringwald
7959a19cd78SMatthias Ringwald /**
7969a19cd78SMatthias Ringwald * Bit consumption of the number of coded coefficients
797*6897da5cSDirk Helbig * dt, sr, nbytes Duration, samplerate and size of the frame
7989a19cd78SMatthias Ringwald * return Bit consumpution of the number of coded coefficients
7999a19cd78SMatthias Ringwald */
get_nbits_nq(enum lc3_dt dt,enum lc3_srate sr)8009a19cd78SMatthias Ringwald static int get_nbits_nq(enum lc3_dt dt, enum lc3_srate sr)
8019a19cd78SMatthias Ringwald {
802*6897da5cSDirk Helbig int ne = lc3_ne(dt, sr);
803*6897da5cSDirk Helbig return 4 + (ne > 32) + (ne > 64) + (ne > 128) + (ne > 256) + (ne > 512);
8049a19cd78SMatthias Ringwald }
8059a19cd78SMatthias Ringwald
8069a19cd78SMatthias Ringwald /**
8079a19cd78SMatthias Ringwald * Bit consumption of the arithmetic coder
8089a19cd78SMatthias Ringwald * dt, sr, nbytes Duration, samplerate and size of the frame
8099a19cd78SMatthias Ringwald * return Bit consumption of bitstream data
8109a19cd78SMatthias Ringwald */
get_nbits_ac(enum lc3_dt dt,enum lc3_srate sr,int nbytes)8119a19cd78SMatthias Ringwald static int get_nbits_ac(enum lc3_dt dt, enum lc3_srate sr, int nbytes)
8129a19cd78SMatthias Ringwald {
813*6897da5cSDirk Helbig return get_nbits_nq(dt, sr) +
814*6897da5cSDirk Helbig 3 + lc3_hr(sr) + LC3_MIN((nbytes-1) / 160, 2);
8159a19cd78SMatthias Ringwald }
8169a19cd78SMatthias Ringwald
8179a19cd78SMatthias Ringwald /**
8189a19cd78SMatthias Ringwald * Spectrum analysis
8199a19cd78SMatthias Ringwald */
lc3_spec_analyze(enum lc3_dt dt,enum lc3_srate sr,int nbytes,bool pitch,const lc3_tns_data_t * tns,struct lc3_spec_analysis * spec,float * x,struct lc3_spec_side * side)820*6897da5cSDirk Helbig void lc3_spec_analyze(
821*6897da5cSDirk Helbig enum lc3_dt dt, enum lc3_srate sr, int nbytes,
822*6897da5cSDirk Helbig bool pitch, const lc3_tns_data_t *tns,
823*6897da5cSDirk Helbig struct lc3_spec_analysis *spec,
824*6897da5cSDirk Helbig float *x, struct lc3_spec_side *side)
8259a19cd78SMatthias Ringwald {
8269a19cd78SMatthias Ringwald bool reset_off;
8279a19cd78SMatthias Ringwald
8289a19cd78SMatthias Ringwald /* --- Bit budget --- */
8299a19cd78SMatthias Ringwald
8309a19cd78SMatthias Ringwald const int nbits_gain = 8;
8319a19cd78SMatthias Ringwald const int nbits_nf = 3;
8329a19cd78SMatthias Ringwald
8339a19cd78SMatthias Ringwald int nbits_budget = 8*nbytes - get_nbits_ac(dt, sr, nbytes) -
8349a19cd78SMatthias Ringwald lc3_bwdet_get_nbits(sr) - lc3_ltpf_get_nbits(pitch) -
8359a19cd78SMatthias Ringwald lc3_sns_get_nbits() - lc3_tns_get_nbits(tns) - nbits_gain - nbits_nf;
8369a19cd78SMatthias Ringwald
8379a19cd78SMatthias Ringwald /* --- Global gain --- */
8389a19cd78SMatthias Ringwald
8399a19cd78SMatthias Ringwald float nbits_off = spec->nbits_off + spec->nbits_spare;
8409a19cd78SMatthias Ringwald nbits_off = fminf(fmaxf(nbits_off, -40), 40);
8414930cef6SMatthias Ringwald nbits_off = 0.8f * spec->nbits_off + 0.2f * nbits_off;
8429a19cd78SMatthias Ringwald
8439a19cd78SMatthias Ringwald int g_off = resolve_gain_offset(sr, nbytes);
8449a19cd78SMatthias Ringwald
845*6897da5cSDirk Helbig int g_min, g_int = estimate_gain(dt, sr,
846*6897da5cSDirk Helbig x, nbytes, nbits_budget, nbits_off, g_off, &reset_off, &g_min);
8479a19cd78SMatthias Ringwald
8489a19cd78SMatthias Ringwald /* --- Quantization --- */
8499a19cd78SMatthias Ringwald
850*6897da5cSDirk Helbig quantize(dt, sr, g_int, x, &side->nq);
8519a19cd78SMatthias Ringwald
852*6897da5cSDirk Helbig int nbits = compute_nbits(dt, sr, nbytes, x, &side->nq, 0, NULL);
8539a19cd78SMatthias Ringwald
8549a19cd78SMatthias Ringwald spec->nbits_off = reset_off ? 0 : nbits_off;
8559a19cd78SMatthias Ringwald spec->nbits_spare = reset_off ? 0 : nbits_budget - nbits;
8569a19cd78SMatthias Ringwald
8579a19cd78SMatthias Ringwald /* --- Adjust gain and requantize --- */
8589a19cd78SMatthias Ringwald
859*6897da5cSDirk Helbig int g_adj = adjust_gain(dt, sr,
860*6897da5cSDirk Helbig g_off + g_int, nbits, nbits_budget, g_off + g_min);
8619a19cd78SMatthias Ringwald
8629a19cd78SMatthias Ringwald if (g_adj)
863*6897da5cSDirk Helbig quantize(dt, sr, g_adj, x, &side->nq);
8649a19cd78SMatthias Ringwald
8659a19cd78SMatthias Ringwald side->g_idx = g_int + g_adj + g_off;
8669a19cd78SMatthias Ringwald nbits = compute_nbits(dt, sr, nbytes,
867*6897da5cSDirk Helbig x, &side->nq, nbits_budget, &side->lsb_mode);
8689a19cd78SMatthias Ringwald }
8699a19cd78SMatthias Ringwald
8709a19cd78SMatthias Ringwald /**
8719a19cd78SMatthias Ringwald * Put spectral quantization side data
8729a19cd78SMatthias Ringwald */
lc3_spec_put_side(lc3_bits_t * bits,enum lc3_dt dt,enum lc3_srate sr,const struct lc3_spec_side * side)8739a19cd78SMatthias Ringwald void lc3_spec_put_side(lc3_bits_t *bits,
874*6897da5cSDirk Helbig enum lc3_dt dt, enum lc3_srate sr,
875*6897da5cSDirk Helbig const struct lc3_spec_side *side)
8769a19cd78SMatthias Ringwald {
8779a19cd78SMatthias Ringwald int nbits_nq = get_nbits_nq(dt, sr);
8789a19cd78SMatthias Ringwald
8799a19cd78SMatthias Ringwald lc3_put_bits(bits, LC3_MAX(side->nq >> 1, 1) - 1, nbits_nq);
8809a19cd78SMatthias Ringwald lc3_put_bits(bits, side->lsb_mode, 1);
8819a19cd78SMatthias Ringwald lc3_put_bits(bits, side->g_idx, 8);
8829a19cd78SMatthias Ringwald }
8839a19cd78SMatthias Ringwald
8849a19cd78SMatthias Ringwald /**
8859a19cd78SMatthias Ringwald * Encode spectral coefficients
8869a19cd78SMatthias Ringwald */
lc3_spec_encode(lc3_bits_t * bits,enum lc3_dt dt,enum lc3_srate sr,enum lc3_bandwidth bw,int nbytes,const lc3_spec_side_t * side,float * x)8879a19cd78SMatthias Ringwald void lc3_spec_encode(lc3_bits_t *bits,
888*6897da5cSDirk Helbig enum lc3_dt dt, enum lc3_srate sr, enum lc3_bandwidth bw,
889*6897da5cSDirk Helbig int nbytes, const lc3_spec_side_t *side, float *x)
8909a19cd78SMatthias Ringwald {
8919a19cd78SMatthias Ringwald bool lsb_mode = side->lsb_mode;
8929a19cd78SMatthias Ringwald int nq = side->nq;
8939a19cd78SMatthias Ringwald
894*6897da5cSDirk Helbig put_noise_factor(bits, estimate_noise(dt, bw, lc3_hr(sr), x, nq));
8959a19cd78SMatthias Ringwald
896*6897da5cSDirk Helbig put_quantized(bits, dt, sr, nbytes, x, nq, lsb_mode);
8979a19cd78SMatthias Ringwald
8989a19cd78SMatthias Ringwald int nbits_left = lc3_get_bits_left(bits);
8999a19cd78SMatthias Ringwald
9009a19cd78SMatthias Ringwald if (lsb_mode)
901*6897da5cSDirk Helbig put_lsb(bits, nbits_left, lc3_hr(sr), x, nq);
9029a19cd78SMatthias Ringwald else
903*6897da5cSDirk Helbig put_residual(bits, nbits_left, lc3_hr(sr), x, nq);
9049a19cd78SMatthias Ringwald }
9059a19cd78SMatthias Ringwald
9069a19cd78SMatthias Ringwald
9079a19cd78SMatthias Ringwald /* ----------------------------------------------------------------------------
9089a19cd78SMatthias Ringwald * Decoding
9099a19cd78SMatthias Ringwald * -------------------------------------------------------------------------- */
9109a19cd78SMatthias Ringwald
9119a19cd78SMatthias Ringwald /**
9129a19cd78SMatthias Ringwald * Get spectral quantization side data
9139a19cd78SMatthias Ringwald */
lc3_spec_get_side(lc3_bits_t * bits,enum lc3_dt dt,enum lc3_srate sr,struct lc3_spec_side * side)9149a19cd78SMatthias Ringwald int lc3_spec_get_side(lc3_bits_t *bits,
9159a19cd78SMatthias Ringwald enum lc3_dt dt, enum lc3_srate sr, struct lc3_spec_side *side)
9169a19cd78SMatthias Ringwald {
9179a19cd78SMatthias Ringwald int nbits_nq = get_nbits_nq(dt, sr);
918*6897da5cSDirk Helbig int ne = lc3_ne(dt, sr);
9199a19cd78SMatthias Ringwald
9209a19cd78SMatthias Ringwald side->nq = (lc3_get_bits(bits, nbits_nq) + 1) << 1;
9219a19cd78SMatthias Ringwald side->lsb_mode = lc3_get_bit(bits);
9229a19cd78SMatthias Ringwald side->g_idx = lc3_get_bits(bits, 8);
9239a19cd78SMatthias Ringwald
9249a19cd78SMatthias Ringwald return side->nq > ne ? (side->nq = ne), -1 : 0;
9259a19cd78SMatthias Ringwald }
9269a19cd78SMatthias Ringwald
9279a19cd78SMatthias Ringwald /**
9289a19cd78SMatthias Ringwald * Decode spectral coefficients
9299a19cd78SMatthias Ringwald */
lc3_spec_decode(lc3_bits_t * bits,enum lc3_dt dt,enum lc3_srate sr,enum lc3_bandwidth bw,int nbytes,const lc3_spec_side_t * side,float * x)9309a19cd78SMatthias Ringwald int lc3_spec_decode(lc3_bits_t *bits,
9319a19cd78SMatthias Ringwald enum lc3_dt dt, enum lc3_srate sr, enum lc3_bandwidth bw,
9329a19cd78SMatthias Ringwald int nbytes, const lc3_spec_side_t *side, float *x)
9339a19cd78SMatthias Ringwald {
9349a19cd78SMatthias Ringwald bool lsb_mode = side->lsb_mode;
9359a19cd78SMatthias Ringwald int nq = side->nq;
9369a19cd78SMatthias Ringwald int ret = 0;
9379a19cd78SMatthias Ringwald
9389a19cd78SMatthias Ringwald int nf = get_noise_factor(bits);
9399a19cd78SMatthias Ringwald uint16_t nf_seed;
9409a19cd78SMatthias Ringwald
9419a19cd78SMatthias Ringwald if ((ret = get_quantized(bits, dt, sr, nbytes,
9429a19cd78SMatthias Ringwald nq, lsb_mode, x, &nf_seed)) < 0)
9439a19cd78SMatthias Ringwald return ret;
9449a19cd78SMatthias Ringwald
9459a19cd78SMatthias Ringwald int nbits_left = lc3_get_bits_left(bits);
9469a19cd78SMatthias Ringwald
9479a19cd78SMatthias Ringwald if (lsb_mode)
9489a19cd78SMatthias Ringwald get_lsb(bits, nbits_left, x, nq, &nf_seed);
9499a19cd78SMatthias Ringwald else
950*6897da5cSDirk Helbig get_residual(bits, nbits_left, lc3_hr(sr), x, nq);
9519a19cd78SMatthias Ringwald
9529a19cd78SMatthias Ringwald int g_int = side->g_idx - resolve_gain_offset(sr, nbytes);
9539a19cd78SMatthias Ringwald float g = unquantize(dt, sr, g_int, x, nq);
9549a19cd78SMatthias Ringwald
9559a19cd78SMatthias Ringwald if (nq > 2 || x[0] || x[1] || side->g_idx > 0 || nf < 7)
9569a19cd78SMatthias Ringwald fill_noise(dt, bw, nf, nf_seed, g, x, nq);
9579a19cd78SMatthias Ringwald
9589a19cd78SMatthias Ringwald return 0;
9599a19cd78SMatthias Ringwald }
960