improve replay gain support

This commit is contained in:
Adrian Ulrich 2013-04-01 21:20:13 +02:00
parent 7b0fb5a07f
commit ac28a36d5a
4 changed files with 81 additions and 27 deletions

View File

@ -152,9 +152,16 @@ THE SOFTWARE.
<string name="headset_pause_summary">Pause when the headphones are unplugged.</string> <string name="headset_pause_summary">Pause when the headphones are unplugged.</string>
<string name="headset_play_title">Play When Plugged</string> <string name="headset_play_title">Play When Plugged</string>
<string name="headset_play_summary">Play when the headphones are plugged in. (Only works when the service is running.)</string> <string name="headset_play_summary">Play when the headphones are plugged in. (Only works when the service is running.)</string>
<string name="replaygain">Replay Gain</string> <string name="replaygain">Replay Gain</string>
<string name="replaygain_title">Enable Replay Gain</string> <string name="replaygain_title">Enable Replay Gain</string>
<string name="replaygain_summary">Configure handling of Replay Gain information</string> <string name="replaygain_summary">Configure handling of Replay Gain information</string>
<string name="replaygain_track_title">Enable per-track Replay Gain</string>
<string name="replaygain_track_summary">Play all tracks at equal loudness</string>
<string name="replaygain_album_title">Enable album Replay Gain</string>
<string name="replaygain_album_summary">Preserve album dynamics</string>
<string name="replaygain_silence_title">Keep volume down</string>
<string name="replaygain_silence_summary">Automatically reduce the volume by 30% for tracks without any Replay Gain information</string>
<string name="notifications">Notifications</string> <string name="notifications">Notifications</string>
<string name="notification_mode_title">Notification Mode</string> <string name="notification_mode_title">Notification Mode</string>

View File

@ -24,8 +24,18 @@ THE SOFTWARE.
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:persistent="true"> android:persistent="true">
<CheckBoxPreference <CheckBoxPreference
android:key="enable_replaygain" android:key="enable_track_replaygain"
android:title="@string/replaygain_title" android:title="@string/replaygain_track_title"
android:summary="@string/replaygain_summary" android:summary="@string/replaygain_track_summary"
android:defaultValue="false" />
<CheckBoxPreference
android:key="enable_album_replaygain"
android:title="@string/replaygain_album_title"
android:summary="@string/replaygain_album_summary"
android:defaultValue="false" />
<CheckBoxPreference
android:key="silence_nonreplaygain_tracks"
android:title="@string/replaygain_silence_title"
android:summary="@string/replaygain_silence_summary"
android:defaultValue="false" /> android:defaultValue="false" />
</PreferenceScreen> </PreferenceScreen>

View File

@ -370,7 +370,9 @@ public final class PlaybackService extends Service
/** /**
* Enables or disables Replay Gain * Enables or disables Replay Gain
*/ */
private boolean mReplayGainEnabled; private boolean mReplayGainTrackEnabled;
private boolean mReplayGainAlbumEnabled;
private boolean mReplayGainSilenceEnabled;
@Override @Override
public void onCreate() public void onCreate()
@ -403,7 +405,10 @@ public final class PlaybackService extends Service
mHeadsetPause = getSettings(this).getBoolean(PrefKeys.HEADSET_PAUSE, true); mHeadsetPause = getSettings(this).getBoolean(PrefKeys.HEADSET_PAUSE, true);
mShakeAction = settings.getBoolean(PrefKeys.ENABLE_SHAKE, false) ? Action.getAction(settings, PrefKeys.SHAKE_ACTION, Action.NextSong) : Action.Nothing; mShakeAction = settings.getBoolean(PrefKeys.ENABLE_SHAKE, false) ? Action.getAction(settings, PrefKeys.SHAKE_ACTION, Action.NextSong) : Action.Nothing;
mShakeThreshold = settings.getInt(PrefKeys.SHAKE_THRESHOLD, 80) / 10.0f; mShakeThreshold = settings.getInt(PrefKeys.SHAKE_THRESHOLD, 80) / 10.0f;
mReplayGainEnabled = settings.getBoolean(PrefKeys.ENABLE_REPLAYGAIN, false);
mReplayGainTrackEnabled = settings.getBoolean(PrefKeys.ENABLE_TRACK_REPLAYGAIN, false);
mReplayGainAlbumEnabled = settings.getBoolean(PrefKeys.ENABLE_ALBUM_REPLAYGAIN, false);
mReplayGainSilenceEnabled = settings.getBoolean(PrefKeys.SILENCE_NONRG_TRACKS, false);
PowerManager powerManager = (PowerManager)getSystemService(POWER_SERVICE); PowerManager powerManager = (PowerManager)getSystemService(POWER_SERVICE);
mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "VanillaMusicLock"); mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "VanillaMusicLock");
@ -565,34 +570,60 @@ public final class PlaybackService extends Service
} }
public void prepareMediaPlayer(MediaPlayer mp, String path) throws IOException{ public void prepareMediaPlayer(MediaPlayer mp, String path) throws IOException{
float adjust = 0f;
mp.setDataSource(path); mp.setDataSource(path);
if(mReplayGainEnabled == true) { float[] rg = calculateReplayGainAdjustment(path); /* track, album */
applyReplayGain(mp, path);
if(mReplayGainAlbumEnabled) {
adjust = (rg[0] > 0 ? rg[0] : adjust); /* do we have track adjustment ? */
adjust = (rg[1] > 0 ? rg[1] : adjust); /* ..or, even better, album adj? */
}
if(mReplayGainTrackEnabled || (mReplayGainAlbumEnabled && adjust == 0)) {
adjust = (rg[1] > 0 ? rg[1] : adjust); /* do we have album adjustment ? */
adjust = (rg[0] > 0 ? rg[0] : adjust); /* ..or, even better, track adj? */
}
if(adjust == 0 && mReplayGainSilenceEnabled) {
adjust = 0.7f;
}
if(adjust > 0) {
Toast.makeText(this, path+"\n"+" PX "+adjust, Toast.LENGTH_SHORT).show();
mp.setVolume(adjust, adjust);
Log.d("VanillaMusic", "adjusting replaygain of "+path+" to "+adjust);
} }
mp.prepare(); mp.prepare();
} }
private void applyReplayGain(MediaPlayer mp, String path) { /**
HashMap tags = (new Bastp()).getTags(path); * Returns TRACK, ALBUM gain values for given path
float adjust = 1.0f; * A value of 0 means that the tag was not found in given file
*/
private float[] calculateReplayGainAdjustment(String path) {
String[] keys = { "REPLAYGAIN_TRACK_GAIN", "REPLAYGAIN_ALBUM_GAIN" };
float[] adjust= { 0f , 0f };
HashMap tags = (new Bastp()).getTags(path);
if(tags.containsKey("REPLAYGAIN_TRACK_GAIN")) { for (int i=0; i<keys.length; i++) {
String rg_raw = (String)((Vector)tags.get("REPLAYGAIN_TRACK_GAIN")).get(0); String curKey = keys[i];
String rg_numonly = ""; if(tags.containsKey(curKey)) {
float rg_float = 0f; String rg_raw = (String)((Vector)tags.get(curKey)).get(0);
try { String rg_numonly = "";
String nums = rg_raw.replaceAll("[^0-9.-]",""); float rg_float = 0f;
rg_float = Float.parseFloat(nums); try {
} catch(Exception e) {} String nums = rg_raw.replaceAll("[^0-9.-]","");
rg_float = Float.parseFloat(nums);
} catch(Exception e) {}
adjust = (float)Math.pow(10, (rg_float/20) ); float rg_result = (float)Math.pow(10, (rg_float/20) );
Toast.makeText(this, path+"\n"+" PX "+rg_raw+" adj = "+adjust, Toast.LENGTH_SHORT).show(); adjust[i] = rg_result;
}
} }
return adjust;
mp.setVolume(adjust, adjust);
} }
/** /**
@ -708,8 +739,12 @@ public final class PlaybackService extends Service
setupSensor(); setupSensor();
} else if (PrefKeys.SHAKE_THRESHOLD.equals(key)) { } else if (PrefKeys.SHAKE_THRESHOLD.equals(key)) {
mShakeThreshold = settings.getInt(PrefKeys.SHAKE_THRESHOLD, 80) / 10.0f; mShakeThreshold = settings.getInt(PrefKeys.SHAKE_THRESHOLD, 80) / 10.0f;
} else if (PrefKeys.ENABLE_REPLAYGAIN.equals(key)) { } else if (PrefKeys.ENABLE_TRACK_REPLAYGAIN.equals(key)) {
mReplayGainEnabled = settings.getBoolean(PrefKeys.ENABLE_REPLAYGAIN, false); mReplayGainTrackEnabled = settings.getBoolean(PrefKeys.ENABLE_TRACK_REPLAYGAIN, false);
} else if (PrefKeys.ENABLE_ALBUM_REPLAYGAIN.equals(key)) {
mReplayGainAlbumEnabled = settings.getBoolean(PrefKeys.ENABLE_ALBUM_REPLAYGAIN, false);
} else if (PrefKeys.SILENCE_NONRG_TRACKS.equals(key)) {
mReplayGainSilenceEnabled = settings.getBoolean(PrefKeys.SILENCE_NONRG_TRACKS, false);
} }
CompatFroyo.dataChanged(this); CompatFroyo.dataChanged(this);

View File

@ -57,5 +57,7 @@ public class PrefKeys {
public static final String USE_IDLE_TIMEOUT = "use_idle_timeout"; public static final String USE_IDLE_TIMEOUT = "use_idle_timeout";
public static final String VISIBLE_CONTROLS = "visible_controls"; public static final String VISIBLE_CONTROLS = "visible_controls";
public static final String VISIBLE_EXTRA_INFO = "visible_extra_info"; public static final String VISIBLE_EXTRA_INFO = "visible_extra_info";
public static final String ENABLE_REPLAYGAIN = "enable_replaygain"; public static final String ENABLE_TRACK_REPLAYGAIN = "enable_track_replaygain";
public static final String ENABLE_ALBUM_REPLAYGAIN = "enable_album_replaygain";
public static final String SILENCE_NONRG_TRACKS = "silence_nonreplaygain_tracks";
} }