[vlc-devel] [PATCH] Audiotrack: Hardware volume management
Geoffrey Métais
geoffrey.metais at gmail.com
Mon Nov 26 15:36:08 CET 2018
This allows proper ducking during notifications on Android
---
modules/audio_output/audiotrack.c | 99 +++++++++++++++++++++++++++++--
1 file changed, 94 insertions(+), 5 deletions(-)
diff --git a/modules/audio_output/audiotrack.c b/modules/audio_output/audiotrack.c
index 238826bb95..04a7305887 100644
--- a/modules/audio_output/audiotrack.c
+++ b/modules/audio_output/audiotrack.c
@@ -80,13 +80,12 @@ static const struct {
};
struct aout_sys_t {
- /* sw gain */
- float soft_gain;
- bool soft_mute;
enum at_dev at_dev;
jobject p_audiotrack; /* AudioTrack ref */
+ float volume;
+ bool mute;
audio_sample_format_t fmt; /* fmt setup by Start */
@@ -218,6 +217,9 @@ static struct
jmethodID getTimestamp;
jmethodID getMinBufferSize;
jmethodID getNativeOutputSampleRate;
+ jmethodID getMaxVolume;
+ jmethodID setVolume;
+ jmethodID setStereoVolume;
jint STATE_INITIALIZED;
jint MODE_STREAM;
jint ERROR;
@@ -358,6 +360,13 @@ InitJNIFields( audio_output_t *p_aout, JNIEnv* env )
GET_ID( GetStaticMethodID, AudioTrack.getNativeOutputSampleRate,
"getNativeOutputSampleRate", "(I)I", true );
#endif
+ GET_ID( GetStaticMethodID, AudioTrack.getMaxVolume,
+ "getMaxVolume", "()F", true );
+ GET_ID( GetMethodID, AudioTrack.setVolume,
+ "setVolume", "(F)I", true );
+ if( !jfields.AudioTrack.setVolume )
+ GET_ID( GetMethodID, AudioTrack.setStereoVolume,
+ "setStereoVolume", "(FF)I", true );
GET_CONST_INT( AudioTrack.STATE_INITIALIZED, "STATE_INITIALIZED", true );
GET_CONST_INT( AudioTrack.MODE_STREAM, "MODE_STREAM", true );
GET_CONST_INT( AudioTrack.ERROR, "ERROR", true );
@@ -495,6 +504,7 @@ check_exception( JNIEnv *env, audio_output_t *p_aout,
#define JNI_AT_CALL_BOOL( method, ... ) JNI_CALL_BOOL( p_sys->p_audiotrack, jfields.AudioTrack.method, ##__VA_ARGS__ )
#define JNI_AT_CALL_VOID( method, ... ) JNI_CALL_VOID( p_sys->p_audiotrack, jfields.AudioTrack.method, ##__VA_ARGS__ )
#define JNI_AT_CALL_STATIC_INT( method, ... ) JNI_CALL( CallStaticIntMethod, jfields.AudioTrack.clazz, jfields.AudioTrack.method, ##__VA_ARGS__ )
+#define JNI_AT_CALL_STATIC_FLOAT( method, ... ) JNI_CALL( CallStaticFloatMethod, jfields.AudioTrack.clazz, jfields.AudioTrack.method, ##__VA_ARGS__ )
#define JNI_AUDIOTIMESTAMP_GET_LONG( field ) JNI_CALL( GetLongField, p_sys->timestamp.p_obj, jfields.AudioTimestamp.field )
@@ -1332,8 +1342,11 @@ Start( audio_output_t *p_aout, audio_sample_format_t *restrict p_fmt )
CHECK_AT_EXCEPTION( "play" );
*p_fmt = p_sys->fmt;
- aout_SoftVolumeStart( p_aout );
+ if (p_sys->mute)
+ p_aout->mute_set(p_aout, true);
+ else
+ p_aout->volume_set(p_aout, p_sys->volume)
aout_FormatPrint( p_aout, "VLC will output:", &p_sys->fmt );
return VLC_SUCCESS;
@@ -1898,6 +1911,78 @@ bailout:
vlc_mutex_unlock( &p_sys->lock );
}
+static int
+VolumeSet( audio_output_t *p_aout, float volume )
+{
+ aout_sys_t *p_sys = p_aout->sys;
+ JNIEnv *env;
+ float gain = 1.0f;
+ if (volume > 1.f)
+ {
+ p_sys->volume = 1.f;
+ gain = volume;
+ }
+ else
+ p_sys->volume = volume;
+
+ if( p_sys->b_error || !( env = GET_ENV() ) )
+ return VLC_EGENERIC;
+ if (p_sys->p_audiotrack != NULL)
+ {
+ if( jfields.AudioTrack.setVolume )
+ {
+ JNI_AT_CALL_INT( setVolume, volume );
+ CHECK_AT_EXCEPTION( "setVolume" );
+ } else
+ {
+ JNI_AT_CALL_INT( setStereoVolume, volume, volume );
+ CHECK_AT_EXCEPTION( "setStereoVolume" );
+ }
+ }
+ aout_VolumeReport(p_aout, volume);
+ aout_GainRequest(aout, gain * gain * gain);
+ return 0;
+}
+
+static int
+MuteSet( audio_output_t *p_aout, bool mute )
+{
+ aout_sys_t *p_sys = p_aout->sys;
+ JNIEnv *env;
+ p_sys->mute = mute;
+
+ if( p_sys->b_error || !( env = GET_ENV() ) )
+ return VLC_EGENERIC;
+ if (p_sys->p_audiotrack != NULL)
+ {
+ if( jfields.AudioTrack.setVolume )
+ {
+ JNI_AT_CALL_INT( setVolume, mute ? 0.0f : p_sys->volume );
+ CHECK_AT_EXCEPTION( "setVolume" );
+ } else
+ {
+ JNI_AT_CALL_INT( setStereoVolume, mute ? 0.0f : p_sys->volume, mute ? 0.0f : p_sys->volume );
+ CHECK_AT_EXCEPTION( "setStereoVolume" );
+ }
+ }
+ aout_MuteReport(aout, mute);
+ return 0;
+}
+
+static float
+getMaxVolume( audio_output_t *p_aout)
+{
+ aout_sys_t *p_sys = p_aout->sys;
+ JNIEnv *env;
+
+ if( p_sys->b_error || !( env = GET_ENV() ) )
+ return VLC_EGENERIC;
+
+ float ret = JNI_AT_CALL_STATIC_FLOAT( getMaxVolume );
+ CHECK_AT_EXCEPTION( "getMaxVolume" );
+ return ret;
+}
+
static int DeviceSelect(audio_output_t *p_aout, const char *p_id)
{
aout_sys_t *p_sys = p_aout->sys;
@@ -1981,7 +2066,11 @@ Open( vlc_object_t *obj )
for( unsigned int i = 0; at_devs[i].id; ++i )
aout_HotplugReport(p_aout, at_devs[i].id, at_devs[i].name);
- aout_SoftVolumeInit( p_aout );
+ msg_Dbg( p_aout, "max_volume: %f", getMaxVolume(p_aout));
+ p_aout->volume_set = VolumeSet;
+ p_aout->mute_set = MuteSet;
+ p_sys->volume = 1.0f;
+ p_sys->mute = false;
return VLC_SUCCESS;
}
--
2.17.1
More information about the vlc-devel
mailing list