summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorAndree Buschmann <AndreeBuschmann@t-online.de>2011-02-24 19:10:59 +0000
committerAndree Buschmann <AndreeBuschmann@t-online.de>2011-02-24 19:10:59 +0000
commit71ceac0b740398050af4f21b56acd5b31e2520f0 (patch)
treeda550f14a3c81f62aceae698c8b459287d201a01 /apps
parent65109732230849eeb9eec2f56f9e046ad6b476c3 (diff)
downloadrockbox-71ceac0b740398050af4f21b56acd5b31e2520f0.tar.gz
rockbox-71ceac0b740398050af4f21b56acd5b31e2520f0.zip
FS#11964. Rework replaygain handling to save metadata buffer and binsize. Remove string representation of replaygain and use a dedicated ftoa implementation for WPS/screen info.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29388 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r--apps/dsp.c8
-rw-r--r--apps/gui/skin_engine/skin_tokens.c9
-rw-r--r--apps/metadata.c6
-rw-r--r--apps/metadata.h7
-rw-r--r--apps/metadata/asf.c12
-rw-r--r--apps/metadata/id3tags.c18
-rw-r--r--apps/metadata/metadata_common.c2
-rw-r--r--apps/metadata/mp4.c8
-rw-r--r--apps/metadata/mpc.c6
-rw-r--r--apps/replaygain.c130
-rw-r--r--apps/replaygain.h10
-rw-r--r--apps/screens.c7
12 files changed, 65 insertions, 158 deletions
diff --git a/apps/dsp.c b/apps/dsp.c
index 3cff1918d7..c462fc37a6 100644
--- a/apps/dsp.c
+++ b/apps/dsp.c
@@ -1475,22 +1475,22 @@ intptr_t dsp_configure(struct dsp_config *dsp, int setting, intptr_t value)
case DSP_SET_TRACK_GAIN:
if (dsp == &AUDIO_DSP)
- dsp_set_gain_var(&track_gain, value);
+ dsp_set_gain_var(&track_gain, convert_gain(value));
break;
case DSP_SET_ALBUM_GAIN:
if (dsp == &AUDIO_DSP)
- dsp_set_gain_var(&album_gain, value);
+ dsp_set_gain_var(&album_gain, convert_gain(value));
break;
case DSP_SET_TRACK_PEAK:
if (dsp == &AUDIO_DSP)
- dsp_set_gain_var(&track_peak, value);
+ dsp_set_gain_var(&track_peak, convert_gain(value));
break;
case DSP_SET_ALBUM_PEAK:
if (dsp == &AUDIO_DSP)
- dsp_set_gain_var(&album_peak, value);
+ dsp_set_gain_var(&album_peak, convert_gain(value));
break;
default:
diff --git a/apps/gui/skin_engine/skin_tokens.c b/apps/gui/skin_engine/skin_tokens.c
index f455999b2a..1fbe3d714e 100644
--- a/apps/gui/skin_engine/skin_tokens.c
+++ b/apps/gui/skin_engine/skin_tokens.c
@@ -35,6 +35,7 @@
#include "sound.h"
#include "debug.h"
#include "cuesheet.h"
+#include "replaygain.h"
#ifdef HAVE_LCD_CHARCELLS
#include "hwcompat.h"
#endif
@@ -1305,8 +1306,8 @@ const char *get_token_value(struct gui_wps *gwps,
{
int type;
if (LIKELY(id3))
- type = get_replaygain_mode(id3->track_gain_string != NULL,
- id3->album_gain_string != NULL);
+ type = get_replaygain_mode(id3->track_gain != 0,
+ id3->album_gain != 0);
else
type = -1;
@@ -1331,11 +1332,11 @@ const char *get_token_value(struct gui_wps *gwps,
/* due to above, coming here with !id3 shouldn't be possible */
case 2:
case 4:
- strlcpy(buf, id3->track_gain_string, buf_size);
+ replaygain_itoa(buf, buf_size, id3->track_gain);
break;
case 3:
case 5:
- strlcpy(buf, id3->album_gain_string, buf_size);
+ replaygain_itoa(buf, buf_size, id3->album_gain);
break;
}
return buf;
diff --git a/apps/metadata.c b/apps/metadata.c
index 12bea286d0..4e4ffb6ad2 100644
--- a/apps/metadata.c
+++ b/apps/metadata.c
@@ -411,12 +411,6 @@ void adjust_mp3entry(struct mp3entry *entry, void *dest, const void *orig)
entry->albumartist += offset;
if (entry->grouping)
entry->grouping += offset;
-#if CONFIG_CODEC == SWCODEC
- if (entry->track_gain_string)
- entry->track_gain_string += offset;
- if (entry->album_gain_string)
- entry->album_gain_string += offset;
-#endif
if (entry->mb_track_id)
entry->mb_track_id += offset;
}
diff --git a/apps/metadata.h b/apps/metadata.h
index 8d20882835..5662c2e840 100644
--- a/apps/metadata.h
+++ b/apps/metadata.h
@@ -283,13 +283,10 @@ struct mp3entry {
#endif
/* replaygain support */
-
#if CONFIG_CODEC == SWCODEC
- char* track_gain_string;
- char* album_gain_string;
- long track_gain; /* 7.24 signed fixed point. 0 for no gain. */
+ long track_gain; /* s19.12 signed fixed point. 0 for no gain. */
long album_gain;
- long track_peak; /* 7.24 signed fixed point. 0 for no peak. */
+ long track_peak; /* s19.12 signed fixed point. 0 for no peak. */
long album_peak;
#endif
diff --git a/apps/metadata/asf.c b/apps/metadata/asf.c
index c445e485a2..56d5c87f9d 100644
--- a/apps/metadata/asf.c
+++ b/apps/metadata/asf.c
@@ -456,18 +456,8 @@ static int asf_parse_header(int fd, struct mp3entry* id3,
lseek(fd, length, SEEK_CUR);
}
} else if (!strncmp("replaygain_", utf8buf, 11)) {
- char* value = id3buf;
- int buf_len = id3buf_remaining;
- int len;
asf_utf16LEdecode(fd, length, &id3buf, &id3buf_remaining);
- len = parse_replaygain(utf8buf, value, id3,
- value, buf_len);
-
- if (len == 0) {
- /* Don't need to keep the value */
- id3buf = value;
- id3buf_remaining = buf_len;
- }
+ parse_replaygain(utf8buf, id3buf, id3);
} else if (!strcmp("MusicBrainz/Track Id", utf8buf)) {
id3->mb_track_id = id3buf;
asf_utf16LEdecode(fd, length, &id3buf, &id3buf_remaining);
diff --git a/apps/metadata/id3tags.c b/apps/metadata/id3tags.c
index 3cbebc12e3..c1d9cb2020 100644
--- a/apps/metadata/id3tags.c
+++ b/apps/metadata/id3tags.c
@@ -370,14 +370,8 @@ static int parseuser( struct mp3entry* entry, char* tag, int bufferpos )
entry->albumartist = tag;
#if CONFIG_CODEC == SWCODEC
} else {
- /* Calculate residual buffer size in bytes which can be used by
- * parse_replaygain() to save the string representation of
- * replaygain data.*/
- length = sizeof(entry->id3v2buf) - (tag - entry->id3v2buf);
-
- /* Call parse_replaygain(), returns length in bytes used by the
- * string representation of replaygain data. */
- length = parse_replaygain(tag, value, entry, tag, length);
+ /* Call parse_replaygain(). */
+ parse_replaygain(tag, value, entry);
#endif
}
}
@@ -387,12 +381,11 @@ static int parseuser( struct mp3entry* entry, char* tag, int bufferpos )
#if CONFIG_CODEC == SWCODEC
/* parse RVA2 binary data and convert to replaygain information. */
-static int parserva2( struct mp3entry* entry, char* tag, int bufferpos )
+static int parserva2( struct mp3entry* entry, char* tag, int bufferpos)
{
int desc_len = strlen(tag);
int start_pos = tag - entry->id3v2buf;
int end_pos = start_pos + desc_len + 5;
- int value_len = 0;
unsigned char* value = tag + desc_len + 1;
/* Only parse RVA2 replaygain tags if tag version == 2.4 and channel
@@ -447,11 +440,10 @@ static int parserva2( struct mp3entry* entry, char* tag, int bufferpos )
}
}
- value_len = parse_replaygain_int(album, gain, peak * 2, entry,
- tag, sizeof(entry->id3v2buf) - start_pos);
+ parse_replaygain_int(album, gain, peak * 2, entry);
}
- return start_pos + value_len;
+ return start_pos;
}
#endif
diff --git a/apps/metadata/metadata_common.c b/apps/metadata/metadata_common.c
index 341d279b5d..ae6b245616 100644
--- a/apps/metadata/metadata_common.c
+++ b/apps/metadata/metadata_common.c
@@ -333,7 +333,7 @@ long parse_tag(const char* name, char* value, struct mp3entry* id3,
}
else
{
- len = parse_replaygain(name, value, id3, buf, buf_remaining);
+ parse_replaygain(name, value, id3);
p = NULL;
}
diff --git a/apps/metadata/mp4.c b/apps/metadata/mp4.c
index 6130135bae..a431231e12 100644
--- a/apps/metadata/mp4.c
+++ b/apps/metadata/mp4.c
@@ -528,13 +528,7 @@ static bool read_mp4_tags(int fd, struct mp3entry* id3,
buffer -= length;
buffer_left += length;
- if (parse_replaygain(tag_name, buffer, id3,
- buffer, buffer_left) > 0)
- {
- /* Data used, keep it. */
- buffer += length;
- buffer_left -= length;
- }
+ parse_replaygain(tag_name, buffer, id3);
}
}
}
diff --git a/apps/metadata/mpc.c b/apps/metadata/mpc.c
index 0387dc9f77..0b75ed04dd 100644
--- a/apps/metadata/mpc.c
+++ b/apps/metadata/mpc.c
@@ -46,8 +46,7 @@ static int set_replaygain_sv7(struct mp3entry* id3,
/* We use a peak value of 0 to indicate a given gain type isn't used. */
if (peak != 0) {
/* Save the ReplayGain data to id3-structure for further processing. */
- used += parse_replaygain_int(album, gain * 512 / 100, peak << 9,
- id3, id3->toc + used, sizeof(id3->toc) - used);
+ parse_replaygain_int(album, gain * 512 / 100, peak << 9, id3);
}
return used;
@@ -73,8 +72,7 @@ static int set_replaygain_sv8(struct mp3entry* id3,
/* We use a peak value of 0 to indicate a given gain type isn't used. */
if (peak != 0) {
/* Save the ReplayGain data to id3-structure for further processing. */
- used += parse_replaygain_int(album, gain * 512 / 100, peak,
- id3, id3->toc + used, sizeof(id3->toc) - used);
+ parse_replaygain_int(album, gain * 512 / 100, peak, id3);
}
return used;
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;
}
diff --git a/apps/replaygain.h b/apps/replaygain.h
index 02ca2e0bae..4fb5476e23 100644
--- a/apps/replaygain.h
+++ b/apps/replaygain.h
@@ -25,9 +25,11 @@
#include "metadata.h"
long get_replaygain_int(long int_gain);
-long parse_replaygain(const char* key, const char* value,
- struct mp3entry* entry, char* buffer, int length);
-long parse_replaygain_int(bool album, long gain, long peak,
- struct mp3entry* entry, char* buffer, int length);
+void parse_replaygain(const char* key, const char* value,
+ struct mp3entry* entry);
+void parse_replaygain_int(bool album, long gain, long peak,
+ struct mp3entry* entry);
+void replaygain_itoa(char* buffer, int length, long int_gain);
+long convert_gain(long gain);
#endif
diff --git a/apps/screens.c b/apps/screens.c
index 81472e6cc7..b1a48c5bd6 100644
--- a/apps/screens.c
+++ b/apps/screens.c
@@ -53,6 +53,7 @@
#include "backdrop.h"
#include "viewport.h"
#include "language.h"
+#include "replaygain.h"
#if CONFIG_CODEC == SWCODEC
#include "dsp.h"
@@ -728,10 +729,12 @@ static const char* id3_get_info(int selected_item, void* data,
break;
#if CONFIG_CODEC == SWCODEC
case LANG_ID3_TRACK_GAIN:
- val=id3->track_gain_string;
+ replaygain_itoa(buffer, buffer_len, id3->track_gain);
+ val=(id3->track_gain) ? buffer : NULL; /* only show gains!=0 */
break;
case LANG_ID3_ALBUM_GAIN:
- val=id3->album_gain_string;
+ replaygain_itoa(buffer, buffer_len, id3->album_gain);
+ val=(id3->album_gain) ? buffer : NULL; /* only show gains!=0 */
break;
#endif
case LANG_ID3_PATH: