summaryrefslogtreecommitdiff
path: root/src/libfaad/sbr_fbt.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libfaad/sbr_fbt.c')
-rw-r--r--src/libfaad/sbr_fbt.c129
1 files changed, 121 insertions, 8 deletions
diff --git a/src/libfaad/sbr_fbt.c b/src/libfaad/sbr_fbt.c
index b18536b69..ae241a01e 100644
--- a/src/libfaad/sbr_fbt.c
+++ b/src/libfaad/sbr_fbt.c
@@ -22,7 +22,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
**
-** $Id: sbr_fbt.c,v 1.2 2004/01/11 15:44:05 mroi Exp $
+** $Id: sbr_fbt.c,v 1.3 2004/01/26 22:34:11 jstembridge Exp $
**/
/* Calculate frequency band tables */
@@ -184,8 +184,8 @@ uint8_t qmf_stop_channel(uint8_t bs_stop_freq, uint32_t sample_rate,
version for bs_freq_scale = 0
*/
-void master_frequency_table_fs0(sbr_info *sbr, uint8_t k0, uint8_t k2,
- uint8_t bs_alter_scale)
+uint8_t master_frequency_table_fs0(sbr_info *sbr, uint8_t k0, uint8_t k2,
+ uint8_t bs_alter_scale)
{
int8_t incr;
uint8_t k;
@@ -197,7 +197,7 @@ void master_frequency_table_fs0(sbr_info *sbr, uint8_t k0, uint8_t k2,
if (k2 <= k0)
{
sbr->N_master = 0;
- return;
+ return 0;
}
dk = bs_alter_scale ? 2 : 1;
@@ -213,6 +213,8 @@ void master_frequency_table_fs0(sbr_info *sbr, uint8_t k0, uint8_t k2,
}
#endif
nrBands = min(nrBands, 63);
+ if (nrBands <= 0)
+ return 1;
k2Achieved = k0 + nrBands * dk;
k2Diff = k2 - k2Achieved;
@@ -247,6 +249,8 @@ void master_frequency_table_fs0(sbr_info *sbr, uint8_t k0, uint8_t k2,
}
printf("\n");
#endif
+
+ return 0;
}
/*
@@ -255,22 +259,93 @@ void master_frequency_table_fs0(sbr_info *sbr, uint8_t k0, uint8_t k2,
*/
static int32_t find_bands(uint8_t warp, uint8_t bands, uint8_t a0, uint8_t a1)
{
+#ifdef FIXED_POINT
+ /* table with log2() values */
+ static const real_t log2Table[65] = {
+ COEF_CONST(0.0), COEF_CONST(0.0), COEF_CONST(1.0000000000), COEF_CONST(1.5849625007),
+ COEF_CONST(2.0000000000), COEF_CONST(2.3219280949), COEF_CONST(2.5849625007), COEF_CONST(2.8073549221),
+ COEF_CONST(3.0000000000), COEF_CONST(3.1699250014), COEF_CONST(3.3219280949), COEF_CONST(3.4594316186),
+ COEF_CONST(3.5849625007), COEF_CONST(3.7004397181), COEF_CONST(3.8073549221), COEF_CONST(3.9068905956),
+ COEF_CONST(4.0000000000), COEF_CONST(4.0874628413), COEF_CONST(4.1699250014), COEF_CONST(4.2479275134),
+ COEF_CONST(4.3219280949), COEF_CONST(4.3923174228), COEF_CONST(4.4594316186), COEF_CONST(4.5235619561),
+ COEF_CONST(4.5849625007), COEF_CONST(4.6438561898), COEF_CONST(4.7004397181), COEF_CONST(4.7548875022),
+ COEF_CONST(4.8073549221), COEF_CONST(4.8579809951), COEF_CONST(4.9068905956), COEF_CONST(4.9541963104),
+ COEF_CONST(5.0000000000), COEF_CONST(5.0443941194), COEF_CONST(5.0874628413), COEF_CONST(5.1292830169),
+ COEF_CONST(5.1699250014), COEF_CONST(5.2094533656), COEF_CONST(5.2479275134), COEF_CONST(5.2854022189),
+ COEF_CONST(5.3219280949), COEF_CONST(5.3575520046), COEF_CONST(5.3923174228), COEF_CONST(5.4262647547),
+ COEF_CONST(5.4594316186), COEF_CONST(5.4918530963), COEF_CONST(5.5235619561), COEF_CONST(5.5545888517),
+ COEF_CONST(5.5849625007), COEF_CONST(5.6147098441), COEF_CONST(5.6438561898), COEF_CONST(5.6724253420),
+ COEF_CONST(5.7004397181), COEF_CONST(5.7279204546), COEF_CONST(5.7548875022), COEF_CONST(5.7813597135),
+ COEF_CONST(5.8073549221), COEF_CONST(5.8328900142), COEF_CONST(5.8579809951), COEF_CONST(5.8826430494),
+ COEF_CONST(5.9068905956), COEF_CONST(5.9307373376), COEF_CONST(5.9541963104), COEF_CONST(5.9772799235),
+ COEF_CONST(6.0)
+ };
+ real_t r0 = log2Table[a0]; /* coef */
+ real_t r1 = log2Table[a1]; /* coef */
+ real_t r2 = (r1 - r0); /* coef */
+
+ if (warp)
+ r2 = MUL_C(r2, COEF_CONST(1.0/1.3));
+
+ /* convert r2 to real and then multiply and round */
+ r2 = (r2 >> (COEF_BITS-REAL_BITS)) * bands + (1<<(REAL_BITS-1));
+
+ return (r2 >> REAL_BITS);
+#else
real_t div = (real_t)log(2.0);
if (warp) div *= (real_t)1.3;
return (int32_t)(bands * log((float)a1/(float)a0)/div + 0.5);
+#endif
}
static real_t find_initial_power(uint8_t bands, uint8_t a0, uint8_t a1)
{
+#ifdef FIXED_POINT
+ /* table with log() values */
+ static const real_t logTable[65] = {
+ COEF_CONST(0.0), COEF_CONST(0.0), COEF_CONST(0.6931471806), COEF_CONST(1.0986122887),
+ COEF_CONST(1.3862943611), COEF_CONST(1.6094379124), COEF_CONST(1.7917594692), COEF_CONST(1.9459101491),
+ COEF_CONST(2.0794415417), COEF_CONST(2.1972245773), COEF_CONST(2.3025850930), COEF_CONST(2.3978952728),
+ COEF_CONST(2.4849066498), COEF_CONST(2.5649493575), COEF_CONST(2.6390573296), COEF_CONST(2.7080502011),
+ COEF_CONST(2.7725887222), COEF_CONST(2.8332133441), COEF_CONST(2.8903717579), COEF_CONST(2.9444389792),
+ COEF_CONST(2.9957322736), COEF_CONST(3.0445224377), COEF_CONST(3.0910424534), COEF_CONST(3.1354942159),
+ COEF_CONST(3.1780538303), COEF_CONST(3.2188758249), COEF_CONST(3.2580965380), COEF_CONST(3.2958368660),
+ COEF_CONST(3.3322045102), COEF_CONST(3.3672958300), COEF_CONST(3.4011973817), COEF_CONST(3.4339872045),
+ COEF_CONST(3.4657359028), COEF_CONST(3.4965075615), COEF_CONST(3.5263605246), COEF_CONST(3.5553480615),
+ COEF_CONST(3.5835189385), COEF_CONST(3.6109179126), COEF_CONST(3.6375861597), COEF_CONST(3.6635616461),
+ COEF_CONST(3.6888794541), COEF_CONST(3.7135720667), COEF_CONST(3.7376696183), COEF_CONST(3.7612001157),
+ COEF_CONST(3.7841896339), COEF_CONST(3.8066624898), COEF_CONST(3.8286413965), COEF_CONST(3.8501476017),
+ COEF_CONST(3.8712010109), COEF_CONST(3.8918202981), COEF_CONST(3.9120230054), COEF_CONST(3.9318256327),
+ COEF_CONST(3.9512437186), COEF_CONST(3.9702919136), COEF_CONST(3.9889840466), COEF_CONST(4.0073331852),
+ COEF_CONST(4.0253516907), COEF_CONST(4.0430512678), COEF_CONST(4.0604430105), COEF_CONST(4.0775374439),
+ COEF_CONST(4.0943445622), COEF_CONST(4.1108738642), COEF_CONST(4.1271343850), COEF_CONST(4.1431347264),
+ COEF_CONST(4.158883083)
+ };
+ /* standard Taylor polynomial coefficients for exp(x) around 0 */
+ /* a polynomial around x=1 is more precise, as most values are around 1.07,
+ but this is just fine already */
+ static const real_t c1 = COEF_CONST(1.0);
+ static const real_t c2 = COEF_CONST(1.0/2.0);
+ static const real_t c3 = COEF_CONST(1.0/6.0);
+ static const real_t c4 = COEF_CONST(1.0/24.0);
+
+ real_t r0 = logTable[a0]; /* coef */
+ real_t r1 = logTable[a1]; /* coef */
+ real_t r2 = (r1 - r0) / bands; /* coef */
+ real_t rexp = c1 + MUL_C((c1 + MUL_C((c2 + MUL_C((c3 + MUL_C(c4,r2)), r2)), r2)), r2);
+
+ return (rexp >> (COEF_BITS-REAL_BITS)); /* real */
+#else
return (real_t)pow((real_t)a1/(real_t)a0, 1.0/(real_t)bands);
+#endif
}
/*
version for bs_freq_scale > 0
*/
-void master_frequency_table(sbr_info *sbr, uint8_t k0, uint8_t k2,
- uint8_t bs_freq_scale, uint8_t bs_alter_scale)
+uint8_t master_frequency_table(sbr_info *sbr, uint8_t k0, uint8_t k2,
+ uint8_t bs_freq_scale, uint8_t bs_alter_scale)
{
uint8_t k, bands, twoRegions;
uint8_t k1;
@@ -285,12 +360,16 @@ void master_frequency_table(sbr_info *sbr, uint8_t k0, uint8_t k2,
if (k2 <= k0)
{
sbr->N_master = 0;
- return;
+ return 0;
}
bands = temp1[bs_freq_scale-1];
+#ifdef FIXED_POINT
+ if (REAL_CONST(k2) > MUL_R(REAL_CONST(k0),REAL_CONST(2.2449)))
+#else
if ((float)k2/(float)k0 > 2.2449)
+#endif
{
twoRegions = 1;
k1 = k0 << 1;
@@ -301,15 +380,26 @@ void master_frequency_table(sbr_info *sbr, uint8_t k0, uint8_t k2,
nrBand0 = 2 * find_bands(0, bands, k0, k1);
nrBand0 = min(nrBand0, 63);
+ if (nrBand0 <= 0)
+ return 1;
q = find_initial_power(nrBand0, k0, k1);
qk = REAL_CONST(k0);
+#ifdef FIXED_POINT
+ A_1 = (int32_t)((qk + REAL_CONST(0.5)) >> REAL_BITS);
+#else
A_1 = (int32_t)(qk + .5);
+#endif
for (k = 0; k <= nrBand0; k++)
{
int32_t A_0 = A_1;
+#ifdef FIXED_POINT
+ qk = MUL_R(qk,q);
+ A_1 = (int32_t)((qk + REAL_CONST(0.5)) >> REAL_BITS);
+#else
qk *= q;
A_1 = (int32_t)(qk + 0.5);
+#endif
vDk0[k] = A_1 - A_0;
}
@@ -320,6 +410,8 @@ void master_frequency_table(sbr_info *sbr, uint8_t k0, uint8_t k2,
for (k = 1; k <= nrBand0; k++)
{
vk0[k] = vk0[k-1] + vDk0[k-1];
+ if (vDk0[k-1] == 0)
+ return 1;
}
if (!twoRegions)
@@ -329,7 +421,7 @@ void master_frequency_table(sbr_info *sbr, uint8_t k0, uint8_t k2,
sbr->N_master = nrBand0;
sbr->N_master = min(sbr->N_master, 64);
- return;
+ return 0;
}
nrBand1 = 2 * find_bands(1 /* warped */, bands, k1, k2);
@@ -337,12 +429,21 @@ void master_frequency_table(sbr_info *sbr, uint8_t k0, uint8_t k2,
q = find_initial_power(nrBand1, k1, k2);
qk = REAL_CONST(k1);
+#ifdef FIXED_POINT
+ A_1 = (int32_t)((qk + REAL_CONST(0.5)) >> REAL_BITS);
+#else
A_1 = (int32_t)(qk + .5);
+#endif
for (k = 0; k <= nrBand1 - 1; k++)
{
int32_t A_0 = A_1;
+#ifdef FIXED_POINT
+ qk = MUL_R(qk,q);
+ A_1 = (int32_t)((qk + REAL_CONST(0.5)) >> REAL_BITS);
+#else
qk *= q;
A_1 = (int32_t)(qk + 0.5);
+#endif
vDk1[k] = A_1 - A_0;
}
@@ -363,6 +464,8 @@ void master_frequency_table(sbr_info *sbr, uint8_t k0, uint8_t k2,
for (k = 1; k <= nrBand1; k++)
{
vk1[k] = vk1[k-1] + vDk1[k-1];
+ if (vDk1[k-1] == 0)
+ return 1;
}
sbr->N_master = nrBand0 + nrBand1;
@@ -384,6 +487,8 @@ void master_frequency_table(sbr_info *sbr, uint8_t k0, uint8_t k2,
}
printf("\n");
#endif
+
+ return 0;
}
/* calculate the derived frequency border tables from f_master */
@@ -410,6 +515,10 @@ uint8_t derived_frequency_table(sbr_info *sbr, uint8_t bs_xover_band,
sbr->M = sbr->f_table_res[HI_RES][sbr->N_high] - sbr->f_table_res[HI_RES][0];
sbr->kx = sbr->f_table_res[HI_RES][0];
+ if (sbr->kx > 32)
+ return 1;
+ if (sbr->kx + sbr->M > 64)
+ return 1;
minus = (sbr->N_high & 1) ? 1 : 0;
@@ -556,7 +665,11 @@ restart:
#if 0
nOctaves = REAL_CONST(log((float)limTable[k]/(float)limTable[k-1])/log(2.0));
#endif
+#ifdef FIXED_POINT
+ nOctaves = SBR_DIV(REAL_CONST(limTable[k]),REAL_CONST(limTable[k-1]));
+#else
nOctaves = (real_t)limTable[k]/(real_t)limTable[k-1];
+#endif
else
nOctaves = 0;