1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
diff --git a/apps/codecs/libfaad/common.c b/apps/codecs/libfaad/common.c
index 025c8f8..67a3211 100644
--- a/apps/codecs/libfaad/common.c
+++ b/apps/codecs/libfaad/common.c
@@ -319,31 +319,6 @@ static const uint32_t pow2_tab[] ICONST_ATTR = {
     UFIX_CONST(2.000000000000000,POWTBL_PRECIS)
 };

-static const real_t log2_tab[] ICONST_ATTR = {
-    REAL_CONST(0.000000000000000), REAL_CONST(0.022367813028455), REAL_CONST(0.044394119358453),
-    REAL_CONST(0.066089190457772), REAL_CONST(0.087462841250339), REAL_CONST(0.108524456778169),
-    REAL_CONST(0.129283016944966), REAL_CONST(0.149747119504682), REAL_CONST(0.169925001442312),
-    REAL_CONST(0.189824558880017), REAL_CONST(0.209453365628950), REAL_CONST(0.228818690495881),
-    REAL_CONST(0.247927513443585), REAL_CONST(0.266786540694901), REAL_CONST(0.285402218862248),
-    REAL_CONST(0.303780748177103), REAL_CONST(0.321928094887362), REAL_CONST(0.339850002884625),
-    REAL_CONST(0.357552004618084), REAL_CONST(0.375039431346925), REAL_CONST(0.392317422778760),
-    REAL_CONST(0.409390936137702), REAL_CONST(0.426264754702098), REAL_CONST(0.442943495848728),
-    REAL_CONST(0.459431618637297), REAL_CONST(0.475733430966398), REAL_CONST(0.491853096329675),
-    REAL_CONST(0.507794640198696), REAL_CONST(0.523561956057013), REAL_CONST(0.539158811108031),
-    REAL_CONST(0.554588851677637), REAL_CONST(0.569855608330948), REAL_CONST(0.584962500721156),
-    REAL_CONST(0.599912842187128), REAL_CONST(0.614709844115208), REAL_CONST(0.629356620079610),
-    REAL_CONST(0.643856189774725), REAL_CONST(0.658211482751795), REAL_CONST(0.672425341971496),
-    REAL_CONST(0.686500527183218), REAL_CONST(0.700439718141092), REAL_CONST(0.714245517666123),
-    REAL_CONST(0.727920454563199), REAL_CONST(0.741466986401147), REAL_CONST(0.754887502163469),
-    REAL_CONST(0.768184324776926), REAL_CONST(0.781359713524660), REAL_CONST(0.794415866350106),
-    REAL_CONST(0.807354922057604), REAL_CONST(0.820178962415188), REAL_CONST(0.832890014164742),
-    REAL_CONST(0.845490050944375), REAL_CONST(0.857980995127572), REAL_CONST(0.870364719583405),
-    REAL_CONST(0.882643049361841), REAL_CONST(0.894817763307943), REAL_CONST(0.906890595608519),
-    REAL_CONST(0.918863237274595), REAL_CONST(0.930737337562886), REAL_CONST(0.942514505339240),
-    REAL_CONST(0.954196310386875), REAL_CONST(0.965784284662087), REAL_CONST(0.977279923499917),
-    REAL_CONST(0.988684686772166), REAL_CONST(1.000000000000000)
-};
-
 uint32_t pow2_fix(real_t val)
 {
     uint32_t x1, x2;
@@ -402,89 +377,39 @@ uint32_t pow2_int(real_t val)
     return retval;
 }

-/* ld(x) = ld(x*y/y) = ld(x/y) + ld(y), with y=2^N and [1 <= (x/y) < 2] */
 int32_t log2_int(uint32_t val)
 {
-    uint32_t frac;
-    int32_t exp = 0;
-    uint32_t index;
-    uint32_t index_frac;
-    uint32_t x1, x2;
-    uint32_t errcorr;
-
-    /* error */
-    if (val == 0)
-        return -10000;
-
-    exp = floor_log2(val);
-    exp -= REAL_BITS;
-
-    /* frac = [1..2] */
-    if (exp >= 0)
-        frac = val >> exp;
-    else
-        frac = val << -exp;
-
-    /* index in the log2 table */
-    index = frac >> (REAL_BITS-TABLE_BITS);
-
-    /* leftover part for linear interpolation */
-    index_frac = frac & ((1<<(REAL_BITS-TABLE_BITS))-1);
-
-    /* leave INTERP_BITS bits */
-    index_frac = index_frac >> (REAL_BITS-TABLE_BITS-INTERP_BITS);
-
-    x1 = log2_tab[index & ((1<<TABLE_BITS)-1)];
-    x2 = log2_tab[(index & ((1<<TABLE_BITS)-1)) + 1];
-
-    /* linear interpolation */
-    /* retval = exp + ((index_frac)*x2 + (1-index_frac)*x1) */
-
-    errcorr = (index_frac * (x2-x1)) >> INTERP_BITS;
-
-    return ((exp+REAL_BITS) << REAL_BITS) + errcorr + x1;
-}
-
-/* ld(x) = ld(x*y/y) = ld(x/y) + ld(y), with y=2^N and [1 <= (x/y) < 2] */
-real_t log2_fix(uint32_t val)
-{
-    uint32_t frac;
-    int8_t exp = 0;
-    uint32_t index;
-    uint32_t index_frac;
-    uint32_t x1, x2;
-    uint32_t errcorr;
-
-    /* error */
-    if (val == 0)
-        return -100000;
-
-    exp = floor_log2(val);
-    exp -= REAL_BITS;
-
-    /* frac = [1..2] */
-    if (exp >= 0)
-        frac = val >> exp;
+    uint32_t r;
+    uint32_t tmp;
+    uint32_t exp;
+#if defined(CPU_ARM) && ARM_ARCH >= 5
+    exp = __builtin_clz(val);
+    if ((exp - 1) >= 0)
+        val <<= exp - 1;
     else
-        frac = val << -exp;
-
-    /* index in the log2 table */
-    index = frac >> (REAL_BITS-TABLE_BITS);
-
-    /* leftover part for linear interpolation */
-    index_frac = frac & ((1<<(REAL_BITS-TABLE_BITS))-1);
-
-    /* leave INTERP_BITS bits */
-    index_frac = index_frac >> (REAL_BITS-TABLE_BITS-INTERP_BITS);
-
-    x1 = log2_tab[index & ((1<<TABLE_BITS)-1)];
-    x2 = log2_tab[(index & ((1<<TABLE_BITS)-1)) + 1];
-
-    /* linear interpolation */
-    /* retval = exp + ((index_frac)*x2 + (1-index_frac)*x1) */
-
-    errcorr = (index_frac * (x2-x1)) >> INTERP_BITS;
-
-    return (exp << REAL_BITS) + errcorr + x1;
+        val >>= 1;
+    val <<= exp;
+    r = (32 - exp) << 24;
+#else
+    exp = 32;
+    if (val < 0x10000) { val <<= 16; exp -= 16; }
+    if (val < 0x1000000) { val <<= 8; exp -= 8; }
+    if (val < 0x10000000) { val <<= 4; exp -= 4; }
+    if (val < 0x40000000) { val <<= 2; exp -= 2; }
+    if (val < 0x80000000) { val <<= 1; exp -= 1; }
+    r = exp << 24;
+#endif
+    tmp = val + (val >> 1); if (tmp & 0x80000000) { val = tmp; r -= 9814042; }
+    tmp = val + (val >> 2); if (tmp & 0x80000000) { val = tmp; r -= 5401057; }
+    tmp = val + (val >> 3); if (tmp & 0x80000000) { val = tmp; r -= 2850868; }
+    tmp = val + (val >> 4); if (tmp & 0x80000000) { val = tmp; r -= 1467383; }
+    tmp = val + (val >> 5); if (tmp & 0x80000000) { val = tmp; r -= 744810; }
+    tmp = val + (val >> 6); if (tmp & 0x80000000) { val = tmp; r -= 375270; }
+    tmp = val + (val >> 7); if (tmp & 0x80000000) { val = tmp; r -= 188362; }
+    val = 0x80000000 - val;
+    tmp = val - (val >> 5);
+    val = tmp - (val >> 2);
+    r -= (val) >> 6;
+    return (r) >> 10;
 }
 #endif
diff --git a/apps/codecs/libfaad/sbr_hfadj.c b/apps/codecs/libfaad/sbr_hfadj.c
index 374d16f..faeecad 100644
--- a/apps/codecs/libfaad/sbr_hfadj.c
+++ b/apps/codecs/libfaad/sbr_hfadj.c
@@ -494,13 +494,21 @@ static void calculate_gain(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch)
                 acc1 = LOG2_MIN_INF;
             else
                 acc1 = log2_int(acc1);
+            
+            /* acc2 was the argument of the only log2_int call without a
+               zero-input guard, and this was the magic value returned by
+               log2_int in that case */
+            if (acc2 == 0)
+                acc2 = -10000;
+            else
+                acc2 = log2_int(acc2);


             /* calculate the maximum gain */
             /* ratio of the energy of the original signal and the energy
              * of the HF generated signal
              */
-            G_max = acc1 - log2_int(acc2) + limGain[sbr->bs_limiter_gains];
+            G_max = acc1 - acc2 + limGain[sbr->bs_limiter_gains];
             G_max = min(G_max, limGain[3]);