1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2005 Magnus Holmgren
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
32 #include "replaygain.h"
34 /* The fixed point math routines (with the exception of fp_atof) are based
35 * on oMathFP by Dan Carter (http://orbisstudios.com).
38 /* 12 bits of precision gives fairly accurate result, but still allows a
39 * compact implementation. The math code supports up to 13...
43 #define FP_MASK ((1 << FP_BITS) - 1)
44 #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))
55 #define FP_MAX_DIGITS (4)
56 #define FP_MAX_DIGITS_INT (10000)
58 #define FP_FAST_MUL_DIV
60 #ifdef FP_FAST_MUL_DIV
62 /* These macros can easily overflow, but they are good enough for our uses,
63 * and saves some code.
65 #define fp_mul(x, y) (((x) * (y)) >> FP_BITS)
66 #define fp_div(x, y) (((x) << FP_BITS) / (y))
70 static long fp_mul(long x
, long y
)
76 if ((x
== 0) || (y
== 0))
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
));
98 if ((x_neg
^ y_neg
) == 1)
106 static long fp_div(long x
, long y
)
122 return (x
< 0) ? -FP_INF
: FP_INF
;
137 while ((x
& (1 << (30 - msb
))) == 0)
142 while ((y
& (1 << lsb
)) == 0)
147 shifty
= FP_BITS
- (msb
+ lsb
);
148 rc
= ((x
<< msb
) / (y
>> lsb
));
159 if ((x_neg
^ y_neg
) == 1)
167 #endif /* FP_FAST_MUL_DIV */
169 static long fp_exp(long x
)
181 k
= (fp_mul(abs(x
), FP_LN2_INV
) + FP_HALF
) & ~FP_MASK
;
188 x
-= fp_mul(k
, FP_LN2
);
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
);
196 k
= FP_ONE
>> (-k
>> FP_BITS
);
200 k
= FP_ONE
<< (k
>> FP_BITS
);
203 return fp_mul(k
, xp
);
206 static long fp_exp10(long x
)
213 return fp_exp(fp_mul(FP_LN10
, x
));
216 static long fp_atof(const char* s
, int precision
)
219 long int_one
= 1 << precision
;
222 long frac_max
= ((precision
* 4) + 12) / 13;
223 long frac_max_int
= 1;
227 while ((*s
!= '\0') && isspace(*s
))
253 else if (isdigit(*s
))
257 if (frac_count
< frac_max
)
259 frac_part
= frac_part
* 10 + (*s
- '0');
266 int_part
= int_part
* 10 + (*s
- '0');
277 while (frac_count
< frac_max
)
284 return sign
* ((int_part
* int_one
)
285 + (((int64_t) frac_part
* int_one
) / frac_max_int
));
288 static long convert_gain(long gain
)
290 /* Don't allow unreasonably low or high gain changes.
291 * Our math code can't handle it properly anyway. :)
293 if (gain
< (-48 * FP_ONE
))
298 if (gain
> (17 * FP_ONE
))
303 gain
= fp_exp10(gain
/ 20) << (24 - FP_BITS
);
308 /* Get the sample scale factor in Q7.24 format from a gain value. Returns 0
311 * str Gain in dB as a string. E.g., "-3.45 dB"; the "dB" part is ignored.
313 static long get_replaygain(const char* str
)
319 gain
= fp_atof(str
, FP_BITS
);
320 gain
= convert_gain(gain
);
326 /* Get the peak volume in Q7.24 format.
328 * str Peak volume. Full scale is specified as "1.0". Returns 0 for no peak.
330 static long get_replaypeak(const char* str
)
336 peak
= fp_atof(str
, 24);
342 /* Get a sample scale factor in Q7.24 format from a gain value.
344 * int_gain Gain in dB, multiplied by 100.
346 long get_replaygain_int(long int_gain
)
348 return convert_gain(int_gain
* FP_ONE
/ 100);
351 /* Parse a ReplayGain tag conforming to the "VorbisGain standard". If a
352 * valid tag is found, update mp3entry struct accordingly. Existing values
353 * are not overwritten. Returns number of bytes written to buffer.
355 * key Name of the tag.
356 * value Value of the tag.
357 * entry mp3entry struct to update.
358 * buffer Where to store the text for gain values (for later display).
359 * length Bytes left in buffer.
361 long parse_replaygain(const char* key
, const char* value
,
362 struct mp3entry
* entry
, char* buffer
, int length
)
366 if (((strcasecmp(key
, "replaygain_track_gain") == 0)
367 || (strcasecmp(key
, "rg_radio") == 0)) && !entry
->track_gain
)
369 entry
->track_gain
= get_replaygain(value
);
370 p
= &(entry
->track_gain_string
);
372 else if (((strcasecmp(key
, "replaygain_album_gain") == 0)
373 || (strcasecmp(key
, "rg_audiophile") == 0)) && !entry
->album_gain
)
375 entry
->album_gain
= get_replaygain(value
);
376 p
= &(entry
->album_gain_string
);
378 else if (((strcasecmp(key
, "replaygain_track_peak") == 0)
379 || (strcasecmp(key
, "rg_peak") == 0)) && !entry
->track_peak
)
381 entry
->track_peak
= get_replaypeak(value
);
383 else if ((strcasecmp(key
, "replaygain_album_peak") == 0)
384 && !entry
->album_peak
)
386 entry
->album_peak
= get_replaypeak(value
);
391 int len
= strlen(value
);
393 len
= MIN(len
, length
- 1);
395 /* A few characters just isn't interesting... */
398 strncpy(buffer
, value
, len
);
408 /* Set ReplayGain values from integers. Existing values are not overwritten.
409 * Returns number of bytes written to buffer.
411 * album If true, set album values, otherwise set track values.
412 * gain Gain value in dB, multiplied by 512. 0 for no gain.
413 * peak Peak volume in Q7.24 format, where 1.0 is full scale. 0 for no
415 * buffer Where to store the text for gain values (for later display).
416 * length Bytes left in buffer.
418 long parse_replaygain_int(bool album
, long gain
, long peak
,
419 struct mp3entry
* entry
, char* buffer
, int length
)
425 len
= snprintf(buffer
, length
, "%d.%02d dB", gain
/ 512,
426 ((abs(gain
) & 0x01ff) * 100 + 256) / 512);
432 gain
= convert_gain(gain
* FP_ONE
/ 512);
437 entry
->album_gain
= gain
;
438 entry
->album_gain_string
= buffer
;
442 entry
->album_peak
= peak
;
447 entry
->track_gain
= gain
;
448 entry
->track_gain_string
= buffer
;
452 entry
->track_peak
= peak
;