aboutsummaryrefslogtreecommitdiff
path: root/src/github
diff options
context:
space:
mode:
Diffstat (limited to 'src/github')
-rw-r--r--src/github/daneren2005/dsub/activity/SubsonicFragmentActivity.java1
-rw-r--r--src/github/daneren2005/dsub/audiofx/AudioEffectsController.java82
-rw-r--r--src/github/daneren2005/dsub/audiofx/EqualizerController.java248
-rw-r--r--src/github/daneren2005/dsub/audiofx/LoudnessEnhancerController.java77
-rw-r--r--src/github/daneren2005/dsub/audiofx/VisualizerController.java109
-rw-r--r--src/github/daneren2005/dsub/fragments/DownloadFragment.java3
-rw-r--r--src/github/daneren2005/dsub/fragments/EqualizerFragment.java113
-rw-r--r--src/github/daneren2005/dsub/receiver/MediaButtonIntentReceiver.java18
-rw-r--r--src/github/daneren2005/dsub/service/ChromeCastController.java2
-rw-r--r--src/github/daneren2005/dsub/service/DownloadService.java87
-rw-r--r--src/github/daneren2005/dsub/service/RESTMusicService.java28
11 files changed, 539 insertions, 229 deletions
diff --git a/src/github/daneren2005/dsub/activity/SubsonicFragmentActivity.java b/src/github/daneren2005/dsub/activity/SubsonicFragmentActivity.java
index a55abfc0..5aee380f 100644
--- a/src/github/daneren2005/dsub/activity/SubsonicFragmentActivity.java
+++ b/src/github/daneren2005/dsub/activity/SubsonicFragmentActivity.java
@@ -511,7 +511,6 @@ public class SubsonicFragmentActivity extends SubsonicActivity {
private void showInfoDialog() {
if (!infoDialogDisplayed) {
infoDialogDisplayed = true;
- Log.i(TAG, Util.getRestUrl(this, null));
if (Util.getRestUrl(this, null).contains("demo.subsonic.org")) {
Util.info(this, R.string.main_welcome_title, R.string.main_welcome_text);
}
diff --git a/src/github/daneren2005/dsub/audiofx/AudioEffectsController.java b/src/github/daneren2005/dsub/audiofx/AudioEffectsController.java
new file mode 100644
index 00000000..f53a4dff
--- /dev/null
+++ b/src/github/daneren2005/dsub/audiofx/AudioEffectsController.java
@@ -0,0 +1,82 @@
+/*
+ This file is part of Subsonic.
+
+ Subsonic is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Subsonic is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
+
+ Copyright 2014 (C) Scott Jackson
+*/
+package github.daneren2005.dsub.audiofx;
+
+import android.content.Context;
+import android.media.MediaPlayer;
+import android.media.audiofx.AudioEffect;
+import android.media.audiofx.LoudnessEnhancer;
+import android.os.Build;
+import android.util.Log;
+
+public class AudioEffectsController {
+ private static final String TAG = AudioEffectsController.class.getSimpleName();
+
+ private final Context context;
+ private int audioSessionId = 0;
+
+ private boolean available = false;
+
+ private EqualizerController equalizerController;
+ private VisualizerController visualizerController;
+
+ public AudioEffectsController(Context context, int audioSessionId) {
+ this.context = context;
+ this.audioSessionId = audioSessionId;
+
+ if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
+ available = true;
+ }
+ }
+
+ public boolean isAvailable() {
+ return available;
+ }
+
+ public void release() {
+ if(equalizerController != null) {
+ equalizerController.release();
+ }
+ if(visualizerController != null) {
+ visualizerController.release();
+ }
+ }
+
+ public EqualizerController getEqualizerController() {
+ if (available && equalizerController == null) {
+ equalizerController = new EqualizerController(context, audioSessionId);
+ if (!equalizerController.isAvailable()) {
+ equalizerController = null;
+ } else {
+ equalizerController.loadSettings();
+ }
+ }
+ return equalizerController;
+ }
+ public VisualizerController getVisualizerController() {
+ if (available && visualizerController == null) {
+ visualizerController = new VisualizerController(context, audioSessionId);
+ if (!visualizerController.isAvailable()) {
+ visualizerController = null;
+ }
+ }
+ return visualizerController;
+ }
+}
+
diff --git a/src/github/daneren2005/dsub/audiofx/EqualizerController.java b/src/github/daneren2005/dsub/audiofx/EqualizerController.java
index 0e1c49b5..254f168d 100644
--- a/src/github/daneren2005/dsub/audiofx/EqualizerController.java
+++ b/src/github/daneren2005/dsub/audiofx/EqualizerController.java
@@ -21,8 +21,9 @@ package github.daneren2005.dsub.audiofx;
import java.io.Serializable;
import android.content.Context;
-import android.media.MediaPlayer;
+import android.media.audiofx.BassBoost;
import android.media.audiofx.Equalizer;
+import android.os.Build;
import android.util.Log;
import github.daneren2005.dsub.util.FileUtil;
@@ -34,125 +35,170 @@ import github.daneren2005.dsub.util.FileUtil;
*/
public class EqualizerController {
- private static final String TAG = EqualizerController.class.getSimpleName();
+ private static final String TAG = EqualizerController.class.getSimpleName();
- private final Context context;
- private Equalizer equalizer;
+ private final Context context;
+ private Equalizer equalizer;
+ private BassBoost bass;
+ private boolean loudnessAvailable = false;
+ private LoudnessEnhancerController loudnessEnhancerController;
private boolean released = false;
private int audioSessionId = 0;
- // Class initialization fails when this throws an exception.
- static {
- try {
- Class.forName("android.media.audiofx.Equalizer");
- } catch (Exception ex) {
- throw new RuntimeException(ex);
- }
- }
-
- /**
- * Throws an exception if the {@link Equalizer} class is not available.
- */
- public static void checkAvailable() throws Throwable {
- // Calling here forces class initialization.
- }
-
- public EqualizerController(Context context, MediaPlayer mediaPlayer) {
- this.context = context;
- try {
- audioSessionId = mediaPlayer.getAudioSessionId();
- equalizer = new Equalizer(0, audioSessionId);
- } catch (Throwable x) {
- Log.w(TAG, "Failed to create equalizer.", x);
- }
- }
-
- public void saveSettings() {
- try {
- if (isAvailable()) {
- FileUtil.serialize(context, new EqualizerSettings(equalizer), "equalizer.dat");
- }
- } catch (Throwable x) {
- Log.w(TAG, "Failed to save equalizer settings.", x);
- }
- }
-
- public void loadSettings() {
- try {
- if (isAvailable()) {
- EqualizerSettings settings = FileUtil.deserialize(context, "equalizer.dat", EqualizerSettings.class);
- if (settings != null) {
- settings.apply(equalizer);
- }
- }
- } catch (Throwable x) {
- Log.w(TAG, "Failed to load equalizer settings.", x);
- }
- }
-
- public boolean isAvailable() {
- return equalizer != null;
- }
-
- public boolean isEnabled() {
- try {
- return isAvailable() && equalizer.getEnabled();
- } catch(Exception e) {
- return false;
- }
- }
-
- public void release() {
- if (isAvailable()) {
+ public EqualizerController(Context context, int audioSessionId) {
+ this.context = context;
+ try {
+ this.audioSessionId = audioSessionId;
+ init();
+ } catch (Throwable x) {
+ Log.w(TAG, "Failed to create equalizer.", x);
+ }
+ }
+
+ private void init() {
+ equalizer = new Equalizer(0, audioSessionId);
+ bass = new BassBoost(0, audioSessionId);
+ if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ loudnessAvailable = true;
+ loudnessEnhancerController = new LoudnessEnhancerController(context, audioSessionId);
+ }
+ }
+
+ public void saveSettings() {
+ try {
+ if (isAvailable()) {
+ FileUtil.serialize(context, new EqualizerSettings(equalizer, bass, loudnessEnhancerController), "equalizer.dat");
+ }
+ } catch (Throwable x) {
+ Log.w(TAG, "Failed to save equalizer settings.", x);
+ }
+ }
+
+ public void loadSettings() {
+ try {
+ if (isAvailable()) {
+ EqualizerSettings settings = FileUtil.deserialize(context, "equalizer.dat", EqualizerSettings.class);
+ if (settings != null) {
+ settings.apply(equalizer, bass, loudnessEnhancerController);
+ }
+ }
+ } catch (Throwable x) {
+ Log.w(TAG, "Failed to load equalizer settings.", x);
+ }
+ }
+
+ public boolean isAvailable() {
+ return equalizer != null && bass != null;
+ }
+
+ public boolean isEnabled() {
+ try {
+ return isAvailable() && equalizer.getEnabled();
+ } catch(Exception e) {
+ return false;
+ }
+ }
+
+ public void release() {
+ if (isAvailable()) {
released = true;
- equalizer.release();
- }
- }
+ equalizer.release();
+ bass.release();
+ if(loudnessEnhancerController != null && loudnessEnhancerController.isAvailable()) {
+ loudnessEnhancerController.release();
+ }
+ }
+ }
- public Equalizer getEqualizer() {
+ public Equalizer getEqualizer() {
if(released) {
released = false;
try {
- equalizer = new Equalizer(0, audioSessionId);
+ init();
} catch (Throwable x) {
equalizer = null;
Log.w(TAG, "Failed to create equalizer.", x);
}
}
- return equalizer;
- }
+ return equalizer;
+ }
+ public BassBoost getBassBoost() {
+ if(released) {
+ released = false;
+ try {
+ init();
+ } catch (Throwable x) {
+ bass = null;
+ Log.w(TAG, "Failed to create bass booster.", x);
+ }
+ }
+ return bass;
+ }
+ public LoudnessEnhancerController getLoudnessEnhancerController() {
+ if(loudnessAvailable && released) {
+ released = false;
+ try {
+ init();
+ } catch (Throwable x) {
+ loudnessEnhancerController = null;
+ Log.w(TAG, "Failed to create loudness enhancer.", x);
+ }
+ }
+ return loudnessEnhancerController;
+ }
- private static class EqualizerSettings implements Serializable {
+ private static class EqualizerSettings implements Serializable {
- private short[] bandLevels;
- private short preset;
- private boolean enabled;
+ private short[] bandLevels;
+ private short preset;
+ private boolean enabled;
+ private short bass;
+ private int loudness;
public EqualizerSettings() {
}
- public EqualizerSettings(Equalizer equalizer) {
- enabled = equalizer.getEnabled();
- bandLevels = new short[equalizer.getNumberOfBands()];
- for (short i = 0; i < equalizer.getNumberOfBands(); i++) {
- bandLevels[i] = equalizer.getBandLevel(i);
- }
- try {
- preset = equalizer.getCurrentPreset();
- } catch (Exception x) {
- preset = -1;
- }
- }
-
- public void apply(Equalizer equalizer) {
- for (short i = 0; i < bandLevels.length; i++) {
- equalizer.setBandLevel(i, bandLevels[i]);
- }
- if (preset >= 0 && preset < equalizer.getNumberOfPresets()) {
- equalizer.usePreset(preset);
- }
- equalizer.setEnabled(enabled);
- }
- }
+ public EqualizerSettings(Equalizer equalizer, BassBoost boost, LoudnessEnhancerController loudnessEnhancerController) {
+ enabled = equalizer.getEnabled();
+ bandLevels = new short[equalizer.getNumberOfBands()];
+ for (short i = 0; i < equalizer.getNumberOfBands(); i++) {
+ bandLevels[i] = equalizer.getBandLevel(i);
+ }
+ try {
+ preset = equalizer.getCurrentPreset();
+ } catch (Exception x) {
+ preset = -1;
+ }
+ try {
+ bass = boost.getRoundedStrength();
+ } catch(Exception e) {
+ bass = 0;
+ }
+
+ try {
+ loudness = (int) loudnessEnhancerController.getGain();
+ } catch(Exception e) {
+ loudness = 0;
+ }
+ }
+
+ public void apply(Equalizer equalizer, BassBoost boost, LoudnessEnhancerController loudnessController) {
+ for (short i = 0; i < bandLevels.length; i++) {
+ equalizer.setBandLevel(i, bandLevels[i]);
+ }
+ if (preset >= 0 && preset < equalizer.getNumberOfPresets()) {
+ equalizer.usePreset(preset);
+ }
+ equalizer.setEnabled(enabled);
+ if(bass != 0) {
+ boost.setEnabled(true);
+ boost.setStrength(bass);
+ }
+ if(loudness != 0) {
+ loudnessController.enable();
+ loudnessController.setGain(loudness);
+ }
+ }
+ }
}
diff --git a/src/github/daneren2005/dsub/audiofx/LoudnessEnhancerController.java b/src/github/daneren2005/dsub/audiofx/LoudnessEnhancerController.java
new file mode 100644
index 00000000..df6fdb1c
--- /dev/null
+++ b/src/github/daneren2005/dsub/audiofx/LoudnessEnhancerController.java
@@ -0,0 +1,77 @@
+/*
+ This file is part of Subsonic.
+
+ Subsonic is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Subsonic is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
+
+ Copyright 2014 (C) Scott Jackson
+*/
+package github.daneren2005.dsub.audiofx;
+
+import android.content.Context;
+import android.media.audiofx.LoudnessEnhancer;
+import android.util.Log;
+
+public class LoudnessEnhancerController {
+ private static final String TAG = LoudnessEnhancerController.class.getSimpleName();
+
+ private final Context context;
+ private LoudnessEnhancer enhancer;
+ private boolean released = false;
+ private int audioSessionId = 0;
+
+ public LoudnessEnhancerController(Context context, int audioSessionId) {
+ this.context = context;
+ try {
+ this.audioSessionId = audioSessionId;
+ enhancer = new LoudnessEnhancer(audioSessionId);
+ } catch (Throwable x) {
+ Log.w(TAG, "Failed to create enhancer", x);
+ }
+ }
+
+ public boolean isAvailable() {
+ return enhancer != null;
+ }
+
+ public boolean isEnabled() {
+ try {
+ return isAvailable() && enhancer.getEnabled();
+ } catch(Exception e) {
+ return false;
+ }
+ }
+
+ public void enable() {
+ enhancer.setEnabled(true);
+ }
+ public void disable() {
+ enhancer.setEnabled(false);
+ }
+
+ public float getGain() {
+ return enhancer.getTargetGain();
+ }
+ public void setGain(int gain) {
+ enhancer.setTargetGain(gain);
+ }
+
+ public void release() {
+ if (isAvailable()) {
+ enhancer.release();
+ released = true;
+ }
+ }
+
+}
+
diff --git a/src/github/daneren2005/dsub/audiofx/VisualizerController.java b/src/github/daneren2005/dsub/audiofx/VisualizerController.java
index b32245f4..92e3712c 100644
--- a/src/github/daneren2005/dsub/audiofx/VisualizerController.java
+++ b/src/github/daneren2005/dsub/audiofx/VisualizerController.java
@@ -19,7 +19,6 @@
package github.daneren2005.dsub.audiofx;
import android.content.Context;
-import android.media.MediaPlayer;
import android.media.audiofx.Visualizer;
import android.util.Log;
@@ -31,63 +30,63 @@ import android.util.Log;
*/
public class VisualizerController {
- private static final String TAG = VisualizerController.class.getSimpleName();
- private static final int PREFERRED_CAPTURE_SIZE = 128; // Must be a power of two.
+ private static final String TAG = VisualizerController.class.getSimpleName();
+ private static final int PREFERRED_CAPTURE_SIZE = 128; // Must be a power of two.
- private final Context context;
- private Visualizer visualizer;
+ private final Context context;
+ private Visualizer visualizer;
private boolean released = false;
private int audioSessionId = 0;
- // Class initialization fails when this throws an exception.
- static {
- try {
- Class.forName("android.media.audiofx.Visualizer");
- } catch (Exception ex) {
- throw new RuntimeException(ex);
- }
- }
-
- /**
- * Throws an exception if the {@link Visualizer} class is not available.
- */
- public static void checkAvailable() throws Throwable {
- // Calling here forces class initialization.
- }
-
- public VisualizerController(Context context, MediaPlayer mediaPlayer) {
- this.context = context;
- try {
- audioSessionId = mediaPlayer.getAudioSessionId();
- visualizer = new Visualizer(audioSessionId);
- } catch (Throwable x) {
- Log.w(TAG, "Failed to create visualizer.", x);
- }
-
- if (visualizer != null) {
- int[] captureSizeRange = Visualizer.getCaptureSizeRange();
- int captureSize = Math.max(PREFERRED_CAPTURE_SIZE, captureSizeRange[0]);
- captureSize = Math.min(captureSize, captureSizeRange[1]);
- visualizer.setCaptureSize(captureSize);
- }
- }
-
- public boolean isAvailable() {
- return visualizer != null;
- }
-
- public boolean isEnabled() {
- return isAvailable() && visualizer.getEnabled();
- }
-
- public void release() {
- if (isAvailable()) {
- visualizer.release();
+ // Class initialization fails when this throws an exception.
+ static {
+ try {
+ Class.forName("android.media.audiofx.Visualizer");
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ /**
+ * Throws an exception if the {@link Visualizer} class is not available.
+ */
+ public static void checkAvailable() throws Throwable {
+ // Calling here forces class initialization.
+ }
+
+ public VisualizerController(Context context, int audioSessionId) {
+ this.context = context;
+ try {
+ this.audioSessionId = audioSessionId;
+ visualizer = new Visualizer(audioSessionId);
+ } catch (Throwable x) {
+ Log.w(TAG, "Failed to create visualizer.", x);
+ }
+
+ if (visualizer != null) {
+ int[] captureSizeRange = Visualizer.getCaptureSizeRange();
+ int captureSize = Math.max(PREFERRED_CAPTURE_SIZE, captureSizeRange[0]);
+ captureSize = Math.min(captureSize, captureSizeRange[1]);
+ visualizer.setCaptureSize(captureSize);
+ }
+ }
+
+ public boolean isAvailable() {
+ return visualizer != null;
+ }
+
+ public boolean isEnabled() {
+ return isAvailable() && visualizer.getEnabled();
+ }
+
+ public void release() {
+ if (isAvailable()) {
+ visualizer.release();
released = true;
- }
- }
+ }
+ }
- public Visualizer getVisualizer() {
+ public Visualizer getVisualizer() {
if(released) {
released = false;
try {
@@ -97,8 +96,8 @@ public class VisualizerController {
Log.w(TAG, "Failed to create visualizer.", x);
}
}
-
- return visualizer;
- }
+
+ return visualizer;
+ }
}
diff --git a/src/github/daneren2005/dsub/fragments/DownloadFragment.java b/src/github/daneren2005/dsub/fragments/DownloadFragment.java
index 835394ae..d9091b55 100644
--- a/src/github/daneren2005/dsub/fragments/DownloadFragment.java
+++ b/src/github/daneren2005/dsub/fragments/DownloadFragment.java
@@ -464,13 +464,10 @@ public class DownloadFragment extends SubsonicFragment implements OnGestureListe
downloadService.setShufflePlayEnabled(true);
}
- boolean visualizerAvailable = downloadService != null && downloadService.getVisualizerAvailable();
boolean equalizerAvailable = downloadService != null && downloadService.getEqualizerAvailable();
if (!equalizerAvailable) {
equalizerButton.setVisibility(View.GONE);
- }
- if (!visualizerAvailable) {
visualizerButton.setVisibility(View.GONE);
} else {
visualizerView = new VisualizerView(context);
diff --git a/src/github/daneren2005/dsub/fragments/EqualizerFragment.java b/src/github/daneren2005/dsub/fragments/EqualizerFragment.java
index 71067d7c..1475ccdd 100644
--- a/src/github/daneren2005/dsub/fragments/EqualizerFragment.java
+++ b/src/github/daneren2005/dsub/fragments/EqualizerFragment.java
@@ -19,8 +19,10 @@
package github.daneren2005.dsub.fragments;
import android.content.SharedPreferences;
+import android.media.audiofx.BassBoost;
import android.media.audiofx.Equalizer;
import android.os.Bundle;
+import android.util.Log;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.MenuItem;
@@ -37,6 +39,7 @@ import java.util.Map;
import github.daneren2005.dsub.R;
import github.daneren2005.dsub.audiofx.EqualizerController;
+import github.daneren2005.dsub.audiofx.LoudnessEnhancerController;
import github.daneren2005.dsub.service.DownloadService;
import github.daneren2005.dsub.util.Constants;
import github.daneren2005.dsub.util.Util;
@@ -50,20 +53,28 @@ public class EqualizerFragment extends SubsonicFragment {
private static final int MENU_GROUP_PRESET = 100;
private final Map<Short, SeekBar> bars = new HashMap<Short, SeekBar>();
+ private SeekBar bassBar;
+ private SeekBar loudnessBar;
private EqualizerController equalizerController;
private Equalizer equalizer;
+ private BassBoost bass;
+ private LoudnessEnhancerController loudnessEnhancer;
private short masterLevel = 0;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
rootView = inflater.inflate(R.layout.equalizer, container, false);
- equalizerController = DownloadService.getInstance().getEqualizerController();
+ DownloadService service = DownloadService.getInstance();
+ equalizerController = service.getEqualizerController();
equalizer = equalizerController.getEqualizer();
+ bass = equalizerController.getBassBoost();
+ loudnessEnhancer = equalizerController.getLoudnessEnhancerController();
try {
initEqualizer();
} catch(Exception e) {
+ Log.e(TAG, "Failed to initialize EQ", e);
Util.toast(context, "Failed to initialize EQ");
context.onBackPressed();
}
@@ -106,6 +117,7 @@ public class EqualizerFragment extends SubsonicFragment {
super.onResume();
equalizerController = DownloadService.getInstance().getEqualizerController();
equalizer = equalizerController.getEqualizer();
+ bass = equalizerController.getBassBoost();
}
@Override
@@ -180,6 +192,11 @@ public class EqualizerFragment extends SubsonicFragment {
}
}
+ bassBar.setEnabled(isEnabled);
+ if(loudnessBar != null) {
+ loudnessBar.setEnabled(isEnabled);
+ }
+
if(!isEnabled) {
masterLevel = 0;
SharedPreferences prefs = Util.getPreferences(context);
@@ -240,6 +257,98 @@ public class EqualizerFragment extends SubsonicFragment {
});
layout.addView(bandBar);
}
+
+ LinearLayout specialLayout = (LinearLayout) rootView.findViewById(R.id.special_effects_layout);
+
+ // Setup bass booster
+ View bandBar = LayoutInflater.from(context).inflate(R.layout.equalizer_bar, null);
+ TextView freqTextView = (TextView) bandBar.findViewById(R.id.equalizer_frequency);
+ final TextView bassTextView = (TextView) bandBar.findViewById(R.id.equalizer_level);
+ bassBar = (SeekBar) bandBar.findViewById(R.id.equalizer_bar);
+
+ freqTextView.setText(R.string.equalizer_bass_booster);
+ bassBar.setEnabled(equalizer.getEnabled());
+ short bassLevel = 0;
+ if(bass.getEnabled()) {
+ bassLevel = bass.getRoundedStrength();
+ }
+ bassTextView.setText(context.getResources().getString(R.string.equalizer_bass_size, bassLevel));
+ bassBar.setMax(1000);
+ bassBar.setProgress(bassLevel);
+ bassBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ bassTextView.setText(context.getResources().getString(R.string.equalizer_bass_size, progress));
+ if(fromUser) {
+ if(progress > 0) {
+ if(!bass.getEnabled()) {
+ bass.setEnabled(true);
+ }
+ bass.setStrength((short) progress);
+ } else if(progress == 0 && bass.getEnabled()) {
+ bass.setStrength((short) progress);
+ bass.setEnabled(false);
+ }
+ }
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+
+ }
+ });
+ specialLayout.addView(bandBar);
+
+ if(loudnessEnhancer != null && loudnessEnhancer.isAvailable()) {
+ // Setup loudness enhancer
+ bandBar = LayoutInflater.from(context).inflate(R.layout.equalizer_bar, null);
+ freqTextView = (TextView) bandBar.findViewById(R.id.equalizer_frequency);
+ final TextView loudnessTextView = (TextView) bandBar.findViewById(R.id.equalizer_level);
+ loudnessBar = (SeekBar) bandBar.findViewById(R.id.equalizer_bar);
+
+ freqTextView.setText(R.string.equalizer_voice_booster);
+ loudnessBar.setEnabled(equalizer.getEnabled());
+ int loudnessLevel = 0;
+ if(loudnessEnhancer.isEnabled()) {
+ loudnessLevel = (int) loudnessEnhancer.getGain();
+ }
+ loudnessBar.setProgress(loudnessLevel / 100);
+ loudnessTextView.setText(context.getResources().getString(R.string.equalizer_db_size, loudnessLevel / 100));
+ loudnessBar.setMax(15);
+ loudnessBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ loudnessTextView.setText(context.getResources().getString(R.string.equalizer_db_size, progress));
+ if(fromUser) {
+ if(progress > 0) {
+ if(!loudnessEnhancer.isEnabled()) {
+ loudnessEnhancer.enable();
+ }
+ loudnessEnhancer.setGain(progress * 100);
+ } else if(progress == 0 && loudnessEnhancer.isEnabled()) {
+ loudnessEnhancer.setGain(progress * 100);
+ loudnessEnhancer.disable();
+ }
+ }
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+
+ }
+ });
+ specialLayout.addView(bandBar);
+ }
}
private void initPregain(LinearLayout layout, final short minEQLevel, final short maxEQLevel) {
@@ -285,6 +394,6 @@ public class EqualizerFragment extends SubsonicFragment {
}
private void updateLevelText(TextView levelTextView, short level) {
- levelTextView.setText((level > 0 ? "+" : "") + level / 100 + " dB");
+ levelTextView.setText((level > 0 ? "+" : "") + context.getResources().getString(R.string.equalizer_db_size, level / 100));
}
}
diff --git a/src/github/daneren2005/dsub/receiver/MediaButtonIntentReceiver.java b/src/github/daneren2005/dsub/receiver/MediaButtonIntentReceiver.java
index 89a4a87b..8119ef2d 100644
--- a/src/github/daneren2005/dsub/receiver/MediaButtonIntentReceiver.java
+++ b/src/github/daneren2005/dsub/receiver/MediaButtonIntentReceiver.java
@@ -36,18 +36,22 @@ public class MediaButtonIntentReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
KeyEvent event = (KeyEvent) intent.getExtras().get(Intent.EXTRA_KEY_EVENT);
+ if(DownloadService.getInstance() == null && (event.getKeyCode() == KeyEvent.KEYCODE_MEDIA_STOP ||
+ event.getKeyCode() == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE || event.getKeyCode() == KeyEvent.KEYCODE_HEADSETHOOK)) {
+ Log.w(TAG, "Ignore keycode event because downloadService is off");
+ return;
+ }
Log.i(TAG, "Got MEDIA_BUTTON key event: " + event);
Intent serviceIntent = new Intent(context, DownloadService.class);
serviceIntent.putExtra(Intent.EXTRA_KEY_EVENT, event);
context.startService(serviceIntent);
- if (isOrderedBroadcast())
- {
- try {
- abortBroadcast();
- } catch (Exception x) {
- // Ignored.
+ if (isOrderedBroadcast()) {
+ try {
+ abortBroadcast();
+ } catch (Exception x) {
+ // Ignored.
+ }
}
- }
}
}
diff --git a/src/github/daneren2005/dsub/service/ChromeCastController.java b/src/github/daneren2005/dsub/service/ChromeCastController.java
index 02661f14..9ff0f54a 100644
--- a/src/github/daneren2005/dsub/service/ChromeCastController.java
+++ b/src/github/daneren2005/dsub/service/ChromeCastController.java
@@ -245,7 +245,6 @@ public class ChromeCastController extends RemoteController {
}
url = fixURLs(url);
- Log.i(TAG, "Cast url: " + url);
}
// Setup song/video information
@@ -271,7 +270,6 @@ public class ChromeCastController extends RemoteController {
meta.addImage(new WebImage(Uri.parse(coverArt)));
}
}
- Log.i(TAG, "Cover art: " + coverArt);
}
String contentType;
diff --git a/src/github/daneren2005/dsub/service/DownloadService.java b/src/github/daneren2005/dsub/service/DownloadService.java
index 76ec8396..7b4ddf31 100644
--- a/src/github/daneren2005/dsub/service/DownloadService.java
+++ b/src/github/daneren2005/dsub/service/DownloadService.java
@@ -27,7 +27,10 @@ import static github.daneren2005.dsub.domain.PlayerState.PREPARED;
import static github.daneren2005.dsub.domain.PlayerState.PREPARING;
import static github.daneren2005.dsub.domain.PlayerState.STARTED;
import static github.daneren2005.dsub.domain.PlayerState.STOPPED;
+
+import github.daneren2005.dsub.audiofx.AudioEffectsController;
import github.daneren2005.dsub.audiofx.EqualizerController;
+import github.daneren2005.dsub.audiofx.LoudnessEnhancerController;
import github.daneren2005.dsub.audiofx.VisualizerController;
import github.daneren2005.dsub.domain.Bookmark;
import github.daneren2005.dsub.domain.MusicDirectory;
@@ -94,6 +97,7 @@ public class DownloadService extends Service {
private Looper mediaPlayerLooper;
private MediaPlayer mediaPlayer;
private MediaPlayer nextMediaPlayer;
+ private int audioSessionId;
private boolean nextSetup = false;
private boolean isPartial = true;
private final List<DownloadFile> downloadList = new ArrayList<DownloadFile>();
@@ -128,10 +132,7 @@ public class DownloadService extends Service {
private boolean downloadOngoing = false;
private DownloadFile lastDownloaded = null;
- private static boolean equalizerAvailable;
- private static boolean visualizerAvailable;
- private EqualizerController equalizerController;
- private VisualizerController visualizerController;
+ private AudioEffectsController effectsController;
private boolean showVisualization;
private RemoteControlState remoteState = RemoteControlState.LOCAL;
private PositionCache positionCache;
@@ -143,23 +144,18 @@ public class DownloadService extends Service {
private MediaRouteManager mediaRouter;
- static {
- if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
- equalizerAvailable = true;
- visualizerAvailable = true;
- }
- }
-
@Override
public void onCreate() {
super.onCreate();
+ final SharedPreferences prefs = Util.getPreferences(this);
new Thread(new Runnable() {
public void run() {
Looper.prepare();
mediaPlayer = new MediaPlayer();
mediaPlayer.setWakeMode(DownloadService.this, PowerManager.PARTIAL_WAKE_LOCK);
+ mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
@@ -168,16 +164,27 @@ public class DownloadService extends Service {
return false;
}
});
+ audioSessionId = mediaPlayer.getAudioSessionId();
+ Log.d(TAG, "id: " + audioSessionId);
try {
Intent i = new Intent(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION);
- i.putExtra(AudioEffect.EXTRA_AUDIO_SESSION, mediaPlayer.getAudioSessionId());
+ i.putExtra(AudioEffect.EXTRA_AUDIO_SESSION, audioSessionId);
i.putExtra(AudioEffect.EXTRA_PACKAGE_NAME, getPackageName());
sendBroadcast(i);
} catch(Throwable e) {
// Froyo or lower
}
+ effectsController = new AudioEffectsController(DownloadService.this, audioSessionId);
+ if(prefs.getBoolean(Constants.PREFERENCES_EQUALIZER_ON, false)) {
+ getEqualizerController();
+ }
+ if(prefs.getBoolean(Constants.PREFERENCES_VISUALIZER_ON, false)) {
+ getVisualizerController();
+ showVisualization = true;
+ }
+
mediaPlayerLooper = Looper.myLooper();
mediaPlayerHandler = new Handler(mediaPlayerLooper);
Looper.loop();
@@ -197,7 +204,6 @@ public class DownloadService extends Service {
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, this.getClass().getName());
wakeLock.setReferenceCounted(false);
- SharedPreferences prefs = Util.getPreferences(this);
try {
timerDuration = Integer.parseInt(prefs.getString(Constants.PREFERENCES_KEY_SLEEP_TIMER_DURATION, "5"));
} catch(Throwable e) {
@@ -211,14 +217,6 @@ public class DownloadService extends Service {
instance = this;
lifecycleSupport.onCreate();
-
- if(prefs.getBoolean(Constants.PREFERENCES_EQUALIZER_ON, false)) {
- getEqualizerController();
- }
- if(prefs.getBoolean(Constants.PREFERENCES_VISUALIZER_ON, false)) {
- getVisualizerController();
- showVisualization = true;
- }
}
@Override
@@ -255,12 +253,7 @@ public class DownloadService extends Service {
}
mediaPlayerLooper.quit();
shufflePlayBuffer.shutdown();
- if (equalizerController != null) {
- equalizerController.release();
- }
- if (visualizerController != null) {
- visualizerController.release();
- }
+ effectsController.release();
if (mRemoteControl != null) {
mRemoteControl.unregister(this);
mRemoteControl = null;
@@ -1079,33 +1072,15 @@ public class DownloadService extends Service {
}
public boolean getEqualizerAvailable() {
- return equalizerAvailable;
- }
-
- public boolean getVisualizerAvailable() {
- return visualizerAvailable;
+ return effectsController.isAvailable();
}
public EqualizerController getEqualizerController() {
- if (equalizerAvailable && equalizerController == null) {
- equalizerController = new EqualizerController(this, mediaPlayer);
- if (!equalizerController.isAvailable()) {
- equalizerController = null;
- } else {
- equalizerController.loadSettings();
- }
- }
- return equalizerController;
+ return effectsController.getEqualizerController();
}
public VisualizerController getVisualizerController() {
- if (visualizerAvailable && visualizerController == null) {
- visualizerController = new VisualizerController(this, mediaPlayer);
- if (!visualizerController.isAvailable()) {
- visualizerController = null;
- }
- }
- return visualizerController;
+ return effectsController.getVisualizerController();
}
public MediaRouteSelector getRemoteSelector() {
@@ -1251,7 +1226,11 @@ public class DownloadService extends Service {
mediaPlayer.setOnCompletionListener(null);
mediaPlayer.reset();
setPlayerState(IDLE);
- mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
+ try {
+ mediaPlayer.setAudioSessionId(audioSessionId);
+ } catch(Exception e) {
+ mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
+ }
String dataSource = file.getPath();
if(isPartial) {
if (proxy == null) {
@@ -1334,7 +1313,7 @@ public class DownloadService extends Service {
nextMediaPlayer = new MediaPlayer();
nextMediaPlayer.setWakeMode(DownloadService.this, PowerManager.PARTIAL_WAKE_LOCK);
try {
- nextMediaPlayer.setAudioSessionId(mediaPlayer.getAudioSessionId());
+ nextMediaPlayer.setAudioSessionId(audioSessionId);
} catch(Throwable e) {
nextMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
}
@@ -1465,7 +1444,7 @@ public class DownloadService extends Service {
}
public void setVolume(float volume) {
- if(mediaPlayer != null) {
+ if(mediaPlayer != null && (playerState == STARTED || playerState == PAUSED || playerState == STOPPED)) {
mediaPlayer.setVolume(volume, volume);
}
}
@@ -1500,7 +1479,11 @@ public class DownloadService extends Service {
}
private void handleErrorNext(Exception x) {
Log.w(TAG, "Next Media player error: " + x, x);
- nextMediaPlayer.reset();
+ try {
+ nextMediaPlayer.reset();
+ } catch(Exception e) {
+ Log.e(TAG, "Failed to reset next media player", x);
+ }
setNextPlayerState(IDLE);
}
diff --git a/src/github/daneren2005/dsub/service/RESTMusicService.java b/src/github/daneren2005/dsub/service/RESTMusicService.java
index 879339cc..6c4872e9 100644
--- a/src/github/daneren2005/dsub/service/RESTMusicService.java
+++ b/src/github/daneren2005/dsub/service/RESTMusicService.java
@@ -203,6 +203,18 @@ public class RESTMusicService implements MusicService {
return cachedIndexes;
}
+ // If manual refresh, try to start server scan for madsonic servers
+ if(refresh) {
+ Reader reader = getReader(context, progressListener, "startRescan", null);
+ try {
+ new ErrorParser(context).parse(reader);
+ } catch(Exception e) {
+ // Probably not madsonic, don't care
+ } finally {
+ Util.close(reader);
+ }
+ }
+
long lastModified = (cachedIndexes == null || refresh) ? 0L : cachedIndexes.getLastModified();
List<String> parameterNames = new ArrayList<String>();
@@ -715,7 +727,7 @@ public class RESTMusicService implements MusicService {
builder.append("&maxBitRate=").append(maxBitrate);
String url = rewriteUrlWithRedirect(context, builder.toString());
- Log.i(TAG, "Using music URL: " + url);
+ Log.i(TAG, "Using music URL: " + stripUrlInfo(url));
return url;
}
@@ -727,7 +739,7 @@ public class RESTMusicService implements MusicService {
builder.append("&autoplay=true");
String url = rewriteUrlWithRedirect(context, builder.toString());
- Log.i(TAG, "Using video URL: " + url);
+ Log.i(TAG, "Using video URL: " + stripUrlInfo(url));
return url;
}
@@ -742,7 +754,7 @@ public class RESTMusicService implements MusicService {
builder.append("&format=").append(format);
String url = rewriteUrlWithRedirect(context, builder.toString());
- Log.i(TAG, "Using video URL: " + url);
+ Log.i(TAG, "Using video URL: " + stripUrlInfo(url));
return url;
}
@@ -757,7 +769,7 @@ public class RESTMusicService implements MusicService {
}
String url = rewriteUrlWithRedirect(context, builder.toString());
- Log.i(TAG, "Using hls URL: " + url);
+ Log.i(TAG, "Using hls URL: " + stripUrlInfo(url));
return url;
}
@@ -1341,8 +1353,8 @@ public class RESTMusicService implements MusicService {
List<String> parameterNames, List<Object> parameterValues,
List<Header> headers, ProgressListener progressListener, CancellableTask task) throws IOException {
// Strip out sensitive information from log
- Log.i(TAG, "Using URL " + url.substring(0, url.indexOf("?u=") + 1) + url.substring(url.indexOf("&v=") + 1));
-
+ Log.i(TAG, stripUrlInfo(url));
+
SharedPreferences prefs = Util.getPreferences(context);
int networkTimeout = Integer.parseInt(prefs.getString(Constants.PREFERENCES_KEY_NETWORK_TIMEOUT, "15000"));
HttpParams newParams = httpClient.getParams();
@@ -1476,6 +1488,10 @@ public class RESTMusicService implements MusicService {
return url.replace(redirectFrom, redirectTo);
}
+ private String stripUrlInfo(String url) {
+ return url.substring(0, url.indexOf("?u=") + 1) + url.substring(url.indexOf("&v=") + 1);
+ }
+
private int getCurrentNetworkType(Context context) {
ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = manager.getActiveNetworkInfo();