mirror of
https://github.com/google/liblc3.git
synced 2026-05-24 12:15:32 +00:00
Improve storage of quantized coefficients
This commit is contained in:
@@ -199,7 +199,7 @@ static void load_s24(
|
||||
* side, xq Return frame data
|
||||
*/
|
||||
static void analyze(struct lc3_encoder *encoder,
|
||||
int nbytes, struct side_data *side, int16_t *xq)
|
||||
int nbytes, struct side_data *side, uint16_t *xq)
|
||||
{
|
||||
enum lc3_dt dt = encoder->dt;
|
||||
enum lc3_srate sr = encoder->sr;
|
||||
@@ -250,7 +250,7 @@ static void analyze(struct lc3_encoder *encoder,
|
||||
* buffer Output bitstream buffer of `nbytes` size
|
||||
*/
|
||||
static void encode(struct lc3_encoder *encoder,
|
||||
const struct side_data *side, int16_t *xq, int nbytes, void *buffer)
|
||||
const struct side_data *side, uint16_t *xq, int nbytes, void *buffer)
|
||||
{
|
||||
enum lc3_dt dt = encoder->dt;
|
||||
enum lc3_srate sr = encoder->sr;
|
||||
@@ -348,7 +348,7 @@ int lc3_encode(struct lc3_encoder *encoder, enum lc3_pcm_format fmt,
|
||||
/* --- Processing --- */
|
||||
|
||||
struct side_data side;
|
||||
int16_t xq[LC3_NE(encoder->dt, encoder->sr)];
|
||||
uint16_t xq[LC3_NE(encoder->dt, encoder->sr)];
|
||||
|
||||
load[fmt](encoder, pcm, stride);
|
||||
|
||||
|
||||
78
src/spec.c
78
src/spec.c
@@ -197,9 +197,13 @@ static float unquantize_gain(int g_int)
|
||||
* g_int Quantization gain value
|
||||
* x Spectral coefficients, scaled as output
|
||||
* xq, nq Output spectral quantized coefficients, and count
|
||||
*
|
||||
* The spectral coefficients `xq` are stored as :
|
||||
* b0 0:positive or zero 1:negative
|
||||
* b15..b1 Absolute value
|
||||
*/
|
||||
LC3_HOT static void quantize(enum lc3_dt dt, enum lc3_srate sr,
|
||||
int g_int, float *x, int16_t *xq, int *nq)
|
||||
int g_int, float *x, uint16_t *xq, int *nq)
|
||||
{
|
||||
float g_inv = 1 / unquantize_gain(g_int);
|
||||
int ne = LC3_NE(dt, sr);
|
||||
@@ -207,15 +211,16 @@ LC3_HOT static void quantize(enum lc3_dt dt, enum lc3_srate sr,
|
||||
*nq = ne;
|
||||
|
||||
for (int i = 0; i < ne; i += 2) {
|
||||
int16_t x0, x1;
|
||||
uint16_t x0, x1;
|
||||
|
||||
x[i+0] *= g_inv;
|
||||
x0 = fminf(floorf(fabsf(x[i+0]) + 6.f/16), INT16_MAX);
|
||||
xq[i+0] = x[i+0] < 0 ? -x0 : x0;
|
||||
|
||||
x[i+1] *= g_inv;
|
||||
x1 = fminf(floorf(fabsf(x[i+1]) + 6.f/16), INT16_MAX);
|
||||
xq[i+1] = x[i+1] < 0 ? -x1 : x1;
|
||||
|
||||
x0 = fminf(fabsf(x[i+0]) + 6.f/16, INT16_MAX);
|
||||
x1 = fminf(fabsf(x[i+1]) + 6.f/16, INT16_MAX);
|
||||
|
||||
xq[i+0] = (x0 << 1) + ((x0 > 0) & (x[i+0] < 0));
|
||||
xq[i+1] = (x1 << 1) + ((x1 > 0) & (x[i+1] < 0));
|
||||
|
||||
*nq = x0 || x1 ? ne : *nq - 2;
|
||||
}
|
||||
@@ -266,10 +271,14 @@ static int resolve_high_rate(enum lc3_srate sr, int nbytes)
|
||||
* 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
|
||||
*
|
||||
* The spectral coefficients `x` storage is :
|
||||
* b0 0:positive or zero 1:negative
|
||||
* b15..b1 Absolute value
|
||||
*/
|
||||
LC3_HOT static int compute_nbits(
|
||||
enum lc3_dt dt, enum lc3_srate sr, int nbytes,
|
||||
const int16_t *x, int *n, int nbits_budget, bool *p_lsb_mode)
|
||||
const uint16_t *x, int *n, int nbits_budget, bool *p_lsb_mode)
|
||||
{
|
||||
int ne = LC3_NE(dt, sr);
|
||||
|
||||
@@ -295,11 +304,11 @@ LC3_HOT static int compute_nbits(
|
||||
&& nbits <= nbits_budget; i += 2) {
|
||||
|
||||
const uint8_t *lut = lut_coeff[state];
|
||||
int a = LC3_ABS(x[i]), b = LC3_ABS(x[i+1]);
|
||||
uint16_t a = x[i] >> 1, b = x[i+1] >> 1;
|
||||
|
||||
/* --- Sign values --- */
|
||||
|
||||
int s = (a != 0) + (b != 0);
|
||||
int s = (a > 0) + (b > 0);
|
||||
nbits += s * 2048;
|
||||
|
||||
/* --- LSB values Reduce to 2*2 bits MSB values ---
|
||||
@@ -312,6 +321,7 @@ LC3_HOT static int compute_nbits(
|
||||
int m = (a | b) >> 2;
|
||||
|
||||
if (m) {
|
||||
|
||||
if (lsb_mode) {
|
||||
nbits += lc3_spectrum_bits[lut[k++]][16] - 2*2048;
|
||||
nbits_lsb += 2 + (a == 1) + (b == 1);
|
||||
@@ -362,10 +372,14 @@ LC3_HOT static int compute_nbits(
|
||||
* dt, sr, nbytes Duration, samplerate and size of the frame
|
||||
* x Spectral quantized
|
||||
* nq, lsb_mode Count of significants, and LSB discard indication
|
||||
*
|
||||
* The spectral coefficients `x` storage is :
|
||||
* b0 0:positive or zero 1:negative
|
||||
* b15..b1 Absolute value
|
||||
*/
|
||||
LC3_HOT static void put_quantized(lc3_bits_t *bits,
|
||||
enum lc3_dt dt, enum lc3_srate sr, int nbytes,
|
||||
const int16_t *x, int nq, bool lsb_mode)
|
||||
const uint16_t *x, int nq, bool lsb_mode)
|
||||
{
|
||||
int ne = LC3_NE(dt, sr);
|
||||
bool high_rate = resolve_high_rate(sr, nbytes);
|
||||
@@ -380,8 +394,7 @@ LC3_HOT static void put_quantized(lc3_bits_t *bits,
|
||||
for ( ; i < LC3_MIN(nq, (ne + 2) >> (1 - h)); i += 2) {
|
||||
|
||||
const uint8_t *lut = lut_coeff[state];
|
||||
bool a_neg = x[i] < 0, b_neg = x[i+1] < 0;
|
||||
int a = LC3_ABS(x[i]), b = LC3_ABS(x[i+1]);
|
||||
uint16_t a = x[i] >> 1, b = x[i+1] >> 1;
|
||||
|
||||
/* --- LSB values Reduce to 2*2 bits MSB values ---
|
||||
* Reduce to 2x2 bits MSB values. The LSB's pair are arithmetic
|
||||
@@ -413,8 +426,8 @@ LC3_HOT static void put_quantized(lc3_bits_t *bits,
|
||||
|
||||
/* --- Sign values --- */
|
||||
|
||||
if (a) lc3_put_bit(bits, a_neg);
|
||||
if (b) lc3_put_bit(bits, b_neg);
|
||||
if (a) lc3_put_bit(bits, x[i+0] & 1);
|
||||
if (b) lc3_put_bit(bits, x[i+1] & 1);
|
||||
|
||||
/* --- MSB values --- */
|
||||
|
||||
@@ -511,18 +524,24 @@ LC3_HOT static int get_quantized(lc3_bits_t *bits,
|
||||
* Put residual bits of quantization
|
||||
* bits Bitstream context
|
||||
* nbits Maximum number of bits to output
|
||||
* xq, n Spectral quantized, and count of significants
|
||||
* x, n Spectral quantized, and count of significants
|
||||
* xf Scaled spectral coefficients
|
||||
*
|
||||
* The spectral coefficients `x` storage is :
|
||||
* b0 0:positive or zero 1:negative
|
||||
* b15..b1 Absolute value
|
||||
*/
|
||||
LC3_HOT static void put_residual(
|
||||
lc3_bits_t *bits, int nbits, const int16_t *xq, int n, const float *xf)
|
||||
lc3_bits_t *bits, int nbits, const uint16_t *x, int n, const float *xf)
|
||||
{
|
||||
for (int i = 0; i < n && nbits > 0; i++) {
|
||||
|
||||
if (xq[i] == 0)
|
||||
if (x[i] == 0)
|
||||
continue;
|
||||
|
||||
lc3_put_bit(bits, xf[i] >= xq[i]);
|
||||
float xq = x[i] & 1 ? -(x[i] >> 1) : (x[i] >> 1);
|
||||
|
||||
lc3_put_bit(bits, xf[i] >= xq);
|
||||
nbits--;
|
||||
}
|
||||
}
|
||||
@@ -555,14 +574,17 @@ LC3_HOT static void get_residual(
|
||||
* bits Bitstream context
|
||||
* nbits Maximum number of bits to output
|
||||
* x, n Spectral quantized, and count of significants
|
||||
*
|
||||
* The spectral coefficients `x` storage is :
|
||||
* b0 0:positive or zero 1:negative
|
||||
* b15..b1 Absolute value
|
||||
*/
|
||||
LC3_HOT static void put_lsb(
|
||||
lc3_bits_t *bits, int nbits, const int16_t *x, int n)
|
||||
lc3_bits_t *bits, int nbits, const uint16_t *x, int n)
|
||||
{
|
||||
for (int i = 0; i < n && nbits > 0; i += 2) {
|
||||
|
||||
bool a_neg = x[i] < 0, b_neg = x[i+1] < 0;
|
||||
int a = LC3_ABS(x[i]), b = LC3_ABS(x[i+1]);
|
||||
uint16_t a = x[i] >> 1, b = x[i+1] >> 1;
|
||||
int a_neg = x[i] & 1, b_neg = x[i+1] & 1;
|
||||
|
||||
if ((a | b) >> 2 == 0)
|
||||
continue;
|
||||
@@ -631,9 +653,13 @@ LC3_HOT static void get_lsb(lc3_bits_t *bits,
|
||||
* xq, nq Quantized spectral coefficients
|
||||
* x Quantization scaled spectrum coefficients
|
||||
* return Noise factor (0 to 7)
|
||||
*
|
||||
* The spectral coefficients `x` storage is :
|
||||
* b0 0:positive or zero 1:negative
|
||||
* b15..b1 Absolute value
|
||||
*/
|
||||
LC3_HOT static int estimate_noise(enum lc3_dt dt, enum lc3_bandwidth bw,
|
||||
const int16_t *xq, int nq, const float *x)
|
||||
const uint16_t *xq, int nq, const float *x)
|
||||
{
|
||||
int bw_stop = (dt == LC3_DT_7M5 ? 60 : 80) * (1 + bw);
|
||||
int w = 2 + dt;
|
||||
@@ -739,7 +765,7 @@ static int get_nbits_ac(enum lc3_dt dt, enum lc3_srate sr, int nbytes)
|
||||
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,
|
||||
int16_t *xq, struct lc3_spec_side *side)
|
||||
uint16_t *xq, struct lc3_spec_side *side)
|
||||
{
|
||||
bool reset_off;
|
||||
|
||||
@@ -802,7 +828,7 @@ void lc3_spec_put_side(lc3_bits_t *bits,
|
||||
*/
|
||||
void lc3_spec_encode(lc3_bits_t *bits,
|
||||
enum lc3_dt dt, enum lc3_srate sr, enum lc3_bandwidth bw, int nbytes,
|
||||
const int16_t *xq, const lc3_spec_side_t *side, const float *x)
|
||||
const uint16_t *xq, const lc3_spec_side_t *side, const float *x)
|
||||
{
|
||||
bool lsb_mode = side->lsb_mode;
|
||||
int nq = side->nq;
|
||||
|
||||
12
src/spec.h
12
src/spec.h
@@ -54,10 +54,14 @@ typedef struct lc3_spec_side {
|
||||
* spec Context of analysis
|
||||
* x Spectral coefficients, scaled as output
|
||||
* xq, side Return quantization data
|
||||
*
|
||||
* The spectral coefficients `xq` storage is :
|
||||
* b0 0:positive or zero 1:negative
|
||||
* b15..b1 Absolute value
|
||||
*/
|
||||
void lc3_spec_analyze(enum lc3_dt dt, enum lc3_srate sr,
|
||||
int nbytes, bool pitch, const lc3_tns_data_t *tns,
|
||||
lc3_spec_analysis_t *spec, float *x, int16_t *xq, lc3_spec_side_t *side);
|
||||
lc3_spec_analysis_t *spec, float *x, uint16_t *xq, lc3_spec_side_t *side);
|
||||
|
||||
/**
|
||||
* Put spectral quantization side data
|
||||
@@ -75,10 +79,14 @@ void lc3_spec_put_side(lc3_bits_t *bits,
|
||||
* nbytes and size of the frame
|
||||
* xq, side Quantization data
|
||||
* x Scaled spectral coefficients
|
||||
*
|
||||
* The spectral coefficients `xq` storage is :
|
||||
* b0 0:positive or zero 1:negative
|
||||
* b15..b1 Absolute value
|
||||
*/
|
||||
void lc3_spec_encode(lc3_bits_t *bits,
|
||||
enum lc3_dt dt, enum lc3_srate sr, enum lc3_bandwidth bw, int nbytes,
|
||||
const int16_t *xq, const lc3_spec_side_t *side, const float *x);
|
||||
const uint16_t *xq, const lc3_spec_side_t *side, const float *x);
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
|
||||
@@ -86,8 +86,12 @@ static PyObject *quantize_py(PyObject *m, PyObject *args)
|
||||
CTYPES_CHECK("x", x_obj = to_1d_ptr(x_obj, NPY_FLOAT, ne, &x));
|
||||
|
||||
xq_obj = new_1d_ptr(NPY_INT16, ne, &xq);
|
||||
uint16_t __xq[ne];
|
||||
|
||||
quantize(dt, sr, g_int, x, xq, &nq);
|
||||
quantize(dt, sr, g_int, x, __xq, &nq);
|
||||
|
||||
for (int i = 0; i < nq; i++)
|
||||
xq[i] = __xq[i] & 1 ? -(__xq[i] >> 1) : (__xq[i] >> 1);
|
||||
|
||||
return Py_BuildValue("ONi", x_obj, xq_obj, nq);
|
||||
}
|
||||
@@ -111,8 +115,12 @@ static PyObject *compute_nbits_py(PyObject *m, PyObject *args)
|
||||
|
||||
CTYPES_CHECK("xq", xq_obj = to_1d_ptr(xq_obj, NPY_INT16, ne, &xq));
|
||||
|
||||
uint16_t __xq[ne];
|
||||
for (int i = 0; i < ne; i++)
|
||||
__xq[i] = xq[i] < 0 ? (-xq[i] << 1) + 1 : (xq[i] << 1);
|
||||
|
||||
int nbits = compute_nbits(
|
||||
dt, sr, nbytes, xq, &nq, nbits_budget, &lsb_mode);
|
||||
dt, sr, nbytes, __xq, &nq, nbits_budget, &lsb_mode);
|
||||
|
||||
return Py_BuildValue("iii", nbits, nq, lsb_mode);
|
||||
}
|
||||
@@ -140,9 +148,14 @@ static PyObject *analyze_py(PyObject *m, PyObject *args)
|
||||
CTYPES_CHECK(NULL, tns_obj = to_tns_data(tns_obj, &tns));
|
||||
CTYPES_CHECK(NULL, spec_obj = to_spec_analysis(spec_obj, &spec));
|
||||
CTYPES_CHECK("x", x_obj = to_1d_ptr(x_obj, NPY_FLOAT, ne, &x));
|
||||
xq_obj = new_1d_ptr(NPY_INT16, ne, &xq);
|
||||
|
||||
lc3_spec_analyze(dt, sr, nbytes, pitch, &tns, &spec, x, xq, &side);
|
||||
xq_obj = new_1d_ptr(NPY_INT16, ne, &xq);
|
||||
uint16_t __xq[ne];
|
||||
|
||||
lc3_spec_analyze(dt, sr, nbytes, pitch, &tns, &spec, x, __xq, &side);
|
||||
|
||||
for (int i = 0; i < ne; i++)
|
||||
xq[i] = __xq[i] & 1 ? -(__xq[i] >> 1) : (__xq[i] >> 1);
|
||||
|
||||
from_spec_analysis(spec_obj, &spec);
|
||||
return Py_BuildValue("ONN", x_obj, xq_obj, new_spec_side(&side));
|
||||
@@ -167,7 +180,11 @@ static PyObject *estimate_noise_py(PyObject *m, PyObject *args)
|
||||
CTYPES_CHECK("xq", xq_obj = to_1d_ptr(xq_obj, NPY_INT16, ne, &xq));
|
||||
CTYPES_CHECK("x" , x_obj = to_1d_ptr(x_obj, NPY_FLOAT, ne, &x ));
|
||||
|
||||
int noise_factor = estimate_noise(dt, bw, xq, nq, x);
|
||||
uint16_t __xq[nq];
|
||||
for (int i = 0; i < nq; i++)
|
||||
__xq[i] = xq[i] < 0 ? (-xq[i] << 1) + 1 : (xq[i] << 1);
|
||||
|
||||
int noise_factor = estimate_noise(dt, bw, __xq, nq, x);
|
||||
|
||||
return Py_BuildValue("i", noise_factor);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user