| /****************************************************************************** |
| * |
| * Copyright 2022 Google LLC |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at: |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| ******************************************************************************/ |
| |
| #include "spec.h" |
| #include "bits.h" |
| #include "tables.h" |
| |
| |
| /* ---------------------------------------------------------------------------- |
| * Global Gain / Quantization |
| * -------------------------------------------------------------------------- */ |
| |
| /** |
| * Resolve quantized gain index offset |
| * sr, nbytes Samplerate and size of the frame |
| * return Gain index offset |
| */ |
| static int resolve_gain_offset(enum lc3_srate sr, int nbytes) |
| { |
| int sr_ind = lc3_hr(sr) ? 4 + (sr - LC3_SRATE_48K_HR) : sr; |
| |
| int g_off = (nbytes * 8) / (10 * (1 + sr_ind)); |
| return LC3_MIN(sr >= LC3_SRATE_96K_HR ? 181 : 255, |
| 105 + 5*(1 + sr_ind) + LC3_MIN(g_off, 115)); |
| } |
| |
| /** |
| * Unquantize gain |
| * g_int Quantization gain value |
| * return Unquantized gain value |
| */ |
| static float unquantize_gain(int g_int) |
| { |
| /* Unquantization gain table : |
| * G[i] = 10 ^ (i / 28) , i = [0..27] */ |
| |
| static const float iq_table[] = { |
| 1.00000000e+00, 1.08571112e+00, 1.17876863e+00, 1.27980221e+00, |
| 1.38949549e+00, 1.50859071e+00, 1.63789371e+00, 1.77827941e+00, |
| 1.93069773e+00, 2.09617999e+00, 2.27584593e+00, 2.47091123e+00, |
| 2.68269580e+00, 2.91263265e+00, 3.16227766e+00, 3.43332002e+00, |
| 3.72759372e+00, 4.04708995e+00, 4.39397056e+00, 4.77058270e+00, |
| 5.17947468e+00, 5.62341325e+00, 6.10540230e+00, 6.62870316e+00, |
| 7.19685673e+00, 7.81370738e+00, 8.48342898e+00, 9.21055318e+00 |
| }; |
| |
| float g = 1.f; |
| |
| for ( ; g_int < 0; g_int += 28, g *= 0.1f); |
| for ( ; g_int >= 28; g_int -= 28, g *= 10.f); |
| |
| return g * iq_table[g_int]; |
| } |
| |
| /** |
| * Global Gain Estimation |
| * dt, sr Duration and samplerate of the frame |
| * x Spectral coefficients |
| * nbytes Size of the frame |
| * nbits_budget Number of bits available coding the spectrum |
| * nbits_off Offset on the available bits, temporarily smoothed |
| * g_off Gain index offset |
| * reset_off Return True when the nbits_off must be reset |
| * g_min Return lower bound of quantized gain value |
| * return The quantized gain value |
| */ |
| LC3_HOT static int 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) |
| { |
| int n4 = lc3_ne(dt, sr) / 4; |
| union { float f; int32_t q16; } e[LC3_MAX_NE / 4]; |
| |
| /* --- Signal adaptative noise floor --- */ |
| |
| int reg_bits = 0; |
| float low_bits = 0; |
| |
| if (lc3_hr(sr)) { |
| int reg_c = (const int [LC3_NUM_DT][LC3_NUM_SRATE - LC3_SRATE_48K_HR]){ |
| [LC3_DT_2M5] = { -6, -6 }, |
| [LC3_DT_5M ] = { 0, 0 }, |
| [LC3_DT_10M] = { 2, 5 } |
| }[dt][sr - LC3_SRATE_48K_HR]; |
| |
| reg_bits = (8*nbytes * 4) / (125 * (1 + dt)); |
| reg_bits = LC3_CLIP(reg_bits + reg_c, 6, 23); |
| |
| float m0 = 1e-5f, m1 = 1e-5f, k = 0; |
| |
| for (int i = 0; i < n4; i++) { |
| m0 += fabsf(x[4*i + 0]), m1 += fabsf(x[4*i + 0]) * k++; |
| m0 += fabsf(x[4*i + 1]), m1 += fabsf(x[4*i + 1]) * k++; |
| m0 += fabsf(x[4*i + 2]), m1 += fabsf(x[4*i + 2]) * k++; |
| m0 += fabsf(x[4*i + 3]), m1 += fabsf(x[4*i + 3]) * k++; |
| } |
| |
| int m = roundf((1.6f * m0) / ((1 + dt) * m1)); |
| low_bits = 8 - LC3_MIN(m, 8); |
| } |
| |
| /* --- Energy (dB) by 4 MDCT blocks --- */ |
| |
| float x2_max = 0; |
| |
| for (int i = 0; i < n4; i++) { |
| float x0 = x[4*i + 0] * x[4*i + 0]; |
| float x1 = x[4*i + 1] * x[4*i + 1]; |
| float x2 = x[4*i + 2] * x[4*i + 2]; |
| float x3 = x[4*i + 3] * x[4*i + 3]; |
| |
| x2_max = fmaxf(x2_max, x0); |
| x2_max = fmaxf(x2_max, x1); |
| x2_max = fmaxf(x2_max, x2); |
| x2_max = fmaxf(x2_max, x3); |
| |
| e[i].f = x0 + x1 + x2 + x3; |
| } |
| |
| float x_max = sqrtf(x2_max); |
| float nf = lc3_hr(sr) ? |
| lc3_ldexpf(x_max, -reg_bits) * lc3_exp2f(-low_bits) : 0; |
| |
| for (int i = 0; i < n4; i++) |
| e[i].q16 = lc3_db_q16(fmaxf(e[i].f + nf, 1e-10f)); |
| |
| /* --- Determine gain index --- */ |
| |
| int nbits = nbits_budget + nbits_off + 0.5f; |
| int g_int = 255 - g_off; |
| |
| const int k_20_28 = 20.f/28 * 0x1p16f + 0.5f; |
| const int k_2u7 = 2.7f * 0x1p16f + 0.5f; |
| const int k_1u4 = 1.4f * 0x1p16f + 0.5f; |
| |
| for (int i = 128, j, j0 = n4-1, j1 ; i > 0; i >>= 1) { |
| int gn = (g_int - i) * k_20_28; |
| int v = 0; |
| |
| for (j = j0; j >= 0 && e[j].q16 < gn; j--); |
| |
| for (j1 = j; j >= 0; j--) { |
| int e_diff = e[j].q16 - gn; |
| |
| v += e_diff < 0 ? k_2u7 : |
| e_diff < 43 << 16 ? e_diff + ( 7 << 16) |
| : 2*e_diff - (36 << 16); |
| } |
| |
| if (v > nbits * k_1u4) |
| j0 = j1; |
| else |
| g_int = g_int - i; |
| } |
| |
| /* --- Limit gain index --- */ |
| |
| float x_lim = lc3_hr(sr) ? 0x7fffp8f : 0x7fffp0f; |
| |
| *g_min = 255 - g_off; |
| for (int i = 128 ; i > 0; i >>= 1) |
| if (x_lim * unquantize_gain(*g_min - i) > x_max) |
| *g_min -= i; |
| |
| *reset_off = g_int < *g_min || x_max == 0; |
| if (*reset_off) |
| g_int = *g_min; |
| |
| return g_int; |
| } |
| |
| /** |
| * Global Gain Adjustment |
| * dt, sr Duration and samplerate of the frame |
| * g_idx The estimated quantized gain index |
| * nbits Computed number of bits coding the spectrum |
| * nbits_budget Number of bits available for coding the spectrum |
| * g_idx_min Minimum gain index value |
| * return Gain adjust value (-1 to 2) |
| */ |
| LC3_HOT static int adjust_gain( |
| enum lc3_dt dt, enum lc3_srate sr, |
| int g_idx, int nbits, int nbits_budget, int g_idx_min) |
| { |
| /* --- Compute delta threshold --- */ |
| |
| const int *t = (const int [LC3_NUM_SRATE][3]){ |
| { 80, 500, 850 }, { 230, 1025, 1700 }, { 380, 1550, 2550 }, |
| { 530, 2075, 3400 }, { 680, 2600, 4250 }, |
| { 680, 2600, 4250 }, { 830, 3125, 5100 } |
| }[sr]; |
| |
| int delta, den = 48; |
| |
| if (nbits < t[0]) { |
| delta = 3*(nbits + 48); |
| |
| } else if (nbits < t[1]) { |
| int n0 = 3*(t[0] + 48), range = t[1] - t[0]; |
| delta = n0 * range + (nbits - t[0]) * (t[1] - n0); |
| den *= range; |
| |
| } else { |
| delta = LC3_MIN(nbits, t[2]); |
| } |
| |
| delta = (delta + den/2) / den; |
| |
| /* --- Adjust gain --- */ |
| |
| if (lc3_hr(sr) && nbits > nbits_budget) { |
| int factor = 1 + (dt <= LC3_DT_5M) + |
| (dt <= LC3_DT_2M5) * (1 + (nbits >= 520)); |
| |
| int g_incr = factor + (factor * (nbits - nbits_budget)) / delta; |
| return LC3_MIN(g_idx + g_incr, 255) - g_idx; |
| } |
| |
| if (!lc3_hr(sr) && nbits < nbits_budget - (delta + 2)) |
| return -(g_idx > g_idx_min); |
| |
| if (!lc3_hr(sr) && nbits > nbits_budget) |
| return (g_idx < 255) + (g_idx < 254 && nbits >= nbits_budget + delta); |
| |
| return 0; |
| } |
| |
| /** |
| * Spectrum quantization |
| * dt, sr Duration and samplerate of the frame |
| * g_int Quantization gain value |
| * x Spectral coefficients, scaled as output |
| * n Return count of significants |
| */ |
| LC3_HOT static void quantize( |
| enum lc3_dt dt, enum lc3_srate sr, int g_int, float *x, int *n) |
| { |
| float g_inv = unquantize_gain(-g_int); |
| int ne = lc3_ne(dt, sr); |
| |
| *n = ne; |
| |
| for (int i = 0; i < ne; i += 2) { |
| float xq_min = lc3_hr(sr) ? 0.5f : 10.f/16; |
| |
| x[i+0] *= g_inv; |
| x[i+1] *= g_inv; |
| |
| *n = fabsf(x[i+0]) >= xq_min || |
| fabsf(x[i+1]) >= xq_min ? ne : *n - 2; |
| } |
| } |
| |
| /** |
| * Spectrum quantization inverse |
| * dt, sr Duration and samplerate of the frame |
| * g_int Quantization gain value |
| * x, nq Spectral quantized, and count of significants |
| * return Unquantized gain value |
| */ |
| LC3_HOT static float unquantize( |
| enum lc3_dt dt, enum lc3_srate sr, |
| int g_int, float *x, int nq) |
| { |
| float g = unquantize_gain(g_int); |
| int i, ne = lc3_ne(dt, sr); |
| |
| for (i = 0; i < nq; i++) |
| x[i] = x[i] * g; |
| |
| for ( ; i < ne; i++) |
| x[i] = 0; |
| |
| return g; |
| } |
| |
| |
| /* ---------------------------------------------------------------------------- |
| * Spectrum coding |
| * -------------------------------------------------------------------------- */ |
| |
| /** |
| * Resolve High-bitrate and LSB modes according size of the frame |
| * sr, nbytes Samplerate and size of the frame |
| * p_lsb_mode True when LSB mode allowed, when not NULL |
| * return True when High-Rate mode enabled |
| */ |
| static bool resolve_modes(enum lc3_srate sr, int nbytes, bool *p_lsb_mode) |
| { |
| int sr_ind = lc3_hr(sr) ? 4 + (sr - LC3_SRATE_48K_HR) : sr; |
| |
| if (p_lsb_mode) |
| *p_lsb_mode = (nbytes >= 20 * (3 + sr_ind)) && (sr < LC3_SRATE_96K_HR); |
| |
| return (nbytes > 20 * (1 + sr_ind)) && (sr < LC3_SRATE_96K_HR); |
| } |
| |
| /** |
| * Bit consumption |
| * dt, sr, nbytes Duration, samplerate and size of the frame |
| * x Spectral quantized coefficients |
| * n Count of significant coefficients, updated on truncation |
| * nbits_budget Truncate to stay in budget, when not zero |
| * p_lsb_mode Return True when LSB's are not AC coded, or NULL |
| * return The number of bits coding the spectrum |
| */ |
| LC3_HOT static int compute_nbits( |
| enum lc3_dt dt, enum lc3_srate sr, int nbytes, |
| const float *x, int *n, int nbits_budget, bool *p_lsb_mode) |
| { |
| bool lsb_mode, high_rate = resolve_modes(sr, nbytes, &lsb_mode); |
| int ne = lc3_ne(dt, sr); |
| |
| /* --- Loop on quantized coefficients --- */ |
| |
| int nbits = 0, nbits_lsb = 0; |
| uint8_t state = 0; |
| |
| int nbits_end = 0; |
| int n_end = 0; |
| |
| nbits_budget = nbits_budget ? nbits_budget * 2048 : INT_MAX; |
| |
| for (int i = 0, h = 0; h < 2; h++) { |
| const uint8_t (*lut_coeff)[4] = lc3_spectrum_lookup[high_rate][h]; |
| |
| for ( ; i < LC3_MIN(*n, (ne + 2) >> (1 - h)) |
| && nbits <= nbits_budget; i += 2) { |
| |
| float xq_off = lc3_hr(sr) ? 0.5f : 6.f/16; |
| uint32_t a = fabsf(x[i+0]) + xq_off; |
| uint32_t b = fabsf(x[i+1]) + xq_off; |
| |
| const uint8_t *lut = lut_coeff[state]; |
| |
| /* --- Sign values --- */ |
| |
| int s = (a != 0) + (b != 0); |
| nbits += s * 2048; |
| |
| /* --- LSB values Reduce to 2*2 bits MSB values --- |
| * Reduce to 2x2 bits MSB values. The LSB's pair are arithmetic |
| * coded with an escape code followed by 1 bit for each values. |
| * The LSB mode does not arthmetic code the first LSB, |
| * add the sign of the LSB when one of pair was at value 1 */ |
| |
| uint32_t m = (a | b) >> 2; |
| unsigned k = 0; |
| |
| if (m) { |
| |
| if (lsb_mode) { |
| nbits += lc3_spectrum_bits[lut[k++]][16] - 2*2048; |
| nbits_lsb += 2 + (a == 1) + (b == 1); |
| } |
| |
| for (m >>= lsb_mode; m; m >>= 1, k++) |
| nbits += lc3_spectrum_bits[lut[LC3_MIN(k, 3)]][16]; |
| |
| nbits += k * 2*2048; |
| a >>= k; |
| b >>= k; |
| |
| k = LC3_MIN(k, 3); |
| } |
| |
| /* --- MSB values --- */ |
| |
| nbits += lc3_spectrum_bits[lut[k]][a + 4*b]; |
| |
| /* --- Update state --- */ |
| |
| if (s && nbits <= nbits_budget) { |
| n_end = i + 2; |
| nbits_end = nbits; |
| } |
| |
| state = (state << 4) + (k > 1 ? 12 + k : 1 + (a + b) * (k + 1)); |
| } |
| } |
| |
| /* --- Return --- */ |
| |
| *n = n_end; |
| |
| if (p_lsb_mode) |
| *p_lsb_mode = lsb_mode && |
| nbits_end + nbits_lsb * 2048 > nbits_budget; |
| |
| if (nbits_budget >= INT_MAX) |
| nbits_end += nbits_lsb * 2048; |
| |
| return (nbits_end + 2047) / 2048; |
| } |
| |
| /** |
| * Put quantized spectrum |
| * bits Bitstream context |
| * dt, sr, nbytes Duration, samplerate and size of the frame |
| * x Spectral quantized coefficients |
| * nq, lsb_mode Count of significants, and LSB discard indication |
| */ |
| LC3_HOT static void put_quantized(lc3_bits_t *bits, |
| enum lc3_dt dt, enum lc3_srate sr, int nbytes, |
| const float *x, int nq, bool lsb_mode) |
| { |
| bool high_rate = resolve_modes(sr, nbytes, NULL); |
| int ne = lc3_ne(dt, sr); |
| |
| /* --- Loop on quantized coefficients --- */ |
| |
| uint8_t state = 0; |
| |
| for (int i = 0, h = 0; h < 2; h++) { |
| const uint8_t (*lut_coeff)[4] = lc3_spectrum_lookup[high_rate][h]; |
| |
| for ( ; i < LC3_MIN(nq, (ne + 2) >> (1 - h)); i += 2) { |
| |
| float xq_off = lc3_hr(sr) ? 0.5f : 6.f/16; |
| uint32_t a = fabsf(x[i+0]) + xq_off; |
| uint32_t b = fabsf(x[i+1]) + xq_off; |
| |
| const uint8_t *lut = lut_coeff[state]; |
| |
| /* --- LSB values Reduce to 2*2 bits MSB values --- |
| * Reduce to 2x2 bits MSB values. The LSB's pair are arithmetic |
| * coded with an escape code and 1 bits for each values. |
| * The LSB mode discard the first LSB (at this step) */ |
| |
| uint32_t m = (a | b) >> 2; |
| unsigned k = 0, shr = 0; |
| |
| if (m) { |
| |
| if (lsb_mode) |
| lc3_put_symbol(bits, |
| lc3_spectrum_models + lut[k++], 16); |
| |
| for (m >>= lsb_mode; m; m >>= 1, k++) { |
| lc3_put_bit(bits, (a >> k) & 1); |
| lc3_put_bit(bits, (b >> k) & 1); |
| lc3_put_symbol(bits, |
| lc3_spectrum_models + lut[LC3_MIN(k, 3)], 16); |
| } |
| |
| a >>= lsb_mode; |
| b >>= lsb_mode; |
| |
| shr = k - lsb_mode; |
| k = LC3_MIN(k, 3); |
| } |
| |
| /* --- Sign values --- */ |
| |
| if (a) lc3_put_bit(bits, x[i+0] < 0); |
| if (b) lc3_put_bit(bits, x[i+1] < 0); |
| |
| /* --- MSB values --- */ |
| |
| a >>= shr; |
| b >>= shr; |
| |
| lc3_put_symbol(bits, lc3_spectrum_models + lut[k], a + 4*b); |
| |
| /* --- Update state --- */ |
| |
| state = (state << 4) + (k > 1 ? 12 + k : 1 + (a + b) * (k + 1)); |
| } |
| } |
| } |
| |
| /** |
| * Get quantized spectrum |
| * bits Bitstream context |
| * dt, sr, nbytes Duration, samplerate and size of the frame |
| * nq, lsb_mode Count of significants, and LSB discard indication |
| * x Return `nq` spectral quantized coefficients |
| * nf_seed Return the noise factor seed associated |
| * return 0: Ok -1: Invalid bitstream data |
| */ |
| LC3_HOT static int 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) |
| { |
| bool high_rate = resolve_modes(sr, nbytes, NULL); |
| int ne = lc3_ne(dt, sr); |
| |
| *nf_seed = 0; |
| |
| /* --- Loop on quantized coefficients --- */ |
| |
| uint8_t state = 0; |
| |
| for (int i = 0, h = 0; h < 2; h++) { |
| const uint8_t (*lut_coeff)[4] = lc3_spectrum_lookup[high_rate][h]; |
| |
| for ( ; i < LC3_MIN(nq, (ne + 2) >> (1 - h)); i += 2) { |
| |
| const uint8_t *lut = lut_coeff[state]; |
| int max_shl = lc3_hr(sr) ? 22 : 14; |
| |
| /* --- LSB values --- |
| * Until the symbol read indicates the escape value 16, |
| * read an LSB bit for each values. |
| * The LSB mode discard the first LSB (at this step) */ |
| |
| int u = 0, v = 0; |
| int k = 0, shl = 0; |
| |
| unsigned s = lc3_get_symbol(bits, lc3_spectrum_models + lut[k]); |
| |
| if (lsb_mode && s >= 16) { |
| s = lc3_get_symbol(bits, lc3_spectrum_models + lut[++k]); |
| shl++; |
| } |
| |
| for ( ; s >= 16 && shl < max_shl; shl++) { |
| u |= lc3_get_bit(bits) << shl; |
| v |= lc3_get_bit(bits) << shl; |
| |
| k += (k < 3); |
| s = lc3_get_symbol(bits, lc3_spectrum_models + lut[k]); |
| } |
| |
| if (s >= 16) |
| return -1; |
| |
| /* --- MSB & sign values --- */ |
| |
| int a = s % 4; |
| int b = s / 4; |
| |
| u |= a << shl; |
| v |= b << shl; |
| |
| x[i+0] = u && lc3_get_bit(bits) ? -u : u; |
| x[i+1] = v && lc3_get_bit(bits) ? -v : v; |
| |
| *nf_seed = (*nf_seed + (u & 0x7fff) * (i ) |
| + (v & 0x7fff) * (i+1)) & 0xffff; |
| |
| /* --- Update state --- */ |
| |
| state = (state << 4) + (k > 1 ? 12 + k : 1 + (a + b) * (k + 1)); |
| } |
| } |
| |
| return 0; |
| } |
| |
| /** |
| * Put residual bits of quantization |
| * bits Bitstream context |
| * nbits Maximum number of bits to output |
| * hrmode High-Resolution mode |
| * x, n Spectral quantized, and count of significants |
| */ |
| LC3_HOT static void put_residual(lc3_bits_t *bits, |
| int nbits, bool hrmode, float *x, int n) |
| { |
| float xq_lim = hrmode ? 0.5f : 10.f/16; |
| float xq_off = xq_lim / 2; |
| |
| for (int iter = 0; iter < (hrmode ? 20 : 1) && nbits > 0; iter++) { |
| for (int i = 0; i < n && nbits > 0; i++) { |
| |
| float xr = fabsf(x[i]); |
| if (xr < xq_lim) |
| continue; |
| |
| bool b = (xr - truncf(xr) < xq_lim) ^ (x[i] < 0); |
| lc3_put_bit(bits, b); |
| nbits--; |
| |
| x[i] += b ? -xq_off : xq_off; |
| } |
| |
| xq_off *= xq_lim; |
| } |
| } |
| |
| /** |
| * Get residual bits of quantization |
| * bits Bitstream context |
| * nbits Maximum number of bits to output |
| * hrmode High-Resolution mode |
| * x, nq Spectral quantized, and count of significants |
| */ |
| LC3_HOT static void get_residual(lc3_bits_t *bits, |
| int nbits, bool hrmode, float *x, int n) |
| { |
| float xq_off_1 = hrmode ? 0.25f : 5.f/16; |
| float xq_off_2 = hrmode ? 0.25f : 3.f/16; |
| |
| for (int iter = 0; iter < (hrmode ? 20 : 1) && nbits > 0; iter++) { |
| for (int i = 0; i < n && nbits > 0; i++) { |
| |
| if (x[i] == 0) |
| continue; |
| |
| if (lc3_get_bit(bits) == 0) |
| x[i] -= x[i] < 0 ? xq_off_1 : xq_off_2; |
| else |
| x[i] += x[i] > 0 ? xq_off_1 : xq_off_2; |
| |
| nbits--; |
| } |
| |
| xq_off_1 *= 0.5f; |
| xq_off_2 *= 0.5f; |
| } |
| } |
| |
| /** |
| * Put LSB values of quantized spectrum values |
| * bits Bitstream context |
| * nbits Maximum number of bits to output |
| * hrmode High-Resolution mode |
| * x, n Spectral quantized, and count of significants |
| */ |
| LC3_HOT static void put_lsb(lc3_bits_t *bits, |
| int nbits, bool hrmode, const float *x, int n) |
| { |
| for (int i = 0; i < n && nbits > 0; i += 2) { |
| |
| float xq_off = hrmode ? 0.5f : 6.f/16; |
| uint32_t a = fabsf(x[i+0]) + xq_off; |
| uint32_t b = fabsf(x[i+1]) + xq_off; |
| |
| if ((a | b) >> 2 == 0) |
| continue; |
| |
| if (nbits-- > 0) |
| lc3_put_bit(bits, a & 1); |
| |
| if (a == 1 && nbits-- > 0) |
| lc3_put_bit(bits, x[i+0] < 0); |
| |
| if (nbits-- > 0) |
| lc3_put_bit(bits, b & 1); |
| |
| if (b == 1 && nbits-- > 0) |
| lc3_put_bit(bits, x[i+1] < 0); |
| } |
| } |
| |
| /** |
| * Get LSB values of quantized spectrum values |
| * bits Bitstream context |
| * nbits Maximum number of bits to output |
| * x, nq Spectral quantized, and count of significants |
| * nf_seed Update the noise factor seed according |
| */ |
| LC3_HOT static void get_lsb(lc3_bits_t *bits, |
| int nbits, float *x, int nq, uint16_t *nf_seed) |
| { |
| for (int i = 0; i < nq && nbits > 0; i += 2) { |
| |
| float a = fabsf(x[i]), b = fabsf(x[i+1]); |
| |
| if (fmaxf(a, b) < 4) |
| continue; |
| |
| if (nbits-- > 0 && lc3_get_bit(bits)) { |
| if (a) { |
| x[i] += x[i] < 0 ? -1 : 1; |
| *nf_seed = (*nf_seed + i) & 0xffff; |
| } else if (nbits-- > 0) { |
| x[i] = lc3_get_bit(bits) ? -1 : 1; |
| *nf_seed = (*nf_seed + i) & 0xffff; |
| } |
| } |
| |
| if (nbits-- > 0 && lc3_get_bit(bits)) { |
| if (b) { |
| x[i+1] += x[i+1] < 0 ? -1 : 1; |
| *nf_seed = (*nf_seed + i+1) & 0xffff; |
| } else if (nbits-- > 0) { |
| x[i+1] = lc3_get_bit(bits) ? -1 : 1; |
| *nf_seed = (*nf_seed + i+1) & 0xffff; |
| } |
| } |
| } |
| } |
| |
| |
| /* ---------------------------------------------------------------------------- |
| * Noise coding |
| * -------------------------------------------------------------------------- */ |
| |
| /** |
| * Estimate noise level |
| * dt, bw Duration and bandwidth of the frame |
| * hrmode High-Resolution mode |
| * x, n Spectral quantized, and count of significants |
| * return Noise factor (0 to 7) |
| */ |
| LC3_HOT static int estimate_noise( |
| enum lc3_dt dt, enum lc3_bandwidth bw, bool hrmode, const float *x, int n) |
| { |
| int bw_stop = lc3_ne(dt, (enum lc3_srate)LC3_MIN(bw, LC3_BANDWIDTH_FB)); |
| int w = 1 + (dt >= LC3_DT_7M5) + (dt>= LC3_DT_10M); |
| |
| float xq_lim = hrmode ? 0.5f : 10.f/16; |
| float sum = 0; |
| int i, ns = 0, z = 0; |
| |
| for (i = 6 * (1 + dt) - w; i < LC3_MIN(n, bw_stop); i++) { |
| z = fabsf(x[i]) < xq_lim ? z + 1 : 0; |
| if (z > 2*w) |
| sum += fabsf(x[i - w]), ns++; |
| } |
| |
| for ( ; i < bw_stop + w; i++) |
| if (++z > 2*w) |
| sum += fabsf(x[i - w]), ns++; |
| |
| int nf = ns ? 8 - (int)((16 * sum) / ns + 0.5f) : 8; |
| |
| return LC3_CLIP(nf, 0, 7); |
| } |
| |
| /** |
| * Noise filling |
| * dt, bw Duration and bandwidth of the frame |
| * nf, nf_seed The noise factor and pseudo-random seed |
| * g Quantization gain |
| * x, nq Spectral quantized, and count of significants |
| */ |
| LC3_HOT static void fill_noise(enum lc3_dt dt, enum lc3_bandwidth bw, |
| int nf, uint16_t nf_seed, float g, float *x, int nq) |
| { |
| int bw_stop = lc3_ne(dt, (enum lc3_srate)LC3_MIN(bw, LC3_BANDWIDTH_FB)); |
| int w = 1 + (dt >= LC3_DT_7M5) + (dt>= LC3_DT_10M); |
| |
| float s = g * (float)(8 - nf) / 16; |
| int i, z = 0; |
| |
| for (i = 6 * (1 + dt) - w; i < LC3_MIN(nq, bw_stop); i++) { |
| z = x[i] ? 0 : z + 1; |
| if (z > 2*w) { |
| nf_seed = (13849 + nf_seed*31821) & 0xffff; |
| x[i - w] = nf_seed & 0x8000 ? -s : s; |
| } |
| } |
| |
| for ( ; i < bw_stop + w; i++) |
| if (++z > 2*w) { |
| nf_seed = (13849 + nf_seed*31821) & 0xffff; |
| x[i - w] = nf_seed & 0x8000 ? -s : s; |
| } |
| } |
| |
| /** |
| * Put noise factor |
| * bits Bitstream context |
| * nf Noise factor (0 to 7) |
| */ |
| static void put_noise_factor(lc3_bits_t *bits, int nf) |
| { |
| lc3_put_bits(bits, nf, 3); |
| } |
| |
| /** |
| * Get noise factor |
| * bits Bitstream context |
| * return Noise factor (0 to 7) |
| */ |
| static int get_noise_factor(lc3_bits_t *bits) |
| { |
| return lc3_get_bits(bits, 3); |
| } |
| |
| |
| /* ---------------------------------------------------------------------------- |
| * Encoding |
| * -------------------------------------------------------------------------- */ |
| |
| /** |
| * Bit consumption of the number of coded coefficients |
| * dt, sr, nbytes Duration, samplerate and size of the frame |
| * return Bit consumpution of the number of coded coefficients |
| */ |
| static int get_nbits_nq(enum lc3_dt dt, enum lc3_srate sr) |
| { |
| int ne = lc3_ne(dt, sr); |
| return 4 + (ne > 32) + (ne > 64) + (ne > 128) + (ne > 256) + (ne > 512); |
| } |
| |
| /** |
| * Bit consumption of the arithmetic coder |
| * dt, sr, nbytes Duration, samplerate and size of the frame |
| * return Bit consumption of bitstream data |
| */ |
| static int get_nbits_ac(enum lc3_dt dt, enum lc3_srate sr, int nbytes) |
| { |
| return get_nbits_nq(dt, sr) + |
| 3 + lc3_hr(sr) + LC3_MIN((nbytes-1) / 160, 2); |
| } |
| |
| /** |
| * Spectrum analysis |
| */ |
| void 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) |
| { |
| bool reset_off; |
| |
| /* --- Bit budget --- */ |
| |
| const int nbits_gain = 8; |
| const int nbits_nf = 3; |
| |
| int nbits_budget = 8*nbytes - get_nbits_ac(dt, sr, nbytes) - |
| lc3_bwdet_get_nbits(sr) - lc3_ltpf_get_nbits(pitch) - |
| lc3_sns_get_nbits() - lc3_tns_get_nbits(tns) - nbits_gain - nbits_nf; |
| |
| /* --- Global gain --- */ |
| |
| float nbits_off = spec->nbits_off + spec->nbits_spare; |
| nbits_off = fminf(fmaxf(nbits_off, -40), 40); |
| nbits_off = 0.8f * spec->nbits_off + 0.2f * nbits_off; |
| |
| int g_off = resolve_gain_offset(sr, nbytes); |
| |
| int g_min, g_int = estimate_gain(dt, sr, |
| x, nbytes, nbits_budget, nbits_off, g_off, &reset_off, &g_min); |
| |
| /* --- Quantization --- */ |
| |
| quantize(dt, sr, g_int, x, &side->nq); |
| |
| int nbits = compute_nbits(dt, sr, nbytes, x, &side->nq, 0, NULL); |
| |
| spec->nbits_off = reset_off ? 0 : nbits_off; |
| spec->nbits_spare = reset_off ? 0 : nbits_budget - nbits; |
| |
| /* --- Adjust gain and requantize --- */ |
| |
| int g_adj = adjust_gain(dt, sr, |
| g_off + g_int, nbits, nbits_budget, g_off + g_min); |
| |
| if (g_adj) |
| quantize(dt, sr, g_adj, x, &side->nq); |
| |
| side->g_idx = g_int + g_adj + g_off; |
| nbits = compute_nbits(dt, sr, nbytes, |
| x, &side->nq, nbits_budget, &side->lsb_mode); |
| } |
| |
| /** |
| * Put spectral quantization side data |
| */ |
| void lc3_spec_put_side(lc3_bits_t *bits, |
| enum lc3_dt dt, enum lc3_srate sr, |
| const struct lc3_spec_side *side) |
| { |
| int nbits_nq = get_nbits_nq(dt, sr); |
| |
| lc3_put_bits(bits, LC3_MAX(side->nq >> 1, 1) - 1, nbits_nq); |
| lc3_put_bits(bits, side->lsb_mode, 1); |
| lc3_put_bits(bits, side->g_idx, 8); |
| } |
| |
| /** |
| * Encode spectral coefficients |
| */ |
| void 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) |
| { |
| bool lsb_mode = side->lsb_mode; |
| int nq = side->nq; |
| |
| put_noise_factor(bits, estimate_noise(dt, bw, lc3_hr(sr), x, nq)); |
| |
| put_quantized(bits, dt, sr, nbytes, x, nq, lsb_mode); |
| |
| int nbits_left = lc3_get_bits_left(bits); |
| |
| if (lsb_mode) |
| put_lsb(bits, nbits_left, lc3_hr(sr), x, nq); |
| else |
| put_residual(bits, nbits_left, lc3_hr(sr), x, nq); |
| } |
| |
| |
| /* ---------------------------------------------------------------------------- |
| * Decoding |
| * -------------------------------------------------------------------------- */ |
| |
| /** |
| * Get spectral quantization side data |
| */ |
| int lc3_spec_get_side(lc3_bits_t *bits, |
| enum lc3_dt dt, enum lc3_srate sr, struct lc3_spec_side *side) |
| { |
| int nbits_nq = get_nbits_nq(dt, sr); |
| int ne = lc3_ne(dt, sr); |
| |
| side->nq = (lc3_get_bits(bits, nbits_nq) + 1) << 1; |
| side->lsb_mode = lc3_get_bit(bits); |
| side->g_idx = lc3_get_bits(bits, 8); |
| |
| return side->nq > ne ? (side->nq = ne), -1 : 0; |
| } |
| |
| /** |
| * Decode spectral coefficients |
| */ |
| int 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) |
| { |
| bool lsb_mode = side->lsb_mode; |
| int nq = side->nq; |
| int ret = 0; |
| |
| int nf = get_noise_factor(bits); |
| uint16_t nf_seed; |
| |
| if ((ret = get_quantized(bits, dt, sr, nbytes, |
| nq, lsb_mode, x, &nf_seed)) < 0) |
| return ret; |
| |
| int nbits_left = lc3_get_bits_left(bits); |
| |
| if (lsb_mode) |
| get_lsb(bits, nbits_left, x, nq, &nf_seed); |
| else |
| get_residual(bits, nbits_left, lc3_hr(sr), x, nq); |
| |
| int g_int = side->g_idx - resolve_gain_offset(sr, nbytes); |
| float g = unquantize(dt, sr, g_int, x, nq); |
| |
| if (nq > 2 || x[0] || x[1] || side->g_idx > 0 || nf < 7) |
| fill_noise(dt, bw, nf, nf_seed, g, x, nq); |
| |
| return 0; |
| } |