[vlc-commits] [Git][videolan/vlc][3.0.x] 4 commits: audiotrack: refactor AudioTrack_SetVolume

Jean-Baptiste Kempf gitlab at videolan.org
Sat Jun 19 07:49:26 UTC 2021



Jean-Baptiste Kempf pushed to branch 3.0.x at VideoLAN / VLC


Commits:
fa5e39db by Thomas Guillem at 2021-06-19T07:22:24+00:00
audiotrack: refactor AudioTrack_SetVolume

(cherry picked from commit 784a74bfb7f62790e356c0231c2fcab1d9cd7825)
Signed-off-by: Thomas Guillem <thomas at gllm.fr>

- - - - -
b4a690a4 by Thomas Guillem at 2021-06-19T07:22:24+00:00
audiotrack: save original volume

In order to re-apply the gain > 1.f when audiotrack is restarted.
Fixes #25833

(cherry picked from commit 80d00edc0f8f528842ec04a962e8e84bcd4238d6)
Signed-off-by: Thomas Guillem <thomas at gllm.fr>

- - - - -
a2d5b24e by Thomas Guillem at 2021-06-19T07:22:24+00:00
audiotrack: restore volume if audiotrack is restarted

(cherry picked from commit 7315bc54f75f1825152eb03e43892cd9c70440b8)
Signed-off-by: Thomas Guillem <thomas at gllm.fr>

- - - - -
7ced1002 by Thomas Guillem at 2021-06-19T07:22:24+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%.

(cherry picked from commit a9c6d334482db5bc28b9a4b8b499dea9cb1bddc0)
Signed-off-by: Thomas Guillem <thomas at gllm.fr>

- - - - -


1 changed file:

- modules/audio_output/audiotrack.c


Changes:

=====================================
modules/audio_output/audiotrack.c
=====================================
@@ -83,6 +83,7 @@ struct aout_sys_t {
     enum at_dev at_dev;
 
     jobject p_audiotrack; /* AudioTrack ref */
+    jobject p_dp;
     float volume;
     bool mute;
 
@@ -209,6 +210,7 @@ static struct
         jmethodID writeShortV23;
         jmethodID writeBufferV21;
         jmethodID writeFloat;
+        jmethodID getAudioSessionId;
         jmethodID getPlaybackHeadPosition;
         jmethodID getTimestamp;
         jmethodID getMinBufferSize;
@@ -268,6 +270,12 @@ static struct
         jfieldID framePosition;
         jfieldID nanoTime;
     } AudioTimestamp;
+    struct {
+        jclass clazz;
+        jmethodID ctor;
+        jmethodID setInputGainAllChannelsTo;
+        jmethodID setEnabled;
+    } DynamicsProcessing;
 } jfields;
 
 /* init all jni fields.
@@ -344,6 +352,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.getTimestamp,
             "getTimestamp", "(Landroid/media/AudioTimestamp;)Z", false );
     GET_ID( GetMethodID, AudioTrack.getPlaybackHeadPosition,
@@ -452,6 +463,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
@@ -846,6 +869,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_AT_EXCEPTION( "DynamicsProcessing.ctor" ) )
+            {
+                p_sys->p_dp = (*env)->NewGlobalRef( env, dp );
+                (*env)->DeleteLocalRef( env, dp );
+            }
+        }
+    }
+
     return 0;
 }
 
@@ -861,10 +902,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;
 }
 
 /**
@@ -1387,6 +1438,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 )
     {
@@ -1965,6 +2022,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 )
 {
@@ -1972,28 +2045,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_AT_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_AT_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;
 }
 
@@ -2005,17 +2095,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/5e70837d8d766db6ca5052a2d4f503ad37243d9c...7ced10027683995683a38b5dfe21d311dfccd7aa

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/5e70837d8d766db6ca5052a2d4f503ad37243d9c...7ced10027683995683a38b5dfe21d311dfccd7aa
You're receiving this email because of your account on code.videolan.org.




More information about the vlc-commits mailing list