diff --git a/res/values/translatable.xml b/res/values/translatable.xml index fa5cb98f..69ca9aed 100644 --- a/res/values/translatable.xml +++ b/res/values/translatable.xml @@ -174,6 +174,8 @@ THE SOFTWARE. Enable readahead Readahead the currently playing song. This option may solve \'audio dropout\' issues. (caused by a slow SD card) + Equalizer + Continuous Shuffle \'Shuffle mode\' will play songs in completely random order diff --git a/res/xml/preference_audio.xml b/res/xml/preference_audio.xml index 09e4aff8..c8e61ecb 100644 --- a/res/xml/preference_audio.xml +++ b/res/xml/preference_audio.xml @@ -27,6 +27,10 @@ THE SOFTWARE. android:fragment="ch.blinkenlights.android.vanilla.PreferencesActivity$ReplayGainFragment" android:title="@string/replaygain" android:summary="@string/replaygain_summary" /> + > hasNext="+mMediaPlayer.hasNextMediaPlayer()+", ds="+mMediaPlayer.getDataSource()+", class="+mMediaPlayer); - Log.v("VanillaMusic", "P>> hasNext="+mPreparedMediaPlayer.hasNextMediaPlayer()+", ds="+mPreparedMediaPlayer.getDataSource()+", class="+mPreparedMediaPlayer); + vLog("VanillaMusic", "A>> hasNext="+mMediaPlayer.hasNextMediaPlayer()+", ds="+mMediaPlayer.getDataSource()+", class="+mMediaPlayer); + vLog("VanillaMusic", "P>> hasNext="+mPreparedMediaPlayer.hasNextMediaPlayer()+", ds="+mPreparedMediaPlayer.getDataSource()+", class="+mPreparedMediaPlayer); if(doGapless == true) { try { if(nextSong.path.equals(mPreparedMediaPlayer.getDataSource()) == false) { // Prepared MP has a different data source: We need to re-initalize // it and set it as the next MP for the active media player - Log.v("VanillaMusic", "GAPLESS: SETTING "+nextSong.path); + vLog("VanillaMusic", "GAPLESS: SETTING "+nextSong.path); mPreparedMediaPlayer.reset(); prepareMediaPlayer(mPreparedMediaPlayer, nextSong.path); mMediaPlayer.setNextMediaPlayer(mPreparedMediaPlayer); @@ -700,11 +706,11 @@ public final class PlaybackService extends Service if(mMediaPlayer.hasNextMediaPlayer() == false) { // We can reuse the prepared MediaPlayer but the current instance lacks // a link to it - Log.v("VanillaMusic", "SETTING NEXT MP as in "+mPreparedMediaPlayer.getDataSource()); + vLog("VanillaMusic", "SETTING NEXT MP as in "+mPreparedMediaPlayer.getDataSource()); mMediaPlayer.setNextMediaPlayer(mPreparedMediaPlayer); } } catch (IOException e) { - Log.v("VanillaMusic", "triggerGaplessUpdate() failed with exception "+e); + vLog("VanillaMusic", "triggerGaplessUpdate() failed with exception "+e); mMediaPlayer.setNextMediaPlayer(null); mPreparedMediaPlayer.reset(); } @@ -716,10 +722,14 @@ public final class PlaybackService extends Service } } - Log.v("VanillaMusic", "A<< hasNext="+mMediaPlayer.hasNextMediaPlayer()+", ds="+mMediaPlayer.getDataSource()+", class="+mMediaPlayer); - Log.v("VanillaMusic", "P<< hasNext="+mPreparedMediaPlayer.hasNextMediaPlayer()+", ds="+mPreparedMediaPlayer.getDataSource()+", class="+mPreparedMediaPlayer); - + vLog("VanillaMusic", "A<< hasNext="+mMediaPlayer.hasNextMediaPlayer()+", ds="+mMediaPlayer.getDataSource()+", class="+mMediaPlayer); + vLog("VanillaMusic", "P<< hasNext="+mPreparedMediaPlayer.hasNextMediaPlayer()+", ds="+mPreparedMediaPlayer.getDataSource()+", class="+mPreparedMediaPlayer); + } + // Helper to quickly enable and disable logging of triggerGaplessUpdate + // FIXME: REMOVE ME + private static void vLog(String name, String text) { + Log.v(name, text); } /** @@ -1471,6 +1481,16 @@ public final class PlaybackService extends Service return 0; return mMediaPlayer.getDuration(); } + + /** + * Returns the global audio session + */ + public int getAudioSession() { + // Must not be 'ready' or initialized: the audio session + // is set on object creation + return mMediaPlayer.getAudioSessionId(); + } + /** * Seek to a position in the current song. * diff --git a/src/ch/blinkenlights/android/vanilla/PreferencesActivity.java b/src/ch/blinkenlights/android/vanilla/PreferencesActivity.java index 80b1e753..a65b214f 100644 --- a/src/ch/blinkenlights/android/vanilla/PreferencesActivity.java +++ b/src/ch/blinkenlights/android/vanilla/PreferencesActivity.java @@ -38,6 +38,9 @@ import android.view.View; import android.view.ViewGroup; import android.webkit.WebView; import android.webkit.WebViewFragment; +import android.content.Context; +import android.content.Intent; +import android.media.audiofx.AudioEffect; import android.net.Uri; import java.util.List; @@ -117,6 +120,32 @@ public class PreferencesActivity extends PreferenceActivity { } } + public static class EqualizerFragment extends PreferenceFragment { + @Override + public void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + + Context context = getActivity(); + int mAudioSession = 0; + if (PlaybackService.hasInstance()) { + PlaybackService service = PlaybackService.get(context); + mAudioSession = service.getAudioSession(); + } + + try { + final Intent effects = new Intent(AudioEffect.ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL); + effects.putExtra(AudioEffect.EXTRA_PACKAGE_NAME, context.getPackageName()); + effects.putExtra(AudioEffect.EXTRA_AUDIO_SESSION, mAudioSession); + startActivityForResult(effects, 0); + } catch (Exception e) { + // ignored. Whee! + } + + getActivity().finish(); + } + } + public static class PlaybackFragment extends PreferenceFragment { @Override public void onCreate(Bundle savedInstanceState) diff --git a/src/ch/blinkenlights/android/vanilla/VanillaMediaPlayer.java b/src/ch/blinkenlights/android/vanilla/VanillaMediaPlayer.java index 450092a5..dce062dd 100644 --- a/src/ch/blinkenlights/android/vanilla/VanillaMediaPlayer.java +++ b/src/ch/blinkenlights/android/vanilla/VanillaMediaPlayer.java @@ -22,17 +22,13 @@ import android.content.Context; import android.content.Intent; import android.media.MediaPlayer; import android.media.audiofx.AudioEffect; - import java.io.IOException; - - public class VanillaMediaPlayer extends MediaPlayer { private Context mContext; private String mDataSource; private boolean mHasNextMediaPlayer; - private int mClaimedAudioSessionId = 0; /** * Constructs a new VanillaMediaPlayer class @@ -40,7 +36,6 @@ public class VanillaMediaPlayer extends MediaPlayer { public VanillaMediaPlayer(Context context) { super(); mContext = context; - _claimAudioSession(); } /** @@ -56,7 +51,6 @@ public class VanillaMediaPlayer extends MediaPlayer { * Releases the media player and frees any claimed AudioEffect */ public void release() { - _releaseAudioSession(); mDataSource = null; mHasNextMediaPlayer = false; super.release(); @@ -68,7 +62,6 @@ public class VanillaMediaPlayer extends MediaPlayer { public void setDataSource(String dataSource) throws IOException, IllegalArgumentException, SecurityException, IllegalStateException { mDataSource = dataSource; super.setDataSource(mDataSource); - _claimAudioSession(); } /** @@ -97,28 +90,21 @@ public class VanillaMediaPlayer extends MediaPlayer { /** * Creates a new AudioEffect for our AudioSession */ - private void _claimAudioSession() { - // No active audio session -> claim one - if (mClaimedAudioSessionId == 0) { - mClaimedAudioSessionId = this.getAudioSessionId(); - Intent i = new Intent(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION); - i.putExtra(AudioEffect.EXTRA_AUDIO_SESSION, mClaimedAudioSessionId); - i.putExtra(AudioEffect.EXTRA_PACKAGE_NAME, mContext.getPackageName()); - mContext.sendBroadcast(i); - } + public void openAudioFx() { + Intent i = new Intent(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION); + i.putExtra(AudioEffect.EXTRA_AUDIO_SESSION, this.getAudioSessionId()); + i.putExtra(AudioEffect.EXTRA_PACKAGE_NAME, mContext.getPackageName()); + mContext.sendBroadcast(i); } /** * Releases a previously claimed audio session id */ - private void _releaseAudioSession() { - if (mClaimedAudioSessionId != 0) { - Intent i = new Intent(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION); - i.putExtra(AudioEffect.EXTRA_AUDIO_SESSION, mClaimedAudioSessionId); - i.putExtra(AudioEffect.EXTRA_PACKAGE_NAME, mContext.getPackageName()); - mContext.sendBroadcast(i); - mClaimedAudioSessionId = 0; - } + public void closeAudioFx() { + Intent i = new Intent(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION); + i.putExtra(AudioEffect.EXTRA_AUDIO_SESSION, this.getAudioSessionId()); + i.putExtra(AudioEffect.EXTRA_PACKAGE_NAME, mContext.getPackageName()); + mContext.sendBroadcast(i); } }