]> git.sesse.net Git - vlc/commitdiff
+ src/input/decoder.c src/libvlc.h:
authorBoris Dorès <babal@videolan.org>
Sun, 9 Oct 2005 19:19:06 +0000 (19:19 +0000)
committerBoris Dorès <babal@videolan.org>
Sun, 9 Oct 2005 19:19:06 +0000 (19:19 +0000)
  - more precise message for the "force-dolby-surround" option
  - don't use -1 as a value in an integer list option (dangerous casts
    in the wxWidgets interface)
+ modules/audio_filter/converter/a52tofloat32.c:
  - option to disable the internal upmixing algorithm
+ modules/audio_filter/channel_mixer/headphone.c:
  - option to partially compensate the delay introduced by the algorithm
  - option to accept raw Dolby Surround encoded streams

NEWS
modules/audio_filter/channel_mixer/headphone.c
modules/audio_filter/converter/a52tofloat32.c
src/input/decoder.c
src/libvlc.h

diff --git a/NEWS b/NEWS
index b6c5569aeed5c993710da895803f68c77b736b98..894057466ad67ca02ac404282c0dda6aeb850981 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -25,9 +25,13 @@ Services discovery:
  * UPnP service discovery
  * Bonjour service discovery using avahi (Linux only)
 
-Video Filters:
+Video filters:
  * RSS feed overlay
 
+Audio filters:
+* Fixes, enhancements and new options related to the Headphone Channel
+  Mixer and Dolby Surround
+
 Stream output:
  * New shout output module to forward streams to icecast servers
  * Fixed several SAP and SDP announcement bugs
index 7949b4110caf3cd8cf6c17787a41d68db86cffb2..e36ed615cacc09675d9f9ad87472d1d367600573 100644 (file)
@@ -57,6 +57,18 @@ static void DoWork    ( aout_instance_t *, aout_filter_t *, aout_buffer_t *,
 #define HEADPHONE_DIM_LONGTEXT N_( \
      "Distance between front left speaker and listener in meters.")
 
+#define HEADPHONE_COMPENSATE_TEXT N_("Compensate delay")
+#define HEADPHONE_COMPENSATE_LONGTEXT N_( \
+     "The delay which is introduced by the physical algorithm may "\
+     "sometimes be disturbing for the lipsync. In that case, turn "\
+     "this on to compensate.")
+
+#define HEADPHONE_DOLBY_TEXT N_("No decoding of Dolby Surround")
+#define HEADPHONE_DOLBY_LONGTEXT N_( \
+     "If this option is turned on (not recommended), Dolby Surround "\
+     "encoded streams won't be decoded before being processed by this "\
+     "filter.")
+
 vlc_module_begin();
     set_description( N_("Headphone channel mixer with virtual spatialization effect") );
     set_shortname( _("Headphone effect") );
@@ -65,6 +77,10 @@ vlc_module_begin();
 
     add_integer( "headphone-dim", 10, NULL, HEADPHONE_DIM_TEXT,
                  HEADPHONE_DIM_LONGTEXT, VLC_FALSE );
+    add_bool( "headphone-compensate", 0, NULL, HEADPHONE_COMPENSATE_TEXT,
+              HEADPHONE_COMPENSATE_LONGTEXT, VLC_TRUE );
+    add_bool( "headphone-dolby", 0, NULL, HEADPHONE_DOLBY_TEXT,
+              HEADPHONE_DOLBY_LONGTEXT, VLC_TRUE );
 
     set_capability( "audio filter", 0 );
     set_callbacks( Create, Destroy );
@@ -112,9 +128,10 @@ struct aout_filter_sys_t
 static void ComputeChannelOperations ( struct aout_filter_sys_t * p_data
         , unsigned int i_rate , unsigned int i_next_atomic_operation
         , int i_source_channel_offset , double d_x , double d_z
-        , double d_channel_amplitude_factor )
+        , double d_compensation_length , double d_channel_amplitude_factor )
 {
     double d_c = 340; /*sound celerity (unit: m/s)*/
+    double d_compensation_delay = (d_compensation_length-0.1) / d_c * i_rate;
 
     /* Left ear */
     p_data->p_atomic_operations[i_next_atomic_operation]
@@ -123,7 +140,7 @@ static void ComputeChannelOperations ( struct aout_filter_sys_t * p_data
         .i_dest_channel_offset = 0;/* left */
     p_data->p_atomic_operations[i_next_atomic_operation]
         .i_delay = (int)( sqrt( (-0.1-d_x)*(-0.1-d_x) + (0-d_z)*(0-d_z) )
-                          / d_c * i_rate );
+                          / d_c * i_rate - d_compensation_delay );
     if ( d_x < 0 )
     {
         p_data->p_atomic_operations[i_next_atomic_operation]
@@ -147,7 +164,7 @@ static void ComputeChannelOperations ( struct aout_filter_sys_t * p_data
         .i_dest_channel_offset = 1;/* right */
     p_data->p_atomic_operations[i_next_atomic_operation + 1]
         .i_delay = (int)( sqrt( (0.1-d_x)*(0.1-d_x) + (0-d_z)*(0-d_z) )
-                          / d_c * i_rate );
+                          / d_c * i_rate - d_compensation_delay );
     if ( d_x < 0 )
     {
         p_data->p_atomic_operations[i_next_atomic_operation + 1]
@@ -172,6 +189,7 @@ static int Init ( aout_filter_t * p_filter , struct aout_filter_sys_t * p_data
     double d_x = config_GetInt ( p_filter , "headphone-dim" );
     double d_z = d_x;
     double d_z_rear = -d_x/3;
+    double d_min = 0;
     unsigned int i_next_atomic_operation;
     int i_source_channel_offset;
     unsigned int i;
@@ -182,6 +200,19 @@ static int Init ( aout_filter_t * p_filter , struct aout_filter_sys_t * p_data
         return 0;
     }
 
+    if ( config_GetInt ( p_filter , "headphone-compensate" ) )
+    {
+        /* minimal distance to any speaker */
+        if ( i_physical_channels & AOUT_CHAN_REARCENTER )
+        {
+            d_min = d_z_rear;
+        }
+        else
+        {
+            d_min = d_z;
+        }
+    }
+
     /* Number of elementary operations */
     p_data->i_nb_atomic_operations = i_nb_channels * 2;
     if ( i_physical_channels & AOUT_CHAN_CENTER )
@@ -204,7 +235,7 @@ static int Init ( aout_filter_t * p_filter , struct aout_filter_sys_t * p_data
     {
         ComputeChannelOperations ( p_data , i_rate
                 , i_next_atomic_operation , i_source_channel_offset
-                , -d_x , d_z , 2.0 / i_nb_channels );
+                , -d_x , d_z , d_min , 2.0 / i_nb_channels );
         i_next_atomic_operation += 2;
         i_source_channel_offset++;
     }
@@ -212,7 +243,7 @@ static int Init ( aout_filter_t * p_filter , struct aout_filter_sys_t * p_data
     {
         ComputeChannelOperations ( p_data , i_rate
                 , i_next_atomic_operation , i_source_channel_offset
-                , d_x , d_z , 2.0 / i_nb_channels );
+                , d_x , d_z , d_min , 2.0 / i_nb_channels );
         i_next_atomic_operation += 2;
         i_source_channel_offset++;
     }
@@ -220,7 +251,7 @@ static int Init ( aout_filter_t * p_filter , struct aout_filter_sys_t * p_data
     {
         ComputeChannelOperations ( p_data , i_rate
                 , i_next_atomic_operation , i_source_channel_offset
-                , -d_x , 0 , 1.5 / i_nb_channels );
+                , -d_x , 0 , d_min , 1.5 / i_nb_channels );
         i_next_atomic_operation += 2;
         i_source_channel_offset++;
     }
@@ -228,7 +259,7 @@ static int Init ( aout_filter_t * p_filter , struct aout_filter_sys_t * p_data
     {
         ComputeChannelOperations ( p_data , i_rate
                 , i_next_atomic_operation , i_source_channel_offset
-                , d_x , 0 , 1.5 / i_nb_channels );
+                , d_x , 0 , d_min , 1.5 / i_nb_channels );
         i_next_atomic_operation += 2;
         i_source_channel_offset++;
     }
@@ -236,7 +267,7 @@ static int Init ( aout_filter_t * p_filter , struct aout_filter_sys_t * p_data
     {
         ComputeChannelOperations ( p_data , i_rate
                 , i_next_atomic_operation , i_source_channel_offset
-                , -d_x , d_z_rear , 1.5 / i_nb_channels );
+                , -d_x , d_z_rear , d_min , 1.5 / i_nb_channels );
         i_next_atomic_operation += 2;
         i_source_channel_offset++;
     }
@@ -244,7 +275,7 @@ static int Init ( aout_filter_t * p_filter , struct aout_filter_sys_t * p_data
     {
         ComputeChannelOperations ( p_data , i_rate
                 , i_next_atomic_operation , i_source_channel_offset
-                , d_x , d_z_rear , 1.5 / i_nb_channels );
+                , d_x , d_z_rear , d_min , 1.5 / i_nb_channels );
         i_next_atomic_operation += 2;
         i_source_channel_offset++;
     }
@@ -252,7 +283,7 @@ static int Init ( aout_filter_t * p_filter , struct aout_filter_sys_t * p_data
     {
         ComputeChannelOperations ( p_data , i_rate
                 , i_next_atomic_operation , i_source_channel_offset
-                , 0 , -d_z , 1.5 / i_nb_channels );
+                , 0 , -d_z , d_min , 1.5 / i_nb_channels );
         i_next_atomic_operation += 2;
         i_source_channel_offset++;
     }
@@ -261,11 +292,11 @@ static int Init ( aout_filter_t * p_filter , struct aout_filter_sys_t * p_data
         /* having two center channels increases the spatialization effect */
         ComputeChannelOperations ( p_data , i_rate
                 , i_next_atomic_operation , i_source_channel_offset
-                , d_x / 5.0 , d_z , 0.75 / i_nb_channels );
+                , d_x / 5.0 , d_z , d_min , 0.75 / i_nb_channels );
         i_next_atomic_operation += 2;
         ComputeChannelOperations ( p_data , i_rate
                 , i_next_atomic_operation , i_source_channel_offset
-                , -d_x / 5.0 , d_z , 0.75 / i_nb_channels );
+                , -d_x / 5.0 , d_z , d_min , 0.75 / i_nb_channels );
         i_next_atomic_operation += 2;
         i_source_channel_offset++;
     }
@@ -273,7 +304,7 @@ static int Init ( aout_filter_t * p_filter , struct aout_filter_sys_t * p_data
     {
         ComputeChannelOperations ( p_data , i_rate
                 , i_next_atomic_operation , i_source_channel_offset
-                , 0 , d_z_rear , 5.0 / i_nb_channels );
+                , 0 , d_z_rear , d_min , 5.0 / i_nb_channels );
         i_next_atomic_operation += 2;
         i_source_channel_offset++;
     }
@@ -337,7 +368,8 @@ static int Create( vlc_object_t *p_this )
         p_filter->input.i_rate = p_filter->output.i_rate;
     }
     if ( p_filter->input.i_physical_channels == (AOUT_CHAN_LEFT|AOUT_CHAN_RIGHT)
-          && ( p_filter->input.i_original_channels & AOUT_CHAN_DOLBYSTEREO ) )
+          && ( p_filter->input.i_original_channels & AOUT_CHAN_DOLBYSTEREO )
+          && ! config_GetInt ( p_filter , "headphone-dolby" ) )
     {
         b_fit = VLC_FALSE;
         p_filter->input.i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
index 4e22aba2dde6616f8e8e37103b160f7c34543f59..e2f874616e8ebb9a71623f289f9ae8dd69c07b58 100644 (file)
@@ -98,6 +98,9 @@ struct filter_sys_t
     "environment without disturbing anyone. If you disable the dynamic range "\
     "compression the playback will be more adapted to a movie theater or a " \
     "listening room.")
+#define UPMIX_TEXT N_("Enable internal upmixing")
+#define UPMIX_LONGTEXT N_( \
+    "Enable the internal upmixing algorithm (not recommended).")
 
 vlc_module_begin();
     set_shortname( "A/52" );
@@ -105,6 +108,7 @@ vlc_module_begin();
     set_category( CAT_INPUT );
     set_subcategory( SUBCAT_INPUT_ACODEC );
     add_bool( "a52-dynrng", 1, NULL, DYNRNG_TEXT, DYNRNG_LONGTEXT, VLC_FALSE );
+    add_bool( "a52-upmix", 0, NULL, UPMIX_TEXT, UPMIX_LONGTEXT, VLC_TRUE );
     set_capability( "audio filter", 100 );
     set_callbacks( Create, Destroy );
 
@@ -165,6 +169,16 @@ static int Open( vlc_object_t *p_this, filter_sys_t *p_sys,
     p_sys->b_dynrng = config_GetInt( p_this, "a52-dynrng" );
     p_sys->b_dontwarn = 0;
 
+    /* No upmixing: it's not necessary and some other filters may want to do
+     * it themselves. */
+    if ( aout_FormatNbChannels( &output ) > aout_FormatNbChannels( &input ) )
+    {
+        if ( ! config_GetInt( p_this, "a52-upmix" ) )
+        {
+            return VLC_EGENERIC;
+        }
+    }
+
     /* We'll do our own downmixing, thanks. */
     p_sys->i_nb_channels = aout_FormatNbChannels( &output );
     switch ( (output.i_physical_channels & AOUT_CHAN_PHYSMASK)
index 158515a13f55f4624bb839022253f1a4ff056f4f..3d9276226c02284f0bf9d306f9705fcdc1981f11 100644 (file)
@@ -863,12 +863,12 @@ static aout_buffer_t *aout_new_buffer( decoder_t *p_dec, int i_samples )
         if ( i_force_dolby && (format.i_original_channels&AOUT_CHAN_PHYSMASK)
                                     == (AOUT_CHAN_LEFT|AOUT_CHAN_RIGHT) )
         {
-            if ( i_force_dolby > 0 )
+            if ( i_force_dolby == 1 )
             {
                 format.i_original_channels = format.i_original_channels |
                                              AOUT_CHAN_DOLBYSTEREO;
             }
-            else
+            else /* i_force_dolby == 2 */
             {
                 format.i_original_channels = format.i_original_channels &
                                              ~AOUT_CHAN_DOLBYSTEREO;
index 285d611d80de807c21fb3aef45bf196a6c999c9f..2cdf22b103806b7b3f24d66c39162376bafa9cb2 100644 (file)
@@ -161,9 +161,12 @@ static char *ppsz_snap_formats[] =
 
 #define FORCE_DOLBY_TEXT N_("Force detection of Dolby Surround")
 #define FORCE_DOLBY_LONGTEXT N_( \
-    "Use this when you know your stream is or is not encoded with Dolby Surround " \
-    "but fails to be detected as such." )
-static int pi_force_dolby_values[] = { 0, 1, -1 };
+    "Use this when you know your stream is (or is not) encoded with Dolby "\
+    "Surround but fails to be detected as such. And even if the stream is "\
+    "not actually encoded with Dolby Surround, turning on this option might "\
+    "enhance your experience, especially when combined with the Headphone "\
+    "Channel Mixer." )
+static int pi_force_dolby_values[] = { 0, 1, 2 };
 static char *ppsz_force_dolby_descriptions[] = { N_("Auto"), N_("On"), N_("Off") };