summaryrefslogtreecommitdiffstats
path: root/apps/replaygain.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/replaygain.c')
-rw-r--r--apps/replaygain.c130
1 files changed, 33 insertions, 97 deletions
diff --git a/apps/replaygain.c b/apps/replaygain.c
index 81f1a45ad7..9f0dda7a0b 100644
--- a/apps/replaygain.c
+++ b/apps/replaygain.c
@@ -36,6 +36,13 @@
#define FP_BITS (12)
#define FP_ONE (1 << FP_BITS)
+void replaygain_itoa(char* buffer, int length, long int_gain)
+{
+ /* int_gain uses Q19.12 format. */
+ int one = abs(int_gain) >> FP_BITS;
+ int cent = ((abs(int_gain) & 0x0fff) * 100 + (FP_ONE/2)) >> FP_BITS;
+ snprintf(buffer, length, "%d.%02d dB", (int_gain<0) ? -one : one, cent);
+}
static long fp_atof(const char* s, int precision)
{
@@ -109,42 +116,25 @@ static long fp_atof(const char* s, int precision)
+ (((int64_t) frac_part * int_one) / frac_max_int));
}
-static long convert_gain(long gain)
+long convert_gain(long gain)
{
/* Don't allow unreasonably low or high gain changes.
* Our math code can't handle it properly anyway. :)
*/
- if (gain < (-48 * FP_ONE))
- {
- gain = -48 * FP_ONE;
- }
-
- if (gain > (17 * FP_ONE))
- {
- gain = 17 * FP_ONE;
- }
-
- gain = fp_factor(gain, FP_BITS) << (24 - FP_BITS);
+ gain = MAX(gain,-48 * FP_ONE);
+ gain = MIN(gain, 17 * FP_ONE);
- return gain;
+ return fp_factor(gain, FP_BITS) << (24 - FP_BITS);
}
-/* Get the sample scale factor in Q7.24 format from a gain value. Returns 0
+/* Get the sample scale factor in Q19.12 format from a gain value. Returns 0
* for no gain.
*
* str Gain in dB as a string. E.g., "-3.45 dB"; the "dB" part is ignored.
*/
static long get_replaygain(const char* str)
{
- long gain = 0;
-
- if (str)
- {
- gain = fp_atof(str, FP_BITS);
- gain = convert_gain(gain);
- }
-
- return gain;
+ return fp_atof(str, FP_BITS);
}
/* Get the peak volume in Q7.24 format.
@@ -153,14 +143,7 @@ static long get_replaygain(const char* str)
*/
static long get_replaypeak(const char* str)
{
- long peak = 0;
-
- if (str)
- {
- peak = fp_atof(str, 24);
- }
-
- return peak;
+ return fp_atof(str, 24);
}
/* Get a sample scale factor in Q7.24 format from a gain value.
@@ -174,107 +157,60 @@ long get_replaygain_int(long int_gain)
/* Parse a ReplayGain tag conforming to the "VorbisGain standard". If a
* valid tag is found, update mp3entry struct accordingly. Existing values
- * are not overwritten. Returns number of bytes written to buffer.
+ * are not overwritten.
*
* key Name of the tag.
* value Value of the tag.
* entry mp3entry struct to update.
- * buffer Where to store the text for gain values (for later display).
- * length Bytes left in buffer.
*/
-long parse_replaygain(const char* key, const char* value,
- struct mp3entry* entry, char* buffer, int length)
+void parse_replaygain(const char* key, const char* value,
+ struct mp3entry* entry)
{
- char **p = NULL;
-
- if (((strcasecmp(key, "replaygain_track_gain") == 0)
- || (strcasecmp(key, "rg_radio") == 0)) && !entry->track_gain)
+ if (((strcasecmp(key, "replaygain_track_gain") == 0) ||
+ (strcasecmp(key, "rg_radio") == 0)) &&
+ !entry->track_gain)
{
entry->track_gain = get_replaygain(value);
- p = &(entry->track_gain_string);
}
- else if (((strcasecmp(key, "replaygain_album_gain") == 0)
- || (strcasecmp(key, "rg_audiophile") == 0)) && !entry->album_gain)
+ else if (((strcasecmp(key, "replaygain_album_gain") == 0) ||
+ (strcasecmp(key, "rg_audiophile") == 0)) &&
+ !entry->album_gain)
{
entry->album_gain = get_replaygain(value);
- p = &(entry->album_gain_string);
}
- else if (((strcasecmp(key, "replaygain_track_peak") == 0)
- || (strcasecmp(key, "rg_peak") == 0)) && !entry->track_peak)
+ else if (((strcasecmp(key, "replaygain_track_peak") == 0) ||
+ (strcasecmp(key, "rg_peak") == 0)) &&
+ !entry->track_peak)
{
entry->track_peak = get_replaypeak(value);
}
- else if ((strcasecmp(key, "replaygain_album_peak") == 0)
- && !entry->album_peak)
+ else if ((strcasecmp(key, "replaygain_album_peak") == 0) &&
+ !entry->album_peak)
{
entry->album_peak = get_replaypeak(value);
}
-
- if (p)
- {
- int len = strlen(value);
-
- len = MIN(len, length - 1);
-
- /* A few characters just isn't interesting... */
- if (len > 1)
- {
- strlcpy(buffer, value, len + 1);
- *p = buffer;
- return len + 1;
- }
- }
-
- return 0;
}
/* Set ReplayGain values from integers. Existing values are not overwritten.
- * Returns number of bytes written to buffer.
*
* album If true, set album values, otherwise set track values.
* gain Gain value in dB, multiplied by 512. 0 for no gain.
* peak Peak volume in Q7.24 format, where 1.0 is full scale. 0 for no
* peak volume.
- * buffer Where to store the text for gain values (for later display).
- * length Bytes left in buffer.
*/
-long parse_replaygain_int(bool album, long gain, long peak,
- struct mp3entry* entry, char* buffer, int length)
+void parse_replaygain_int(bool album, long gain, long peak,
+ struct mp3entry* entry)
{
- long len = 0;
-
- if (buffer != NULL)
- {
- len = snprintf(buffer, length, "%ld.%02d dB", gain / 512,
- ((abs(gain) & 0x01ff) * 100 + 256) / 512);
- len++;
- }
-
- if (gain != 0)
- {
- gain = convert_gain(gain * FP_ONE / 512);
- }
+ gain = gain * FP_ONE / 512;
if (album)
{
entry->album_gain = gain;
- entry->album_gain_string = buffer;
-
- if (peak)
- {
- entry->album_peak = peak;
- }
+ entry->album_peak = peak;
}
else
{
entry->track_gain = gain;
- entry->track_gain_string = buffer;
-
- if (peak)
- {
- entry->track_peak = peak;
- }
+ entry->track_peak = peak;
}
-
- return len;
}