aout: move replay gain handling to dec and mixer
authorRémi Denis-Courmont <remi@remlab.net>
Wed, 10 Aug 2011 15:02:24 +0000 (18:02 +0300)
committerRémi Denis-Courmont <remi@remlab.net>
Wed, 10 Aug 2011 14:41:16 +0000 (17:41 +0300)
This had no relations with the audio input anymore. In particular,
there is no need to reinitialize this when the input is restarted.

src/audio_output/aout_internal.h
src/audio_output/dec.c
src/audio_output/input.c
src/audio_output/mixer.c

index 310a6f1..188b434 100644 (file)
@@ -51,7 +51,6 @@ block_t *aout_FilterBufferNew( filter_t *, int );
 /** an input stream for the audio output */
 struct aout_input_t
 {
-    vlc_atomic_t        multiplier; /**< Replay gain multiplier */
     unsigned            samplerate; /**< Input sample rate */
 
     /* pre-filters */
@@ -67,9 +66,6 @@ struct aout_input_t
     mtime_t                 i_resamp_start_date;
     int                     i_resamp_start_drift;
 
-    /* Mixer information */
-    audio_replay_gain_t     replay_gain;
-
     /* If b_error == 1, there is no input pipeline. */
     bool              b_error;
 
@@ -100,7 +96,13 @@ typedef struct
         vlc_mutex_t lock;
         float multiplier; /**< Software volume amplification multiplier */
         struct audio_mixer *mixer; /**< Software volume plugin */
-    } volume; /**< Volume and gain management (FIXME: input manager?) */
+    } volume;
+
+    struct
+    {
+        vlc_atomic_t multiplier;
+        audio_replay_gain_t data;
+    } gain;
 
     audio_sample_format_t mixer_format;
     audio_sample_format_t input_format;
@@ -134,7 +136,6 @@ int aout_InputNew(audio_output_t *, const audio_sample_format_t *,
 int aout_InputDelete( audio_output_t * p_aout, aout_input_t * p_input );
 block_t *aout_InputPlay( audio_output_t *p_aout, aout_input_t *p_input,
                          block_t *p_buffer, int i_input_rate, date_t * );
-float aout_InputGetMultiplier(const aout_input_t *);
 
 /* From filters.c : */
 int aout_FiltersCreatePipeline( vlc_object_t *, filter_t **, int *,
@@ -149,6 +150,20 @@ struct audio_mixer *aout_MixerNew(vlc_object_t *, vlc_fourcc_t);
 #define aout_MixerNew(o, f) aout_MixerNew(VLC_OBJECT(o), f)
 void aout_MixerDelete(struct audio_mixer *);
 void aout_MixerRun(struct audio_mixer *, block_t *, float);
+float aout_ReplayGainSelect(vlc_object_t *, const char *,
+                            const audio_replay_gain_t *);
+#define aout_ReplayGainSelect(o, s, g) \
+        aout_ReplayGainSelect(VLC_OBJECT(o), s, g)
+
+static inline void aout_ReplayGainInit(audio_replay_gain_t *restrict d,
+                                       const audio_replay_gain_t *restrict s)
+{
+    if (s != NULL)
+        *d = *s;
+    else
+        memset (d, 0, sizeof (*d));
+}
+
 
 /* From output.c : */
 int aout_OutputNew( audio_output_t * p_aout,
index c2077a0..92e0d1c 100644 (file)
@@ -38,6 +38,9 @@
 #include "aout_internal.h"
 #include "libvlc.h"
 
+static int ReplayGainCallback (vlc_object_t *, char const *,
+                               vlc_value_t, vlc_value_t, void *);
+
 /**
  * Creates an audio output
  */
@@ -83,30 +86,34 @@ int aout_DecNew( audio_output_t *p_aout,
 
     p_input->b_error = true;
 
-    if( p_replay_gain )
-        p_input->replay_gain = *p_replay_gain;
-
     /* We can only be called by the decoder, so no need to lock
      * p_input->lock. */
     aout_owner_t *owner = aout_owner(p_aout);
     aout_lock( p_aout );
-    assert (owner->input == NULL);
 
+    /* Create the audio output stream */
     var_Destroy( p_aout, "audio-device" );
     var_Destroy( p_aout, "audio-channels" );
 
-    /* Recreate the output using the new format. */
     owner->input_format = *p_format;
     vlc_atomic_set (&owner->restart, 0);
     if( aout_OutputNew( p_aout, p_format ) < 0 )
         goto error;
 
+    /* Allocate a software mixer */
     assert (owner->volume.mixer == NULL);
     owner->volume.mixer = aout_MixerNew (p_aout, owner->mixer_format.i_format);
 
+    aout_ReplayGainInit (&owner->gain.data, p_replay_gain);
+    var_AddCallback (p_aout, "audio-replay-gain-mode",
+                     ReplayGainCallback, owner);
+    var_TriggerCallback (p_aout, "audio-replay-gain-mode");
+
+    /* Create the audio filtering "input" pipeline */
     date_Init (&owner->sync.date, owner->mixer_format.i_rate, 1);
     date_Set (&owner->sync.date, VLC_TS_INVALID);
 
+    assert (owner->input == NULL);
     owner->input = p_input;
     aout_InputNew( p_aout, p_format, &owner->mixer_format, p_input,
                    p_request_vout );
@@ -133,9 +140,13 @@ void aout_DecDelete( audio_output_t * p_aout )
     aout_InputDelete (p_aout, input);
     owner->input = NULL;
 
-    aout_OutputDelete( p_aout );
     mixer = owner->volume.mixer;
     owner->volume.mixer = NULL;
+
+    var_DelCallback (p_aout, "audio-replay-gain-mode",
+                     ReplayGainCallback, owner);
+
+    aout_OutputDelete( p_aout );
     var_Destroy( p_aout, "audio-device" );
     var_Destroy( p_aout, "audio-channels" );
 
@@ -273,9 +284,12 @@ int aout_DecPlay (audio_output_t *p_aout, block_t *p_buffer, int i_input_rate)
         date_Increment (&owner->sync.date, p_buffer->i_nb_samples);
 
         /* Mixer */
-        float amp = owner->volume.multiplier
-                  * aout_InputGetMultiplier (p_input);
-        aout_MixerRun (owner->volume.mixer, p_buffer, amp);
+        if (owner->volume.mixer != NULL)
+        {
+            float amp = owner->volume.multiplier
+                      * vlc_atomic_getf (&owner->gain.multiplier);
+            aout_MixerRun (owner->volume.mixer, p_buffer, amp);
+        }
 
         /* Output */
         aout_OutputPlay( p_aout, p_buffer );
@@ -374,3 +388,14 @@ void aout_TimeReport (audio_output_t *aout, mtime_t ideal)
             date_Move (&owner->sync.date, delta);
     }
 }
+
+static int ReplayGainCallback (vlc_object_t *obj, char const *var,
+                               vlc_value_t oldval, vlc_value_t val, void *data)
+{
+    aout_owner_t *owner = data;
+    float multiplier = aout_ReplayGainSelect (obj, val.psz_string,
+                                              &owner->gain.data);
+    vlc_atomic_setf (&owner->gain.multiplier, multiplier);
+    VLC_UNUSED(var); VLC_UNUSED(oldval);
+    return VLC_SUCCESS;
+}
index 7530358..5494701 100644 (file)
@@ -35,7 +35,6 @@
 
 #include <stdio.h>
 #include <string.h>
-#include <math.h>
 #include <assert.h>
 
 #include <vlc_input.h>
@@ -43,7 +42,6 @@
 #include <vlc_modules.h>
 #include <vlc_aout.h>
 #include <vlc_filter.h>
-#include <vlc_atomic.h>
 #include <libvlc.h>
 
 #include "aout_internal.h"
@@ -56,10 +54,6 @@ static int VisualizationCallback( vlc_object_t *, char const *,
                                   vlc_value_t, vlc_value_t, void * );
 static int EqualizerCallback( vlc_object_t *, char const *,
                               vlc_value_t, vlc_value_t, void * );
-static int ReplayGainCallback( vlc_object_t *, char const *,
-                               vlc_value_t, vlc_value_t, void * );
-static float ReplayGainSelect(vlc_object_t *, const char *,
-                              const audio_replay_gain_t *);
 
 static vout_thread_t *RequestVout( void *,
                                    vout_thread_t *, video_format_t *, bool );
@@ -103,13 +97,6 @@ int aout_InputNew( audio_output_t * p_aout,
     /* Now add user filters */
     var_AddCallback( p_aout, "visual", VisualizationCallback, p_input );
     var_AddCallback( p_aout, "equalizer", EqualizerCallback, p_input );
-    var_AddCallback( p_aout, "audio-replay-gain-mode", ReplayGainCallback, p_input );
-
-    char *gain = var_InheritString (p_aout, "audio-replay-gain-mode");
-    vlc_atomic_setf (&p_input->multiplier,
-                     ReplayGainSelect (VLC_OBJECT(p_aout), gain,
-                                       &p_input->replay_gain));
-    free (gain);
 
     psz_filters = var_GetString( p_aout, "audio-filter" );
     psz_visual = var_GetString( p_aout, "audio-visual");
@@ -318,8 +305,6 @@ int aout_InputDelete( audio_output_t * p_aout, aout_input_t * p_input )
     if ( p_input->b_error )
         return 0;
 
-    var_DelCallback (p_aout, "audio-replay-gain-mode", ReplayGainCallback,
-                     p_input);
     var_DelCallback (p_aout, "equalizer", EqualizerCallback, p_input);
     var_DelCallback (p_aout, "visual", VisualizationCallback, p_input);
 
@@ -700,63 +685,3 @@ static int EqualizerCallback (vlc_object_t *obj, char const *cmd,
         aout_InputRequestRestart ((audio_output_t *)obj);
     return VLC_SUCCESS;
 }
-
-float aout_InputGetMultiplier (const aout_input_t *input)
-{
-    return vlc_atomic_getf (&input->multiplier);
-}
-
-static int ReplayGainCallback (vlc_object_t *obj, char const *var,
-                               vlc_value_t oldval, vlc_value_t val, void *data)
-{
-    aout_input_t *input = data;
-    float multiplier = ReplayGainSelect (obj, val.psz_string,
-                                         &input->replay_gain);
-
-    vlc_atomic_setf (&input->multiplier, multiplier);
-
-    VLC_UNUSED(var); VLC_UNUSED(oldval);
-    return VLC_SUCCESS;
-}
-
-static float ReplayGainSelect (vlc_object_t *obj, const char *str,
-                               const audio_replay_gain_t *replay_gain)
-{
-    float gain = 0.;
-    unsigned mode = AUDIO_REPLAY_GAIN_MAX;
-
-    if (likely(str != NULL))
-    {   /* Find selectrf mode */
-        if (!strcmp (str, "track"))
-            mode = AUDIO_REPLAY_GAIN_TRACK;
-        else
-        if (!strcmp (str, "album"))
-            mode = AUDIO_REPLAY_GAIN_ALBUM;
-
-        /* If the selectrf mode is not available, prefer the other one */
-        if (mode != AUDIO_REPLAY_GAIN_MAX && !replay_gain->pb_gain[mode])
-        {
-            if (replay_gain->pb_gain[!mode])
-                mode = !mode;
-        }
-    }
-
-    /* */
-    if (mode == AUDIO_REPLAY_GAIN_MAX)
-        return 1.;
-
-    if (replay_gain->pb_gain[mode])
-        gain = replay_gain->pf_gain[mode]
-             + var_InheritFloat (obj, "audio-replay-gain-preamp");
-    else
-        gain = var_InheritFloat (obj, "audio-replay-gain-default");
-
-    float multiplier = pow (10., gain / 20.);
-
-    if (replay_gain->pb_peak[mode]
-     && var_InheritBool (obj, "audio-replay-gain-peak-protection")
-     && replay_gain->pf_peak[mode] * multiplier > 1.0)
-        multiplier = 1.0f / replay_gain->pf_peak[mode];
-
-    return multiplier;
-}
index 1c1cfa3..8935288 100644 (file)
@@ -29,6 +29,8 @@
 #endif
 
 #include <stddef.h>
+#include <math.h>
+
 #include <vlc_common.h>
 #include <libvlc.h>
 #include <vlc_modules.h>
@@ -74,6 +76,48 @@ void aout_MixerDelete(audio_mixer_t *mixer)
  */
 void aout_MixerRun(audio_mixer_t *mixer, block_t *block, float amp)
 {
-    if (mixer != NULL)
-        mixer->mix(mixer, block, amp);
+    mixer->mix(mixer, block, amp);
+}
+
+/*** Replay gain ***/
+float (aout_ReplayGainSelect)(vlc_object_t *obj, const char *str,
+                              const audio_replay_gain_t *replay_gain)
+{
+    float gain = 0.;
+    unsigned mode = AUDIO_REPLAY_GAIN_MAX;
+
+    if (likely(str != NULL))
+    {   /* Find selectrf mode */
+        if (!strcmp (str, "track"))
+            mode = AUDIO_REPLAY_GAIN_TRACK;
+        else
+        if (!strcmp (str, "album"))
+            mode = AUDIO_REPLAY_GAIN_ALBUM;
+
+        /* If the selectrf mode is not available, prefer the other one */
+        if (mode != AUDIO_REPLAY_GAIN_MAX && !replay_gain->pb_gain[mode])
+        {
+            if (replay_gain->pb_gain[!mode])
+                mode = !mode;
+        }
+    }
+
+    /* */
+    if (mode == AUDIO_REPLAY_GAIN_MAX)
+        return 1.;
+
+    if (replay_gain->pb_gain[mode])
+        gain = replay_gain->pf_gain[mode]
+             + var_InheritFloat (obj, "audio-replay-gain-preamp");
+    else
+        gain = var_InheritFloat (obj, "audio-replay-gain-default");
+
+    float multiplier = pow (10., gain / 20.);
+
+    if (replay_gain->pb_peak[mode]
+     && var_InheritBool (obj, "audio-replay-gain-peak-protection")
+     && replay_gain->pf_peak[mode] * multiplier > 1.0)
+        multiplier = 1.0f / replay_gain->pf_peak[mode];
+
+    return multiplier;
 }