forked from len0rd/rockbox
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
This commit is contained in:
parent
606bed035e
commit
e50cc0e3d7
8 changed files with 95 additions and 3 deletions
|
@ -23,8 +23,10 @@ package org.rockbox;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
import android.media.AudioFormat;
|
import android.media.AudioFormat;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.media.AudioTrack;
|
import android.media.AudioTrack;
|
||||||
|
@ -52,8 +54,10 @@ public class RockboxPCM extends AudioTrack
|
||||||
|
|
||||||
private AudioManager audiomanager;
|
private AudioManager audiomanager;
|
||||||
private int maxstreamvolume;
|
private int maxstreamvolume;
|
||||||
|
private int setstreamvolume = -1;
|
||||||
private float minpcmvolume;
|
private float minpcmvolume;
|
||||||
private float pcmrange;
|
private float pcmrange;
|
||||||
|
private RockboxService rbservice;
|
||||||
|
|
||||||
private void LOG(CharSequence text)
|
private void LOG(CharSequence text)
|
||||||
{
|
{
|
||||||
|
@ -72,13 +76,53 @@ public class RockboxPCM extends AudioTrack
|
||||||
l = new PCMListener(buf_len);
|
l = new PCMListener(buf_len);
|
||||||
|
|
||||||
/* find cleaner way to get context? */
|
/* find cleaner way to get context? */
|
||||||
final RockboxService rb = RockboxService.get_instance();
|
rbservice = RockboxService.get_instance();
|
||||||
audiomanager =
|
audiomanager =
|
||||||
(AudioManager) rb.getSystemService(Context.AUDIO_SERVICE);
|
(AudioManager) rbservice.getSystemService(Context.AUDIO_SERVICE);
|
||||||
maxstreamvolume = audiomanager.getStreamMaxVolume(streamtype);
|
maxstreamvolume = audiomanager.getStreamMaxVolume(streamtype);
|
||||||
|
|
||||||
minpcmvolume = getMinVolume();
|
minpcmvolume = getMinVolume();
|
||||||
pcmrange = getMaxVolume() - minpcmvolume;
|
pcmrange = getMaxVolume() - minpcmvolume;
|
||||||
|
|
||||||
|
setupVolumeHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
private native void postVolumeChangedEvent(int volume);
|
||||||
|
private void setupVolumeHandler()
|
||||||
|
{
|
||||||
|
BroadcastReceiver broadcastReceiver = new BroadcastReceiver()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent)
|
||||||
|
{
|
||||||
|
int streamType = intent.getIntExtra(
|
||||||
|
"android.media.EXTRA_VOLUME_STREAM_TYPE", -1);
|
||||||
|
int volume = intent.getIntExtra(
|
||||||
|
"android.media.EXTRA_VOLUME_STREAM_VALUE", -1);
|
||||||
|
|
||||||
|
if (streamType == RockboxPCM.streamtype &&
|
||||||
|
volume != -1 &&
|
||||||
|
volume != setstreamvolume &&
|
||||||
|
rbservice.isRockboxRunning())
|
||||||
|
{
|
||||||
|
int rbvolume = ((maxstreamvolume - volume) * -99) /
|
||||||
|
maxstreamvolume;
|
||||||
|
postVolumeChangedEvent(rbvolume);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* at startup, change the internal rockbox volume to what the global
|
||||||
|
android music stream volume is */
|
||||||
|
int volume = audiomanager.getStreamVolume(streamtype);
|
||||||
|
int rbvolume = ((maxstreamvolume - volume) * -99) / maxstreamvolume;
|
||||||
|
postVolumeChangedEvent(rbvolume);
|
||||||
|
|
||||||
|
/* We're relying on internal API's here,
|
||||||
|
this can break in the future! */
|
||||||
|
rbservice.registerReceiver(
|
||||||
|
broadcastReceiver,
|
||||||
|
new IntentFilter("android.media.VOLUME_CHANGED_ACTION"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private int bytes2frames(int bytes)
|
private int bytes2frames(int bytes)
|
||||||
|
@ -164,9 +208,11 @@ public class RockboxPCM extends AudioTrack
|
||||||
}
|
}
|
||||||
|
|
||||||
int oldstreamvolume = audiomanager.getStreamVolume(streamtype);
|
int oldstreamvolume = audiomanager.getStreamVolume(streamtype);
|
||||||
if (streamvolume != oldstreamvolume)
|
if (streamvolume != oldstreamvolume) {
|
||||||
|
setstreamvolume = streamvolume;
|
||||||
audiomanager.setStreamVolume(streamtype, streamvolume, 0);
|
audiomanager.setStreamVolume(streamtype, streamvolume, 0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public native void pcmSamplesToByteArray(byte[] dest);
|
public native void pcmSamplesToByteArray(byte[] dest);
|
||||||
|
|
||||||
|
|
|
@ -636,6 +636,15 @@ long default_event_handler_ex(long event, void (*callback)(void *), void *parame
|
||||||
resume = false;
|
resume = false;
|
||||||
return SYS_CALL_HUNG_UP;
|
return SYS_CALL_HUNG_UP;
|
||||||
#endif
|
#endif
|
||||||
|
#if (CONFIG_PLATFORM & PLATFORM_HOSTED) && defined(PLATFORM_HAS_VOLUME_CHANGE)
|
||||||
|
case SYS_VOLUME_CHANGED:
|
||||||
|
{
|
||||||
|
int volume = hosted_get_volume();
|
||||||
|
if (global_settings.volume != volume)
|
||||||
|
global_settings.volume = volume;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#ifdef HAVE_MULTIMEDIA_KEYS
|
#ifdef HAVE_MULTIMEDIA_KEYS
|
||||||
/* multimedia keys on keyboards, headsets */
|
/* multimedia keys on keyboards, headsets */
|
||||||
case BUTTON_MULTIMEDIA_PLAYPAUSE:
|
case BUTTON_MULTIMEDIA_PLAYPAUSE:
|
||||||
|
|
|
@ -1834,7 +1834,9 @@ static void audio_play_start(size_t offset)
|
||||||
ci.seek_time = 0;
|
ci.seek_time = 0;
|
||||||
wps_offset = 0;
|
wps_offset = 0;
|
||||||
|
|
||||||
|
#ifndef PLAFORM_HAS_VOLUME_CHANGE
|
||||||
sound_set_volume(global_settings.volume);
|
sound_set_volume(global_settings.volume);
|
||||||
|
#endif
|
||||||
track_widx = track_ridx = 0;
|
track_widx = track_ridx = 0;
|
||||||
buf_set_base_handle(-1);
|
buf_set_base_handle(-1);
|
||||||
|
|
||||||
|
|
|
@ -726,7 +726,9 @@ void sound_settings_apply(void)
|
||||||
sound_set(SOUND_TREBLE, global_settings.treble);
|
sound_set(SOUND_TREBLE, global_settings.treble);
|
||||||
#endif
|
#endif
|
||||||
sound_set(SOUND_BALANCE, global_settings.balance);
|
sound_set(SOUND_BALANCE, global_settings.balance);
|
||||||
|
#ifndef PLATFORM_HAS_VOLUME_CHANGE
|
||||||
sound_set(SOUND_VOLUME, global_settings.volume);
|
sound_set(SOUND_VOLUME, global_settings.volume);
|
||||||
|
#endif
|
||||||
sound_set(SOUND_CHANNELS, global_settings.channel_config);
|
sound_set(SOUND_CHANNELS, global_settings.channel_config);
|
||||||
sound_set(SOUND_STEREO_WIDTH, global_settings.stereo_width);
|
sound_set(SOUND_STEREO_WIDTH, global_settings.stereo_width);
|
||||||
#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
|
#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
|
||||||
|
|
|
@ -79,6 +79,9 @@
|
||||||
/* define this if the target has volume keys which can be used in the lists */
|
/* define this if the target has volume keys which can be used in the lists */
|
||||||
#define HAVE_VOLUME_IN_LIST
|
#define HAVE_VOLUME_IN_LIST
|
||||||
|
|
||||||
|
/* define this if the host platform can change volume outside of rockbox */
|
||||||
|
#define PLATFORM_HAS_VOLUME_CHANGE
|
||||||
|
|
||||||
#define HAVE_SW_TONE_CONTROLS
|
#define HAVE_SW_TONE_CONTROLS
|
||||||
|
|
||||||
/* Define current usage levels. */
|
/* Define current usage levels. */
|
||||||
|
|
|
@ -83,6 +83,7 @@
|
||||||
#define SYS_IAP_HANDLEPKT MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 2)
|
#define SYS_IAP_HANDLEPKT MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 2)
|
||||||
#define SYS_CALL_INCOMING MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 3)
|
#define SYS_CALL_INCOMING MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 3)
|
||||||
#define SYS_CALL_HUNG_UP MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 4)
|
#define SYS_CALL_HUNG_UP MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 4)
|
||||||
|
#define SYS_VOLUME_CHANGED MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 5)
|
||||||
|
|
||||||
#define IS_SYSEVENT(ev) ((ev & SYS_EVENT) == SYS_EVENT)
|
#define IS_SYSEVENT(ev) ((ev & SYS_EVENT) == SYS_EVENT)
|
||||||
|
|
||||||
|
|
|
@ -137,6 +137,10 @@ int get_cpu_boost_counter(void);
|
||||||
#undef htobe32
|
#undef htobe32
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if (CONFIG_PLATFORM & PLATFORM_HOSTED) && defined(PLATFORM_HAS_VOLUME_CHANGE)
|
||||||
|
int hosted_get_volume(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Get the byte offset of a type's member */
|
/* Get the byte offset of a type's member */
|
||||||
#define OFFSETOF(type, membername) ((off_t)&((type *)0)->membername)
|
#define OFFSETOF(type, membername) ((off_t)&((type *)0)->membername)
|
||||||
|
|
||||||
|
|
|
@ -179,3 +179,28 @@ void pcm_set_mixer_volume(int volume)
|
||||||
|
|
||||||
(*env_ptr)->CallVoidMethod(env_ptr, RockboxPCM_instance, set_volume_method, volume);
|
(*env_ptr)->CallVoidMethod(env_ptr, RockboxPCM_instance, set_volume_method, volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Due to limitations of default_event_handler(), parameters gets swallowed when
|
||||||
|
* being posted with queue_broadcast(), so workaround this by caching the last
|
||||||
|
* value.
|
||||||
|
*/
|
||||||
|
static int lastPostedVolume = -1;
|
||||||
|
int hosted_get_volume(void)
|
||||||
|
{
|
||||||
|
return lastPostedVolume;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL
|
||||||
|
Java_org_rockbox_RockboxPCM_postVolumeChangedEvent(JNIEnv *env,
|
||||||
|
jobject this,
|
||||||
|
jint volume)
|
||||||
|
{
|
||||||
|
(void) env;
|
||||||
|
(void) this;
|
||||||
|
|
||||||
|
if (volume != lastPostedVolume)
|
||||||
|
{
|
||||||
|
lastPostedVolume = volume;
|
||||||
|
queue_broadcast(SYS_VOLUME_CHANGED, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue