Rockbox Development > Starting Development and Compiling
ReplayGain as volume offset instead of "gain"
color43:
Hello all,
I'm trying to change how Rockbox uses ReplayGain. I want it to just add/subtract the replay gain value from the current volume behind-the-scenes instead of using the normal method which can cause clipping. For example, if my audio file has a replaygain of -5.75 dB, and my current volume is -25 dB, the volume would be set to -31 dB for this song. (the user will still see -25)
Basically, I edited the sound_set_volume function in /rockbox/firmware/sound.c to look like the following:
It works great when manually starting a new track or manually advancing to the next track.
The problem I'm having is when a new track is automatically started because the current track is over.
When this function is called in the above scenario, the mp3entry struct is for the "last" track, so the volume for the new track doesn't get set right.
Once the new track starts and I change the volume up or down, the code works like its supposed to.
My main question is: how can I get an mp3entry struct of the current track at the exact instant a new track automatically starts
--- Code: ---void sound_set_volume(int value)
{
if(!audio_is_initialized)
return;
const int min_vol = sound_min(SOUND_VOLUME);
const int max_vol = sound_max(SOUND_VOLUME);
int volume = value;
int volume_offset = 0;
struct mp3entry *id3 = audio_current_track();
if (id3 && global_settings.replaygain_type != REPLAYGAIN_OFF)
{
long gain = id3->track_level;
volume_offset = abs(gain) >> 12;
/* if this bit is set, the number's decimal part is .5 or greater */
if (abs(gain) & (1 << 11))
volume_offset++;
if (gain < 0)
volume_offset *= -1;
}
if (volume + volume_offset < min_vol)
{
volume = min_vol;
volume_offset = 0;
}
if (value + volume_offset > max_vol)
{
volume = max_vol;
volume_offset = 0;
}
volume += volume_offset;
logf("act:%d off:%d vol:%d", value, volume_offset, volume);
#if defined(AUDIOHW_HAVE_CLIPPING)
audiohw_set_volume(volume);
#elif CONFIG_CPU == PNX0101
int tmp = (60 - volume * 4) & 0xff;
CODECVOL = tmp | (tmp << 8);
#else
current_volume = volume * 10; /* tenth of dB */
set_prescaled_volume();
#endif
}
--- End code ---
saratoga:
--- Quote from: color43 on January 31, 2012, 01:22:28 AM ---I'm trying to change how Rockbox uses ReplayGain. I want it to just add/subtract the replay gain value from the current volume behind-the-scenes instead of using the normal method which can cause clipping.
--- End quote ---
I think you have this backwards. The idea of applying the gain digitally is that it prevents clipping before it happens at the DAC. Replaygain targets a reference level that is sufficiently quiet that clipping does not occur. If you apply the gain on the analog side, you will get additional clipping since the volume adjustment will occur after the audio is already clipped. Basically, you'll just scale the already clipped waveform up and down, which will give you equal loudness but more distortion on loud music. I'm at a loss for a use case where this would be desirable.
--- Quote from: color43 on January 31, 2012, 01:22:28 AM ---Basically, I edited the sound_set_volume function in /rockbox/firmware/sound.c to look like the following:
--- End quote ---
Its probably easier to edit apps/dsp.c to set the volume directly when it applies gain. Check out dsp_apply_gain.
color43:
I forgot to mention that I removed most of the code in dsp_set_replaygain which stops Rockbox from doing its normal ReplayGain processing.
The method I'm using does not play with the waveform at all, it's just like manually changing the volume up or down with the buttons.
I'll take a look at the function you mentioned
saratoga:
--- Quote from: color43 on January 31, 2012, 02:22:50 AM ---The method I'm using does not play with the waveform at all, it's just like manually changing the volume up or down with the buttons.
--- End quote ---
Yes I know, you explained above. You probably do not want to scale the volume rather then the gain since the way you're thinking won't prevent clipping on loud tracks.
Basically, I think you're misunderstanding how replaygain works.
color43:
Say you have Replaygain set to "Off" in the playback settings. Now start playing a fairly loud track. Say the volume's at -25 dB and it's playing at a normal volume level. If I turn the volume up to -5 dB it would be blaring, but not clipping.
If it had a replaygain value of +20.00 dB and replay gain was on, it would clip all over the place?
How can my method cause clipping if its turning up the volume and disabling all gain handling?
Here's why I'm doing this: I have some podcasts that are pretty quiet compared to other files. I manually put my own ID3 tag on there with a replaygain_track_gain of +10.00 dB. I just want my Rockbox player to play it 10 dB (or 10 volume clicks) louder without it clipping.
Navigation
[0] Message Index
[#] Next page
Go to full version