[vlc-commits] [Git][videolan/vlc][master] 4 commits: audiotrack: refactor AudioTrack_SetVolume
Jean-Baptiste Kempf
gitlab at videolan.org
Thu Jun 17 12:12:11 UTC 2021
Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC
Commits:
784a74bf by Thomas Guillem at 2021-06-17T09:42:29+00:00
audiotrack: refactor AudioTrack_SetVolume
- - - - -
80d00edc by Thomas Guillem at 2021-06-17T09:42:29+00:00
audiotrack: save original volume
In order to re-apply the gain > 1.f when audiotrack is restarted.
Fixes #25833
- - - - -
7315bc54 by Thomas Guillem at 2021-06-17T09:42:29+00:00
audiotrack: restore volume if audiotrack is restarted
- - - - -
a9c6d334 by Thomas Guillem at 2021-06-17T09:42:29+00:00
audiotrack: use DynamicsProcessing to increase the gain
This fixes a delay of up to 2 seconds when increasing the volume up to
100%.
- - - - -
1 changed file:
- modules/audio_output/audiotrack.c
Changes:
=====================================
modules/audio_output/audiotrack.c
=====================================
@@ -86,6 +86,7 @@ typedef struct
enum at_dev at_dev;
jobject p_audiotrack; /* AudioTrack ref */
+ jobject p_dp;
float volume;
bool mute;
@@ -213,6 +214,7 @@ static struct
jmethodID writeShortV23;
jmethodID writeBufferV21;
jmethodID writeFloat;
+ jmethodID getAudioSessionId;
jmethodID getBufferSizeInFrames;
jmethodID getLatency;
jmethodID getPlaybackHeadPosition;
@@ -284,6 +286,12 @@ static struct
jfieldID framePosition;
jfieldID nanoTime;
} AudioTimestamp;
+ struct {
+ jclass clazz;
+ jmethodID ctor;
+ jmethodID setInputGainAllChannelsTo;
+ jmethodID setEnabled;
+ } DynamicsProcessing;
} jfields;
/* init all jni fields.
@@ -364,6 +372,9 @@ InitJNIFields( audio_output_t *p_aout, JNIEnv* env )
} else
GET_ID( GetMethodID, AudioTrack.write, "write", "([BII)I", true );
+ GET_ID( GetMethodID, AudioTrack.getAudioSessionId,
+ "getAudioSessionId", "()I", true );
+
GET_ID( GetMethodID, AudioTrack.getBufferSizeInFrames,
"getBufferSizeInFrames", "()I", false );
@@ -497,6 +508,18 @@ InitJNIFields( audio_output_t *p_aout, JNIEnv* env )
jfields.AudioManager.has_ERROR_DEAD_OBJECT = field != NULL;
GET_CONST_INT( AudioManager.STREAM_MUSIC, "STREAM_MUSIC", true );
+ GET_CLASS( "android/media/audiofx/DynamicsProcessing", false );
+ if( clazz )
+ {
+ jfields.DynamicsProcessing.clazz = (jclass) (*env)->NewGlobalRef( env, clazz );
+ CHECK_EXCEPTION( "NewGlobalRef", true );
+ GET_ID( GetMethodID, DynamicsProcessing.ctor, "<init>", "(I)V", true );
+ GET_ID( GetMethodID, DynamicsProcessing.setInputGainAllChannelsTo,
+ "setInputGainAllChannelsTo", "(F)V", true );
+ GET_ID( GetMethodID, DynamicsProcessing.setEnabled,
+ "setEnabled", "(Z)I", true );
+ }
+
#undef CHECK_EXCEPTION
#undef GET_CLASS
#undef GET_ID
@@ -1019,6 +1042,24 @@ AudioTrack_New( JNIEnv *env, audio_output_t *p_aout, unsigned int i_rate,
if( !p_sys->p_audiotrack )
return -1;
+ if( jfields.DynamicsProcessing.clazz )
+ {
+ if (session_id == 0 )
+ session_id = JNI_AT_CALL_INT( getAudioSessionId );
+
+ if( session_id != 0 )
+ {
+ jobject dp = JNI_CALL( NewObject, jfields.DynamicsProcessing.clazz,
+ jfields.DynamicsProcessing.ctor, session_id );
+
+ if( !CHECK_EXCEPTION( "DynamicsProcessing", "ctor" ) )
+ {
+ p_sys->p_dp = (*env)->NewGlobalRef( env, dp );
+ (*env)->DeleteLocalRef( env, dp );
+ }
+ }
+ }
+
return 0;
}
@@ -1034,10 +1075,20 @@ AudioTrack_Recreate( JNIEnv *env, audio_output_t *p_aout )
JNI_AT_CALL_VOID( release );
(*env)->DeleteGlobalRef( env, p_sys->p_audiotrack );
p_sys->p_audiotrack = NULL;
- return AudioTrack_New( env, p_aout, p_sys->audiotrack_args.i_rate,
- p_sys->audiotrack_args.i_channel_config,
- p_sys->audiotrack_args.i_format,
- p_sys->audiotrack_args.i_size );
+
+ int ret = AudioTrack_New( env, p_aout, p_sys->audiotrack_args.i_rate,
+ p_sys->audiotrack_args.i_channel_config,
+ p_sys->audiotrack_args.i_format,
+ p_sys->audiotrack_args.i_size );
+
+ if( ret == 0 )
+ {
+ p_aout->volume_set(p_aout, p_sys->volume);
+ if (p_sys->mute)
+ p_aout->mute_set(p_aout, true);
+ }
+
+ return ret;
}
/**
@@ -1562,6 +1613,12 @@ Stop( audio_output_t *p_aout )
p_sys->p_audiotrack = NULL;
}
+ if( p_sys->p_dp )
+ {
+ (*env)->DeleteGlobalRef( env, p_sys->p_dp );
+ p_sys->p_dp = NULL;
+ }
+
/* Release the timestamp object */
if( p_sys->timestamp.p_obj )
{
@@ -2119,6 +2176,22 @@ bailout:
vlc_mutex_unlock( &p_sys->lock );
}
+static void
+AudioTrack_SetVolume( JNIEnv *env, audio_output_t *p_aout, float volume )
+{
+ aout_sys_t *p_sys = p_aout->sys;
+
+ 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" );
+ }
+}
+
static int
VolumeSet( audio_output_t *p_aout, float volume )
{
@@ -2126,28 +2199,45 @@ VolumeSet( audio_output_t *p_aout, float volume )
JNIEnv *env;
float gain = 1.0f;
+ p_sys->volume = volume;
if (volume > 1.f)
{
- p_sys->volume = 1.f;
- gain = volume;
+ gain = volume * volume * volume;
+ volume = 1.f;
}
- else
- p_sys->volume = volume;
if( !p_sys->b_error && p_sys->p_audiotrack != NULL && ( env = GET_ENV() ) )
{
- if( jfields.AudioTrack.setVolume )
- {
- JNI_AT_CALL_INT( setVolume, volume );
- CHECK_AT_EXCEPTION( "setVolume" );
- } else
+ AudioTrack_SetVolume( env, p_aout, volume );
+
+ /* Apply gain > 1.0f via DynamicsProcessing if possible */
+ if( p_sys->p_dp != NULL )
{
- JNI_AT_CALL_INT( setStereoVolume, volume, volume );
- CHECK_AT_EXCEPTION( "setStereoVolume" );
+ if( gain <= 1.0f )
+ {
+ /* DynamicsProcessing is not needed anymore (using AudioTrack
+ * volume) */
+ JNI_CALL_INT( p_sys->p_dp, jfields.DynamicsProcessing.setEnabled, false );
+ CHECK_EXCEPTION( "DynamicsProcessing", "setEnabled" );
+ }
+ else
+ {
+ /* convert linear gain to dB */
+ float dB = 20.0f * log10f(gain);
+
+ JNI_CALL_VOID( p_sys->p_dp, jfields.DynamicsProcessing.setInputGainAllChannelsTo, dB );
+ int ret = JNI_CALL_INT( p_sys->p_dp, jfields.DynamicsProcessing.setEnabled, true );
+
+ if( !CHECK_EXCEPTION( "DynamicsProcessing", "setEnabled" ) && ret == 0 )
+ gain = 1.0; /* reset sw gain */
+ else
+ msg_Warn( p_aout, "failed to set gain via DynamicsProcessing, fallback to sw gain");
+ }
}
}
- aout_VolumeReport(p_aout, volume);
- aout_GainRequest(p_aout, gain * gain * gain);
+
+ aout_VolumeReport(p_aout, p_sys->volume);
+ aout_GainRequest(p_aout, gain);
return 0;
}
@@ -2159,17 +2249,8 @@ MuteSet( audio_output_t *p_aout, bool mute )
p_sys->mute = mute;
if( !p_sys->b_error && p_sys->p_audiotrack != NULL && ( env = GET_ENV() ) )
- {
- 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" );
- }
- }
+ AudioTrack_SetVolume( env, p_aout, mute ? 0.0f : p_sys->volume );
+
aout_MuteReport(p_aout, mute);
return 0;
}
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/1c9890f1455fc4040109bb255d6d42bfdec75031...a9c6d334482db5bc28b9a4b8b499dea9cb1bddc0
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/1c9890f1455fc4040109bb255d6d42bfdec75031...a9c6d334482db5bc28b9a4b8b499dea9cb1bddc0
You're receiving this email because of your account on code.videolan.org.
More information about the vlc-commits
mailing list