Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #2098 from mcrosson/android-feature-auto-adjust-vo…

…lume

[droid] Native volume control
  • Loading branch information...
commit c45b7fe384494db51f300a3280b8b01de6f163a1 2 parents 16a5abd + 3967e18
@jmarshallnz jmarshallnz authored
View
12 xbmc/Application.cpp
@@ -335,6 +335,10 @@
#include "input/SDLJoystick.h"
#endif
+#if defined(TARGET_ANDROID)
+#include "android/activity/XBMCApp.h"
+#endif
+
using namespace std;
using namespace ADDON;
using namespace XFILE;
@@ -2859,15 +2863,19 @@ bool CApplication::OnAction(const CAction &action)
if (g_settings.m_bMute)
UnMute();
float volume = g_settings.m_fVolumeLevel;
+// Android has steps based on the max available volume level
+#if defined(TARGET_ANDROID)
+ float step = (VOLUME_MAXIMUM - VOLUME_MINIMUM) / CXBMCApp::GetMaxSystemVolume();
+#else
float step = (VOLUME_MAXIMUM - VOLUME_MINIMUM) / VOLUME_CONTROL_STEPS;
+
if (action.GetRepeat())
step *= action.GetRepeat() * 50; // 50 fps
-
+#endif
if (action.GetID() == ACTION_VOLUME_UP)
volume += (float)fabs(action.GetAmount()) * action.GetAmount() * step;
else
volume -= (float)fabs(action.GetAmount()) * action.GetAmount() * step;
-
SetVolume(volume, false);
}
// show visual feedback of volume change...
View
69 xbmc/android/activity/XBMCApp.cpp
@@ -127,7 +127,6 @@ ActivityResult CXBMCApp::onActivate()
default:
break;
}
-
return ActivityOK;
}
@@ -975,3 +974,71 @@ bool CXBMCApp::GetStorageUsage(const std::string &path, std::string &usage)
usage = fmt.str();
return true;
}
+
+// Used in Application.cpp to figure out volume steps
+int CXBMCApp::GetMaxSystemVolume()
+{
+ static int maxVolume = -1;
+ if (maxVolume == -1)
+ {
+ JNIEnv *env = NULL;
+ AttachCurrentThread(&env);
+ maxVolume = GetMaxSystemVolume(env);
+ DetachCurrentThread();
+ }
+ return maxVolume;
+}
+
+int CXBMCApp::GetMaxSystemVolume(JNIEnv *env)
+{
+ jobject oActivity = m_activity->clazz;
+ jclass cActivity = env->GetObjectClass(oActivity);
+
+ // Get Audio manager
+ // (AudioManager)getSystemService(Context.AUDIO_SERVICE)
+ jmethodID mgetSystemService = env->GetMethodID(cActivity, "getSystemService","(Ljava/lang/String;)Ljava/lang/Object;");
+ jstring sAudioService = env->NewStringUTF("audio");
+ jobject oAudioManager = env->CallObjectMethod(oActivity, mgetSystemService, sAudioService);
+ env->DeleteLocalRef(sAudioService);
+ env->DeleteLocalRef(cActivity);
+
+ // Get max volume
+ // int max_volume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
+ jclass cAudioManager = env->GetObjectClass(oAudioManager);
+ jmethodID mgetStreamMaxVolume = env->GetMethodID(cAudioManager, "getStreamMaxVolume", "(I)I");
+ jfieldID fstreamMusic = env->GetStaticFieldID(cAudioManager, "STREAM_MUSIC", "I");
+ jint stream_music = env->GetStaticIntField(cAudioManager, fstreamMusic);
+ int maxVolume = (int)env->CallObjectMethod(oAudioManager, mgetStreamMaxVolume, stream_music); // AudioManager.STREAM_MUSIC
+
+ env->DeleteLocalRef(oAudioManager);
+ env->DeleteLocalRef(cAudioManager);
+
+ return maxVolume;
+}
+
+void CXBMCApp::SetSystemVolume(JNIEnv *env, float percent)
+{
+ CLog::Log(LOGDEBUG, "CXBMCApp::SetSystemVolume: %f", percent);
+
+ jobject oActivity = m_activity->clazz;
+ jclass cActivity = env->GetObjectClass(oActivity);
+
+ // Get Audio manager
+ // (AudioManager)getSystemService(Context.AUDIO_SERVICE)
+ jmethodID mgetSystemService = env->GetMethodID(cActivity, "getSystemService","(Ljava/lang/String;)Ljava/lang/Object;");
+ jstring sAudioService = env->NewStringUTF("audio");
+ jobject oAudioManager = env->CallObjectMethod(oActivity, mgetSystemService, sAudioService);
+ jclass cAudioManager = env->GetObjectClass(oAudioManager);
+ env->DeleteLocalRef(sAudioService);
+ env->DeleteLocalRef(cActivity);
+
+ // Set volume
+ // mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, max_volume, 0);
+ jfieldID fstreamMusic = env->GetStaticFieldID(cAudioManager, "STREAM_MUSIC", "I");
+ jint stream_music = env->GetStaticIntField(cAudioManager, fstreamMusic);
+ jmethodID msetStreamVolume = env->GetMethodID(cAudioManager, "setStreamVolume", "(III)V");
+ env->CallObjectMethod(oAudioManager, msetStreamVolume, stream_music, int(GetMaxSystemVolume(env)*percent), 0);
+ env->DeleteLocalRef(oAudioManager);
+ env->DeleteLocalRef(cAudioManager);
+}
+
View
6 xbmc/android/activity/XBMCApp.h
@@ -87,6 +87,7 @@ class CXBMCApp : public IActivityHandler
static bool ListApplications(std::vector <androidPackage> *applications);
static bool GetIconSize(const std::string &packageName, int *width, int *height);
static bool GetIcon(const std::string &packageName, void* buffer, unsigned int bufSize);
+
/*!
* \brief If external storage is available, it returns the path for the external storage (for the specified type)
* \param path will contain the path of the external storage (for the specified type)
@@ -95,6 +96,7 @@ class CXBMCApp : public IActivityHandler
*/
static bool GetExternalStorage(std::string &path, const std::string &type = "");
static bool GetStorageUsage(const std::string &path, std::string &usage);
+ static int GetMaxSystemVolume();
static int GetDPI();
protected:
@@ -106,6 +108,9 @@ class CXBMCApp : public IActivityHandler
static int AttachCurrentThread(JNIEnv** p_env, void* thr_args = NULL);
static int DetachCurrentThread();
+ static int GetMaxSystemVolume(JNIEnv *env);
+ static void SetSystemVolume(JNIEnv *env, float percent);
+
private:
static bool HasLaunchIntent(const std::string &package);
bool getWakeLock(JNIEnv *env);
@@ -116,7 +121,6 @@ class CXBMCApp : public IActivityHandler
static ANativeActivity *m_activity;
jobject m_wakeLock;
-
typedef enum {
// XBMC_Initialize hasn't been executed yet
Uninitialized,
View
10 xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp
@@ -228,9 +228,11 @@ bool CAESinkAUDIOTRACK::HasVolume()
return true;
}
-void CAESinkAUDIOTRACK::SetVolume(float volume)
+void CAESinkAUDIOTRACK::SetVolume(float scale)
{
- m_volume = volume;
+ // Android uses fixed steps, reverse scale back to percent
+ float gain = CAEUtil::ScaleToGain(scale);
+ m_volume = CAEUtil::GainToPercent(gain);
m_volume_changed = true;
}
@@ -273,7 +275,6 @@ void CAESinkAUDIOTRACK::Process()
jmethodID jmRelease = jenv->GetMethodID(jcAudioTrack, "release", "()V");
jmethodID jmWrite = jenv->GetMethodID(jcAudioTrack, "write", "([BII)I");
jmethodID jmPlayState = jenv->GetMethodID(jcAudioTrack, "getPlayState", "()I");
- jmethodID jmSetStereoVolume = jenv->GetMethodID(jcAudioTrack, "setStereoVolume", "(FF)I");
jmethodID jmPlayHeadPosition = jenv->GetMethodID(jcAudioTrack, "getPlaybackHeadPosition", "()I");
jmethodID jmGetMinBufferSize = jenv->GetStaticMethodID(jcAudioTrack, "getMinBufferSize", "(III)I");
@@ -322,8 +323,7 @@ void CAESinkAUDIOTRACK::Process()
{
// check of volume changes and make them,
// do it here to keep jni calls local to this thread.
- jfloat jvolume = m_volume;
- jenv->CallIntMethod(joAudioTrack, jmSetStereoVolume, jvolume, jvolume);
+ CXBMCApp::SetSystemVolume(jenv, m_volume);
m_volume_changed = false;
}
if (m_draining)
View
2  xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.h
@@ -42,7 +42,7 @@ class CAESinkAUDIOTRACK : public CThread, public IAESink
virtual unsigned int AddPackets (uint8_t *data, unsigned int frames, bool hasAudio);
virtual void Drain ();
virtual bool HasVolume ();
- virtual void SetVolume (float volume);
+ virtual void SetVolume (float scale);
static void EnumerateDevicesEx(AEDeviceInfoList &list);
private:
View
24 xbmc/cores/AudioEngine/Utils/AEUtil.h
@@ -71,6 +71,19 @@ class CAEUtil
return (value - 1)*db_range;
}
+ /*! \brief convert a dB gain to volume percentage (as a proportion)
+ We assume a dB range of 60dB, i.e. assume that 0% volume corresponds
+ to a reduction of 60dB.
+ \param the corresponding gain in dB from -60dB .. 0dB.
+ \return value the volume from 0..1
+ \sa ScaleToGain
+ */
+ static inline const float GainToPercent(const float gain)
+ {
+ static const float db_range = 60.0f;
+ return 1+(gain/db_range);
+ }
+
/*! \brief convert a dB gain to a scale factor for audio manipulation
Inverts gain = 20 log_10(scale)
\param dB the gain in decibels.
@@ -82,6 +95,17 @@ class CAEUtil
return pow(10.0f, dB/20);
}
+ /*! \brief convert a scale factor to dB gain for audio manipulation
+ Inverts GainToScale result
+ \param the scale factor (equivalent to a voltage multiplier).
+ \return dB the gain in decibels.
+ \sa GainToScale
+ */
+ static inline const float ScaleToGain(const float scale)
+ {
+ return 20*log10(scale);
+ }
+
#ifdef __SSE__
static void SSEMulArray (float *data, const float mul, uint32_t count);
static void SSEMulAddArray (float *data, float *add, const float mul, uint32_t count);
Please sign in to comment.
Something went wrong with that request. Please try again.