summaryrefslogtreecommitdiff
path: root/apps/replaygain.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/replaygain.c')
-rw-r--r--apps/replaygain.c181
1 files changed, 2 insertions, 179 deletions
diff --git a/apps/replaygain.c b/apps/replaygain.c
index 90944f91d0..b398afc294 100644
--- a/apps/replaygain.c
+++ b/apps/replaygain.c
@@ -30,188 +30,11 @@
30#include "metadata.h" 30#include "metadata.h"
31#include "debug.h" 31#include "debug.h"
32#include "replaygain.h" 32#include "replaygain.h"
33 33#include "fixedpoint.h"
34/* The fixed point math routines (with the exception of fp_atof) are based
35 * on oMathFP by Dan Carter (http://orbisstudios.com).
36 */
37
38/* 12 bits of precision gives fairly accurate result, but still allows a
39 * compact implementation. The math code supports up to 13...
40 */
41 34
42#define FP_BITS (12) 35#define FP_BITS (12)
43#define FP_MASK ((1 << FP_BITS) - 1)
44#define FP_ONE (1 << FP_BITS) 36#define FP_ONE (1 << FP_BITS)
45#define FP_TWO (2 << FP_BITS)
46#define FP_HALF (1 << (FP_BITS - 1))
47#define FP_LN2 ( 45426 >> (16 - FP_BITS))
48#define FP_LN2_INV ( 94548 >> (16 - FP_BITS))
49#define FP_EXP_ZERO ( 10922 >> (16 - FP_BITS))
50#define FP_EXP_ONE ( -182 >> (16 - FP_BITS))
51#define FP_EXP_TWO ( 4 >> (16 - FP_BITS))
52#define FP_INF (0x7fffffff)
53#define FP_LN10 (150902 >> (16 - FP_BITS))
54
55#define FP_MAX_DIGITS (4)
56#define FP_MAX_DIGITS_INT (10000)
57
58#define FP_FAST_MUL_DIV
59
60#ifdef FP_FAST_MUL_DIV
61
62/* These macros can easily overflow, but they are good enough for our uses,
63 * and saves some code.
64 */
65#define fp_mul(x, y) (((x) * (y)) >> FP_BITS)
66#define fp_div(x, y) (((x) << FP_BITS) / (y))
67
68#else
69
70static long fp_mul(long x, long y)
71{
72 long x_neg = 0;
73 long y_neg = 0;
74 long rc;
75
76 if ((x == 0) || (y == 0))
77 {
78 return 0;
79 }
80
81 if (x < 0)
82 {
83 x_neg = 1;
84 x = -x;
85 }
86
87 if (y < 0)
88 {
89 y_neg = 1;
90 y = -y;
91 }
92
93 rc = (((x >> FP_BITS) * (y >> FP_BITS)) << FP_BITS)
94 + (((x & FP_MASK) * (y & FP_MASK)) >> FP_BITS)
95 + ((x & FP_MASK) * (y >> FP_BITS))
96 + ((x >> FP_BITS) * (y & FP_MASK));
97
98 if ((x_neg ^ y_neg) == 1)
99 {
100 rc = -rc;
101 }
102
103 return rc;
104}
105
106static long fp_div(long x, long y)
107{
108 long x_neg = 0;
109 long y_neg = 0;
110 long shifty;
111 long rc;
112 int msb = 0;
113 int lsb = 0;
114
115 if (x == 0)
116 {
117 return 0;
118 }
119
120 if (y == 0)
121 {
122 return (x < 0) ? -FP_INF : FP_INF;
123 }
124
125 if (x < 0)
126 {
127 x_neg = 1;
128 x = -x;
129 }
130
131 if (y < 0)
132 {
133 y_neg = 1;
134 y = -y;
135 }
136
137 while ((x & BIT_N(30 - msb)) == 0)
138 {
139 msb++;
140 }
141
142 while ((y & BIT_N(lsb)) == 0)
143 {
144 lsb++;
145 }
146
147 shifty = FP_BITS - (msb + lsb);
148 rc = ((x << msb) / (y >> lsb));
149 37
150 if (shifty > 0)
151 {
152 rc <<= shifty;
153 }
154 else
155 {
156 rc >>= -shifty;
157 }
158
159 if ((x_neg ^ y_neg) == 1)
160 {
161 rc = -rc;
162 }
163
164 return rc;
165}
166
167#endif /* FP_FAST_MUL_DIV */
168
169static long fp_exp(long x)
170{
171 long k;
172 long z;
173 long R;
174 long xp;
175
176 if (x == 0)
177 {
178 return FP_ONE;
179 }
180
181 k = (fp_mul(abs(x), FP_LN2_INV) + FP_HALF) & ~FP_MASK;
182
183 if (x < 0)
184 {
185 k = -k;
186 }
187
188 x -= fp_mul(k, FP_LN2);
189 z = fp_mul(x, x);
190 R = FP_TWO + fp_mul(z, FP_EXP_ZERO + fp_mul(z, FP_EXP_ONE
191 + fp_mul(z, FP_EXP_TWO)));
192 xp = FP_ONE + fp_div(fp_mul(FP_TWO, x), R - x);
193
194 if (k < 0)
195 {
196 k = FP_ONE >> (-k >> FP_BITS);
197 }
198 else
199 {
200 k = FP_ONE << (k >> FP_BITS);
201 }
202
203 return fp_mul(k, xp);
204}
205
206static long fp_exp10(long x)
207{
208 if (x == 0)
209 {
210 return FP_ONE;
211 }
212
213 return fp_exp(fp_mul(FP_LN10, x));
214}
215 38
216static long fp_atof(const char* s, int precision) 39static long fp_atof(const char* s, int precision)
217{ 40{
@@ -300,7 +123,7 @@ static long convert_gain(long gain)
300 gain = 17 * FP_ONE; 123 gain = 17 * FP_ONE;
301 } 124 }
302 125
303 gain = fp_exp10(gain / 20) << (24 - FP_BITS); 126 gain = fp_factor(gain, FP_BITS) << (24 - FP_BITS);
304 127
305 return gain; 128 return gain;
306} 129}