feature: Add High-Resolution LC3 plus mode

Duplicate interfaces for HR mode

spec: Remove intermediate quantized table

fix: legacy lc3_frame_bytes() and lc3_resolve_bitrate()

Cosmetic: rename fast_xxx math function to lc3_xxx
This commit is contained in:
Antoine Soulier
2023-12-21 15:42:08 -08:00
parent 149cb6537e
commit daa580235e
46 changed files with 4518 additions and 1149 deletions

View File

@@ -160,7 +160,7 @@ LC3_HOT static inline void fft_bf2(
/**
* Perform FFT
* x, y0, y1 Input, and 2 scratch buffers of size `n`
* n Number of points 30, 40, 60, 80, 90, 120, 160, 180, 240
* n Number of points 30, 40, 60, 80, 90, 120, 160, 180, 240, 480
* return The buffer `y0` or `y1` that hold the result
*
* Input `x` can be the same as the `y0` second scratch buffer
@@ -175,9 +175,9 @@ static struct lc3_complex *fft(const struct lc3_complex *x, int n,
*
* n = 5^1 * 3^n3 * 2^n2
*
* for n = 10, 20, 40, 80, 160 n3 = 0, n2 = [1..5]
* n = 30, 60, 120, 240 n3 = 1, n2 = [1..4]
* n = 90, 180 n3 = 2, n2 = [1..2]
* for n = 10, 20, 40, 80, 160 n3 = 0, n2 = [1..5]
* n = 30, 60, 120, 240, 480 n3 = 1, n2 = [1..5]
* n = 90, 180 n3 = 2, n2 = [1..2]
*
* Note that the expression `n & (n-1) == 0` is equivalent
* to the check that `n` is a power of 2. */
@@ -200,16 +200,18 @@ static struct lc3_complex *fft(const struct lc3_complex *x, int n,
/**
* Windowing of samples before MDCT
* dt, sr Duration and samplerate (size of the transform)
* dt, sr Duration and samplerate
* x, y Input current and delayed samples
* y, d Output windowed samples, and delayed ones
*/
LC3_HOT static void mdct_window(enum lc3_dt dt, enum lc3_srate sr,
LC3_HOT static void mdct_window(
enum lc3_dt dt, enum lc3_srate sr,
const float *x, float *d, float *y)
{
int ns = LC3_NS(dt, sr), nd = LC3_ND(dt, sr);
const float *win = lc3_mdct_win[dt][sr];
int ns = lc3_ns(dt, sr), nd = lc3_nd(dt, sr);
const float *w0 = lc3_mdct_win[dt][sr], *w1 = w0 + ns;
const float *w0 = win, *w1 = w0 + ns;
const float *w2 = w1, *w3 = w2 + nd;
const float *x0 = x + ns-nd, *x1 = x0;
@@ -362,7 +364,8 @@ LC3_HOT static void imdct_post_fft(const struct lc3_mdct_rot_def *def,
* x, d Middle half of IMDCT coefficients and delayed samples
* y, d Output samples and delayed ones
*/
LC3_HOT static void imdct_window(enum lc3_dt dt, enum lc3_srate sr,
LC3_HOT static void imdct_window(
enum lc3_dt dt, enum lc3_srate sr,
const float *x, float *d, float *y)
{
/* The full MDCT coefficients is given by symmetry :
@@ -371,8 +374,9 @@ LC3_HOT static void imdct_window(enum lc3_dt dt, enum lc3_srate sr,
* T[ n/2 .. 3n/4-1] = half[n/4 .. n/2-1]
* T[3n/4 .. n-1] = half[n/2-1 .. n/4 ] */
int n4 = LC3_NS(dt, sr) >> 1, nd = LC3_ND(dt, sr);
const float *w2 = lc3_mdct_win[dt][sr], *w0 = w2 + 3*n4, *w1 = w0;
const float *win = lc3_mdct_win[dt][sr];
int n4 = lc3_ns(dt, sr) >> 1, nd = lc3_nd(dt, sr);
const float *w2 = win, *w0 = w2 + 3*n4, *w1 = w0;
const float *x0 = d + nd-n4, *x1 = x0;
float *y0 = y + nd-n4, *y1 = y0, *y2 = d + nd, *y3 = d;
@@ -423,12 +427,13 @@ LC3_HOT static void rescale(float *x, int n, float f)
/**
* Forward MDCT transformation
*/
void lc3_mdct_forward(enum lc3_dt dt, enum lc3_srate sr,
enum lc3_srate sr_dst, const float *x, float *d, float *y)
void lc3_mdct_forward(
enum lc3_dt dt, enum lc3_srate sr, enum lc3_srate sr_dst,
const float *x, float *d, float *y)
{
const struct lc3_mdct_rot_def *rot = lc3_mdct_rot[dt][sr];
int ns_dst = LC3_NS(dt, sr_dst);
int ns = LC3_NS(dt, sr);
int ns_dst = lc3_ns(dt, sr_dst);
int ns = lc3_ns(dt, sr);
struct lc3_complex buffer[LC3_MAX_NS / 2];
struct lc3_complex *z = (struct lc3_complex *)y;
@@ -447,12 +452,13 @@ void lc3_mdct_forward(enum lc3_dt dt, enum lc3_srate sr,
/**
* Inverse MDCT transformation
*/
void lc3_mdct_inverse(enum lc3_dt dt, enum lc3_srate sr,
enum lc3_srate sr_src, const float *x, float *d, float *y)
void lc3_mdct_inverse(
enum lc3_dt dt, enum lc3_srate sr, enum lc3_srate sr_src,
const float *x, float *d, float *y)
{
const struct lc3_mdct_rot_def *rot = lc3_mdct_rot[dt][sr];
int ns_src = LC3_NS(dt, sr_src);
int ns = LC3_NS(dt, sr);
int ns_src = lc3_ns(dt, sr_src);
int ns = lc3_ns(dt, sr);
struct lc3_complex buffer[LC3_MAX_NS / 2];
struct lc3_complex *z = (struct lc3_complex *)y;