summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjörn Stenberg <bjorn@haxx.se>2011-03-14 12:25:48 +0000
committerBjörn Stenberg <bjorn@haxx.se>2011-03-14 12:25:48 +0000
commite50cc0e3d760d4fdb99f971070a6943ee15a9a98 (patch)
tree9d22cde7d39a2aefbc75cd970916fbc161f53cac
parent606bed035ed898df1d1bf4a8c7be904f76b118ff (diff)
downloadrockbox-e50cc0e3d760d4fdb99f971070a6943ee15a9a98.tar.gz
rockbox-e50cc0e3d760d4fdb99f971070a6943ee15a9a98.zip
Listen to and follow external Android volume changes. (Based on FS#11914 by Maurus Cuelenaere)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29586 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--android/src/org/rockbox/RockboxPCM.java52
-rw-r--r--apps/misc.c9
-rw-r--r--apps/playback.c2
-rw-r--r--apps/settings.c2
-rw-r--r--firmware/export/config/android.h3
-rw-r--r--firmware/export/kernel.h1
-rw-r--r--firmware/export/system.h4
-rw-r--r--firmware/target/hosted/android/pcm-android.c25
8 files changed, 95 insertions, 3 deletions
diff --git a/android/src/org/rockbox/RockboxPCM.java b/android/src/org/rockbox/RockboxPCM.java
index 5a8354abee..7d01da6150 100644
--- a/android/src/org/rockbox/RockboxPCM.java
+++ b/android/src/org/rockbox/RockboxPCM.java
@@ -23,8 +23,10 @@ package org.rockbox;
23 23
24import java.util.Arrays; 24import java.util.Arrays;
25 25
26import android.content.BroadcastReceiver;
26import android.content.Context; 27import android.content.Context;
27import android.content.Intent; 28import android.content.Intent;
29import android.content.IntentFilter;
28import android.media.AudioFormat; 30import android.media.AudioFormat;
29import android.media.AudioManager; 31import android.media.AudioManager;
30import android.media.AudioTrack; 32import android.media.AudioTrack;
@@ -52,8 +54,10 @@ public class RockboxPCM extends AudioTrack
52 54
53 private AudioManager audiomanager; 55 private AudioManager audiomanager;
54 private int maxstreamvolume; 56 private int maxstreamvolume;
57 private int setstreamvolume = -1;
55 private float minpcmvolume; 58 private float minpcmvolume;
56 private float pcmrange; 59 private float pcmrange;
60 private RockboxService rbservice;
57 61
58 private void LOG(CharSequence text) 62 private void LOG(CharSequence text)
59 { 63 {
@@ -72,15 +76,55 @@ public class RockboxPCM extends AudioTrack
72 l = new PCMListener(buf_len); 76 l = new PCMListener(buf_len);
73 77
74 /* find cleaner way to get context? */ 78 /* find cleaner way to get context? */
75 final RockboxService rb = RockboxService.get_instance(); 79 rbservice = RockboxService.get_instance();
76 audiomanager = 80 audiomanager =
77 (AudioManager) rb.getSystemService(Context.AUDIO_SERVICE); 81 (AudioManager) rbservice.getSystemService(Context.AUDIO_SERVICE);
78 maxstreamvolume = audiomanager.getStreamMaxVolume(streamtype); 82 maxstreamvolume = audiomanager.getStreamMaxVolume(streamtype);
79 83
80 minpcmvolume = getMinVolume(); 84 minpcmvolume = getMinVolume();
81 pcmrange = getMaxVolume() - minpcmvolume; 85 pcmrange = getMaxVolume() - minpcmvolume;
86
87 setupVolumeHandler();
82 } 88 }
83 89
90 private native void postVolumeChangedEvent(int volume);
91 private void setupVolumeHandler()
92 {
93 BroadcastReceiver broadcastReceiver = new BroadcastReceiver()
94 {
95 @Override
96 public void onReceive(Context context, Intent intent)
97 {
98 int streamType = intent.getIntExtra(
99 "android.media.EXTRA_VOLUME_STREAM_TYPE", -1);
100 int volume = intent.getIntExtra(
101 "android.media.EXTRA_VOLUME_STREAM_VALUE", -1);
102
103 if (streamType == RockboxPCM.streamtype &&
104 volume != -1 &&
105 volume != setstreamvolume &&
106 rbservice.isRockboxRunning())
107 {
108 int rbvolume = ((maxstreamvolume - volume) * -99) /
109 maxstreamvolume;
110 postVolumeChangedEvent(rbvolume);
111 }
112 }
113 };
114
115 /* at startup, change the internal rockbox volume to what the global
116 android music stream volume is */
117 int volume = audiomanager.getStreamVolume(streamtype);
118 int rbvolume = ((maxstreamvolume - volume) * -99) / maxstreamvolume;
119 postVolumeChangedEvent(rbvolume);
120
121 /* We're relying on internal API's here,
122 this can break in the future! */
123 rbservice.registerReceiver(
124 broadcastReceiver,
125 new IntentFilter("android.media.VOLUME_CHANGED_ACTION"));
126 }
127
84 private int bytes2frames(int bytes) 128 private int bytes2frames(int bytes)
85 { 129 {
86 /* 1 sample is 2 bytes, 2 samples are 1 frame */ 130 /* 1 sample is 2 bytes, 2 samples are 1 frame */
@@ -164,8 +208,10 @@ public class RockboxPCM extends AudioTrack
164 } 208 }
165 209
166 int oldstreamvolume = audiomanager.getStreamVolume(streamtype); 210 int oldstreamvolume = audiomanager.getStreamVolume(streamtype);
167 if (streamvolume != oldstreamvolume) 211 if (streamvolume != oldstreamvolume) {
212 setstreamvolume = streamvolume;
168 audiomanager.setStreamVolume(streamtype, streamvolume, 0); 213 audiomanager.setStreamVolume(streamtype, streamvolume, 0);
214 }
169 } 215 }
170 216
171 public native void pcmSamplesToByteArray(byte[] dest); 217 public native void pcmSamplesToByteArray(byte[] dest);
diff --git a/apps/misc.c b/apps/misc.c
index fa34c21f4e..995d65644e 100644
--- a/apps/misc.c
+++ b/apps/misc.c
@@ -636,6 +636,15 @@ long default_event_handler_ex(long event, void (*callback)(void *), void *parame
636 resume = false; 636 resume = false;
637 return SYS_CALL_HUNG_UP; 637 return SYS_CALL_HUNG_UP;
638#endif 638#endif
639#if (CONFIG_PLATFORM & PLATFORM_HOSTED) && defined(PLATFORM_HAS_VOLUME_CHANGE)
640 case SYS_VOLUME_CHANGED:
641 {
642 int volume = hosted_get_volume();
643 if (global_settings.volume != volume)
644 global_settings.volume = volume;
645 return 0;
646 }
647#endif
639#ifdef HAVE_MULTIMEDIA_KEYS 648#ifdef HAVE_MULTIMEDIA_KEYS
640 /* multimedia keys on keyboards, headsets */ 649 /* multimedia keys on keyboards, headsets */
641 case BUTTON_MULTIMEDIA_PLAYPAUSE: 650 case BUTTON_MULTIMEDIA_PLAYPAUSE:
diff --git a/apps/playback.c b/apps/playback.c
index b72ed8a3b8..fb79c4d382 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -1834,7 +1834,9 @@ static void audio_play_start(size_t offset)
1834 ci.seek_time = 0; 1834 ci.seek_time = 0;
1835 wps_offset = 0; 1835 wps_offset = 0;
1836 1836
1837#ifndef PLAFORM_HAS_VOLUME_CHANGE
1837 sound_set_volume(global_settings.volume); 1838 sound_set_volume(global_settings.volume);
1839#endif
1838 track_widx = track_ridx = 0; 1840 track_widx = track_ridx = 0;
1839 buf_set_base_handle(-1); 1841 buf_set_base_handle(-1);
1840 1842
diff --git a/apps/settings.c b/apps/settings.c
index e9458dc601..623bc5b2a0 100644
--- a/apps/settings.c
+++ b/apps/settings.c
@@ -726,7 +726,9 @@ void sound_settings_apply(void)
726 sound_set(SOUND_TREBLE, global_settings.treble); 726 sound_set(SOUND_TREBLE, global_settings.treble);
727#endif 727#endif
728 sound_set(SOUND_BALANCE, global_settings.balance); 728 sound_set(SOUND_BALANCE, global_settings.balance);
729#ifndef PLATFORM_HAS_VOLUME_CHANGE
729 sound_set(SOUND_VOLUME, global_settings.volume); 730 sound_set(SOUND_VOLUME, global_settings.volume);
731#endif
730 sound_set(SOUND_CHANNELS, global_settings.channel_config); 732 sound_set(SOUND_CHANNELS, global_settings.channel_config);
731 sound_set(SOUND_STEREO_WIDTH, global_settings.stereo_width); 733 sound_set(SOUND_STEREO_WIDTH, global_settings.stereo_width);
732#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) 734#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
diff --git a/firmware/export/config/android.h b/firmware/export/config/android.h
index ed1a283c7d..69a758d69b 100644
--- a/firmware/export/config/android.h
+++ b/firmware/export/config/android.h
@@ -79,6 +79,9 @@
79/* define this if the target has volume keys which can be used in the lists */ 79/* define this if the target has volume keys which can be used in the lists */
80#define HAVE_VOLUME_IN_LIST 80#define HAVE_VOLUME_IN_LIST
81 81
82/* define this if the host platform can change volume outside of rockbox */
83#define PLATFORM_HAS_VOLUME_CHANGE
84
82#define HAVE_SW_TONE_CONTROLS 85#define HAVE_SW_TONE_CONTROLS
83 86
84/* Define current usage levels. */ 87/* Define current usage levels. */
diff --git a/firmware/export/kernel.h b/firmware/export/kernel.h
index 6aaf11ddb9..66efce33f6 100644
--- a/firmware/export/kernel.h
+++ b/firmware/export/kernel.h
@@ -83,6 +83,7 @@
83#define SYS_IAP_HANDLEPKT MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 2) 83#define SYS_IAP_HANDLEPKT MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 2)
84#define SYS_CALL_INCOMING MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 3) 84#define SYS_CALL_INCOMING MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 3)
85#define SYS_CALL_HUNG_UP MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 4) 85#define SYS_CALL_HUNG_UP MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 4)
86#define SYS_VOLUME_CHANGED MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 5)
86 87
87#define IS_SYSEVENT(ev) ((ev & SYS_EVENT) == SYS_EVENT) 88#define IS_SYSEVENT(ev) ((ev & SYS_EVENT) == SYS_EVENT)
88 89
diff --git a/firmware/export/system.h b/firmware/export/system.h
index 78bddae387..3f626c3688 100644
--- a/firmware/export/system.h
+++ b/firmware/export/system.h
@@ -137,6 +137,10 @@ int get_cpu_boost_counter(void);
137#undef htobe32 137#undef htobe32
138#endif 138#endif
139 139
140#if (CONFIG_PLATFORM & PLATFORM_HOSTED) && defined(PLATFORM_HAS_VOLUME_CHANGE)
141int hosted_get_volume(void);
142#endif
143
140/* Get the byte offset of a type's member */ 144/* Get the byte offset of a type's member */
141#define OFFSETOF(type, membername) ((off_t)&((type *)0)->membername) 145#define OFFSETOF(type, membername) ((off_t)&((type *)0)->membername)
142 146
diff --git a/firmware/target/hosted/android/pcm-android.c b/firmware/target/hosted/android/pcm-android.c
index 4c34e3cd91..24881bd3df 100644
--- a/firmware/target/hosted/android/pcm-android.c
+++ b/firmware/target/hosted/android/pcm-android.c
@@ -179,3 +179,28 @@ void pcm_set_mixer_volume(int volume)
179 179
180 (*env_ptr)->CallVoidMethod(env_ptr, RockboxPCM_instance, set_volume_method, volume); 180 (*env_ptr)->CallVoidMethod(env_ptr, RockboxPCM_instance, set_volume_method, volume);
181} 181}
182
183/* Due to limitations of default_event_handler(), parameters gets swallowed when
184 * being posted with queue_broadcast(), so workaround this by caching the last
185 * value.
186 */
187static int lastPostedVolume = -1;
188int hosted_get_volume(void)
189{
190 return lastPostedVolume;
191}
192
193JNIEXPORT void JNICALL
194Java_org_rockbox_RockboxPCM_postVolumeChangedEvent(JNIEnv *env,
195 jobject this,
196 jint volume)
197{
198 (void) env;
199 (void) this;
200
201 if (volume != lastPostedVolume)
202 {
203 lastPostedVolume = volume;
204 queue_broadcast(SYS_VOLUME_CHANGED, 0);
205 }
206}