aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--res/layout-land/download.xml37
-rw-r--r--res/layout-port/download.xml16
-rw-r--r--res/layout/equalizer.xml6
-rw-r--r--res/values-es/strings.xml10
-rw-r--r--res/values-hu/strings.xml12
-rw-r--r--res/values/strings.xml4
-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
17 files changed, 604 insertions, 249 deletions
diff --git a/res/layout-land/download.xml b/res/layout-land/download.xml
index dfdb126a..b6ac32cd 100644
--- a/res/layout-land/download.xml
+++ b/res/layout-land/download.xml
@@ -33,13 +33,18 @@
</github.daneren2005.dsub.view.MyViewFlipper>
- <LinearLayout android:orientation="vertical"
+ <RelativeLayout android:orientation="vertical"
android:id="@+id/download_control_layout"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="1"
android:background="@android:color/transparent">
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerHorizontal="true">
+
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/download_other_controls_layout"
android:orientation="horizontal"
@@ -67,6 +72,7 @@
style="@style/DownloadActionImageButton"
android:src="?attr/bookmark"/>
</LinearLayout>
+ </LinearLayout>
<LinearLayout
android:id="@+id/download_visualizer_view_layout"
@@ -75,7 +81,8 @@
android:layout_height="60dip"
android:layout_marginLeft="12dip"
android:layout_marginRight="12dip"
- android:layout_gravity="center_horizontal"/>
+ android:layout_gravity="center_horizontal"
+ android:layout_above="@+id/download_song_title"/>
<TextView
android:id="@+id/download_song_title"
@@ -88,7 +95,8 @@
android:ellipsize="end"
android:gravity="center_horizontal"
android:textAppearance="?android:attr/textAppearanceMedium"
- android:textColor="?android:textColorPrimary"/>
+ android:textColor="?android:textColorPrimary"
+ android:layout_above="@+id/download_status"/>
<TextView
android:id="@+id/download_status"
@@ -101,13 +109,28 @@
android:singleLine="true"
android:ellipsize="end"
android:textAppearance="?android:attr/textAppearanceSmall"
- android:textColor="?android:textColorSecondary" />
+ android:textColor="?android:textColorSecondary"
+ android:layout_above="@+id/download_media_buttons_wrapper"/>
- <include layout="@layout/download_media_buttons"/>
+ <LinearLayout
+ android:id="@+id/download_media_buttons_wrapper"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_above="@+id/download_slider_wrapper">
+
+ <include layout="@layout/download_media_buttons"/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/download_slider_wrapper"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentBottom="true">
- <include layout="@layout/download_slider"/>
+ <include layout="@layout/download_slider"/>
+ </LinearLayout>
- </LinearLayout>
+ </RelativeLayout>
</LinearLayout>
</LinearLayout>
diff --git a/res/layout-port/download.xml b/res/layout-port/download.xml
index 7aa83fb5..f2a1df1c 100644
--- a/res/layout-port/download.xml
+++ b/res/layout-port/download.xml
@@ -24,25 +24,24 @@
android:layout_weight="1"
android:background="@android:color/transparent">
- <RelativeLayout android:orientation="vertical"
+ <FrameLayout android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_above="@+id/download_song_title">
+ android:layout_alignParentTop="true">
<ImageView
android:id="@+id/download_album_art_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_centerHorizontal="true"
- android:layout_alignParentTop="true"
- android:scaleType="fitCenter"/>
+ android:scaleType="fitCenter"
+ android:layout_gravity="center_horizontal|top"/>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/download_overlay_buttons"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@color/overlayColor"
- android:layout_alignParentBottom="true">
+ android:layout_gravity="center_horizontal|bottom">
<LinearLayout
android:layout_width="wrap_content"
@@ -86,9 +85,8 @@
android:layout_height="60dip"
android:layout_marginLeft="16dip"
android:layout_marginRight="16dip"
- android:layout_gravity="center_horizontal"
- android:layout_alignParentBottom="true"/>
- </RelativeLayout>
+ android:layout_gravity="center_horizontal|bottom"/>
+ </FrameLayout>
<TextView
android:id="@+id/download_status"
diff --git a/res/layout/equalizer.xml b/res/layout/equalizer.xml
index 6e3c7e5c..3f501a7a 100644
--- a/res/layout/equalizer.xml
+++ b/res/layout/equalizer.xml
@@ -22,6 +22,12 @@
android:layout_width="fill_parent"
android:layout_height="wrap_content">
+ <LinearLayout
+ android:id="@+id/special_effects_layout"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"/>
+
<LinearLayout
android:id="@+id/equalizer_layout"
android:orientation="vertical"
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index cb245e83..6b3e7c5b 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -23,6 +23,7 @@
<string name="common.confirm">Confirmar</string>
<string name="common.confirm_message">Quieres %1$s %2$s?</string>
<string name="common.empty">No se ha encontrado nada</string>
+ <string name="common.warning">Aviso</string>
<string name="button_bar.home">Inicio</string>
<string name="button_bar.browse">Biblioteca</string>
@@ -82,6 +83,7 @@
<string name="menu.show_artist">Mostrar artista</string>
<string name="menu.share">Compartir</string>
<string name="menu.delete_cache">Borrar cache</string>
+ <string name="menu.cast">Hacer streaming al dispositivo</string>
<string name="playlist.label">Listas de reproducción</string>
<string name="playlist.update_info">Actualizar información</string>
@@ -191,6 +193,11 @@
<string name="download.save_bookmark">Marcador creado</string>
<string name="download.downloading_title">Descargando %1$d canciones</string>
<string name="download.downloading_summary">En este momento: %1$s</string>
+ <string name="download.downloading_summary_expanded">Actual: %1$s
+ \nTamaño medio: %2$s
+ \nVelocidad media: %3$s kbps
+ </string>
+ <string name="download.failed_to_load">Error al cargar</string>
<string name="starring_content_starred">Marcado con estrella \"%s\"</string>
<string name="starring_content_unstarred">Sin marca de estrella \"%s\"</string>
@@ -376,6 +383,9 @@
<string name="settings.browse_by_tags_summary">Explorar por tags en vez de por estructura de carpetas. Requiere Subsonic 4.7+</string>
<string name="settings.server_local_network_ssid" >SSID Red local</string>
<string name="settings.server_local_network_ssid_hint">SSID Actual: %s</string>
+ <string name="settings.cache_location_reset">No se puede escribir en la ubicación seleccionada para la caché. Si has actualizado recientemente el sistema operativo de tu dispositivo a KitKat 4.4, la manera en la que las apps escriben en la Tarjeta SD ha cambiado, por lo que sólo pueden escribir en una ubicación específica. La ubicación que utiliza DSub ha sido automáticamente cambiada por la ubicación correcta. Para eliminar todos los datos de la app anterior, tendrás que introducir la Tarjeta SD en el ordenador y eliminar la carpeta manualmente.</string>
+ <string name="settings.open_to_library">Acceder directamente a la biblioteca</string>
+ <string name="settings.open_to_library_summary">Acceder directamente a la pantalla de la biblioteca en lugar de abrir primero la pantalla principal.</string>
<string name="share.info">Dueño: %1$s
\nDescripción: %2$s
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index fafdeeeb..3cdab47c 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -23,6 +23,7 @@
<string name="common.confirm">Jóváhagyás</string>
<string name="common.confirm_message">Biztos benne: %1$s %2$s?</string>
<string name="common.empty">Nem található</string>
+ <string name="common.warning">Figyelem!</string>
<string name="button_bar.home">Főoldal</string>
<string name="button_bar.browse">Médiakönyvtár</string>
@@ -155,14 +156,14 @@
<string name="download.shuffle_loading">Kevert sorrendű lista betöltése...</string>
<string name="download.playerstate_downloading">Letöltés - %s</string>
<string name="download.playerstate_buffering">Pufferelés</string>
- <string name="download.playerstate_playing_shuffle">Kevert sorrendű</string>
+ <string name="download.playerstate_playing_shuffle">Kevert lejátszás</string>
<string name="download.menu_show_album">Ugrás az albumhoz</string>
<string name="download.menu_lyrics">Dalszöveg</string>
<string name="download.menu_remove">Eltávolítás a várólistáról</string>
<string name="download.menu_remove_all">Összes eltávolítása</string>
<string name="download.menu_screen_on">Kijelző be</string>
<string name="download.menu_screen_off">Kijelző ki</string>
- <string name="download.menu_shuffle">Kevert sorrendű</string>
+ <string name="download.menu_shuffle">Kevert sorrendben</string>
<string name="download.menu_toggle">Váltás</string>
<string name="download.menu_save">Mentés lejátszási listába</string>
<string name="download.menu_shuffle_notification">Kevert sorrendű lejátszás</string>
@@ -255,6 +256,7 @@
<string name="settings.cache_size">Gyorsítótár mérete (MB)</string>
<string name="settings.cache_location">Gyorsítótár helye</string>
<string name="settings.cache_location_error">Hibás gyorsítótár hely! Az alapértelmezett használata.</string>
+ <string name="settings.cache_location_reset">A beállított gyorsítótár hely már nem írható! Ha a közelmúltban frissítette telefonja Android rendszerét 4.4.x KitKat verzióra, abban az SD kártya kezelése megváltozott, és az alkalmazások csak egy speciális helyre tudnak írni. A Dsub már automatikusan átállt a megfelelő helyre. Ahhoz, hogy a régi adatokat törölni tudja, csatlakoztassa az SD kártyát a számítógépéhez, és törölje a régi mappát!</string>
<string name="settings.cache_clear">Gyorsítótár törlése</string>
<string name="settings.cache_clear_complete">Gyorsítótár törlése kész!</string>
<string name="settings.testing_connection">Kapcsolat tesztelése...</string>
@@ -274,7 +276,9 @@
<string name="settings.track_title">Dalsorszám megjelenítése #</string>
<string name="settings.track_summary">Dalsorszám megjelenítése # a dal címe előtt, ha létezik.</string>
<string name="settings.custom_sort">Egyéni rendezés</string>
- <string name="settings.custom_sort_summary">Könyvtárlisa rendezése a lemez sorszámának megfelelően. Ütközhet a kiszolgáló év szerinti albumrendezésével!</string>
+ <string name="settings.custom_sort_summary">A kiszolgáló alapértelmezett rendezésének felülbírálása, rendezés a lemez sorszáma és a kiadás éve alapján.</string>
+ <string name="settings.open_to_library">Médiakönyvtár megnyitása</string>
+ <string name="settings.open_to_library_summary">A Médiakönyvtár megnyitása a Főoldal helyett.</string>
<string name="settings.network_title">Hálózat</string>
<string name="settings.max_bitrate_wifi">Max. audió bitráta - Wi-Fi</string>
<string name="settings.max_bitrate_mobile">Max. audió bitráta - Mobilhálózat</string>
@@ -396,7 +400,7 @@
<string name="settings.browse_by_tags">Böngészés ID3 Tag használatával</string>
<string name="settings.browse_by_tags_summary">ID3 Tag módszer használata a fájlredszer alapú mód helyett. Subsonic 4.7+ verzió felett!</string>
- <string name="shuffle.title">Kevert sorrend</string>
+ <string name="shuffle.title">Sorrend keverése</string>
<string name="shuffle.startYear">Kezdő év:</string>
<string name="shuffle.endYear">Befejező év:</string>
<string name="shuffle.genre">Műfaj:</string>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index a80f0c67..319396d3 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -453,6 +453,10 @@
<string name="equalizer.label">Equalizer</string>
<string name="equalizer.enabled">Enabled</string>
<string name="equalizer.preset">Select preset</string>
+ <string name="equalizer.bass_booster">Bass Booster</string>
+ <string name="equalizer.voice_booster">Voice Booster</string>
+ <string name="equalizer.db_size">%d dB</string>
+ <string name="equalizer.bass_size">%d mille</string>
<string name="widget.4x1">DSub (4x1)</string>
<string name="widget.4x2">DSub (4x2)</string>
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();