Major change of the channels management. p_format->i_channels disappeares
authorChristophe Massiot <massiot@videolan.org>
Thu, 14 Nov 2002 22:38:48 +0000 (22:38 +0000)
committerChristophe Massiot <massiot@videolan.org>
Thu, 14 Nov 2002 22:38:48 +0000 (22:38 +0000)
and is replaced by two members : i_physical_channels and i_original_channels.
i_physical_channels describes the channels which are effectively present
in the stream (at the current point of the aout pipeline), whereas
i_original_channels represents the channels we used to constitute the
stream. For instance a mono stream (FRONT_CENTER) may emanate from a
FRONT_LEFT channel of a STEREO stream.

Additionally, this contains hooks to dynamically select the audio device
and the channels configuration. In order to do that, all aout plugins,
and all interface plug-ins need to be adapted. Currently only SDL
(partially OSS) and the rc interface have been adapted, please use them
as a guide. Other aout plug-ins have been temporarily disabled.

IMPORTANT : if you need a working sound output, DO NOT UPDATE YOUR TREE
for several days until we fix that.

* modules/misc/network/ipv4.c: Fixed a long-standing segfault when saving
  preferences and asking for multicast.

29 files changed:
configure.ac.in
include/aout_internal.h
include/audio_output.h
modules/audio_filter/channel_mixer/trivial.c
modules/audio_filter/converter/a52tofloat32.c
modules/audio_filter/resampler/trivial.c
modules/audio_filter/resampler/ugly.c
modules/audio_mixer/float32.c
modules/audio_output/oss.c
modules/audio_output/sdl.c
modules/codec/a52.c
modules/codec/araw.c
modules/codec/faad/decoder.c
modules/codec/faad/decoder.h
modules/codec/ffmpeg/audio.c
modules/codec/ffmpeg/audio.h
modules/codec/lpcm.c
modules/codec/mad/libmad.c
modules/codec/mpeg_audio/decoder.c
modules/codec/vorbis.c
modules/control/rc/rc.c
modules/gui/macosx/aout.m
modules/misc/network/ipv4.c
modules/video_output/x11/xcommon.c
src/audio_output/common.c
src/audio_output/dec.c
src/audio_output/filters.c
src/audio_output/intf.c
src/audio_output/output.c

index a4471df..8d08e05 100644 (file)
@@ -1755,7 +1755,7 @@ if test "x${enable_oss}" != "xno" &&
   (test "x${SYS}" != "xmingw32" || test "x${enable_oss}" = "xyes")
 then
   AC_CHECK_HEADERS(soundcard.h sys/soundcard.h machine/soundcard.h, [
-    PLUGINS="${PLUGINS} oss"
+    #PLUGINS="${PLUGINS} oss"
     AC_CHECK_LIB(ossaudio,main,LDFLAGS_oss="${LDFLAGS_oss} -lossaudio")
   ])
 fi
@@ -1770,7 +1770,7 @@ AC_ARG_ENABLE(esd,
      AC_PATH_PROG(ESD_CONFIG, esd-config, no)
      if test "x${ESD_CONFIG}" != "xno"
      then
-       PLUGINS="${PLUGINS} esd"
+       #PLUGINS="${PLUGINS} esd"
        CFLAGS_esd="${CFLAGS_esd} `${ESD_CONFIG} --cflags`"
        LDFLAGS_esd="${LDFLAGS_esd} `${ESD_CONFIG} --libs`"
      fi
@@ -1786,7 +1786,7 @@ AC_ARG_ENABLE(arts,
      AC_PATH_PROG(ARTS_CONFIG, artsc-config, no)
      if test "x${ARTS_CONFIG}" != "xno"
      then
-       PLUGINS="${PLUGINS} arts"
+       #PLUGINS="${PLUGINS} arts"
        CFLAGS_arts="${CFLAGS_arts} `${ARTS_CONFIG} --cflags`"
        LDFLAGS_arts="${LDFLAGS_arts} `${ARTS_CONFIG} --libs `"
      fi
@@ -1802,7 +1802,7 @@ AC_ARG_ENABLE(alsa,
      AC_CHECK_HEADER(alsa/asoundlib.h, AC_CHECK_LIB(asound, main, have_alsa="true", have_alsa="false"),have_alsa="false")
      if test "x${have_alsa}" = "xtrue"
      then
-       PLUGINS="${PLUGINS} alsa"
+       #PLUGINS="${PLUGINS} alsa"
        LDFLAGS_alsa="${LDFLAGS_alsa} -lasound -lm -ldl"
      fi
    fi])
@@ -1814,7 +1814,7 @@ AC_ARG_ENABLE(waveout,
   [  --enable-waveout        Win32 waveOut module (default enabled on Win32)])
 if test "x${enable_waveout}" != "xno"; then
   if test "x${SYS}" = "xmingw32" -o "x${SYS}" = "xcygwin"; then
-    PLUGINS="${PLUGINS} waveout"
+    #PLUGINS="${PLUGINS} waveout"
     LDFLAGS_waveout="-lwinmm"
   fi
 fi
index a5c388c..a2ff0c6 100644 (file)
@@ -2,7 +2,7 @@
  * aout_internal.h : internal defines for audio output
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: aout_internal.h,v 1.33 2002/11/13 20:51:04 sam Exp $
+ * $Id: aout_internal.h,v 1.34 2002/11/14 22:38:46 massiot Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -275,10 +275,11 @@ void aout_OutputDelete( aout_instance_t * p_aout );
 VLC_EXPORT( aout_buffer_t *, aout_OutputNextBuffer, ( aout_instance_t *, mtime_t, vlc_bool_t ) );
 
 /* From common.c : */
-VLC_EXPORT( int, aout_FormatNbChannels, ( audio_sample_format_t * p_format ) );
+VLC_EXPORT( int, aout_FormatNbChannels, ( const audio_sample_format_t * p_format ) );
 VLC_EXPORT( void, aout_FormatPrepare, ( audio_sample_format_t * p_format ) );
 VLC_EXPORT( void, aout_FormatPrint, ( aout_instance_t * p_aout, const char * psz_text, const audio_sample_format_t * p_format ) );
 VLC_EXPORT( void, aout_FormatsPrint, ( aout_instance_t * p_aout, const char * psz_text, const audio_sample_format_t * p_format1, const audio_sample_format_t * p_format2 ) );
+VLC_EXPORT( const char *, aout_FormatPrintChannels, ( const audio_sample_format_t * ) );
 void aout_FifoInit( aout_instance_t *, aout_fifo_t *, uint32_t );
 mtime_t aout_FifoNextStart( aout_instance_t *, aout_fifo_t * );
 void aout_FifoPush( aout_instance_t *, aout_fifo_t *, aout_buffer_t * );
index 47b7b34..2e8b090 100644 (file)
@@ -2,7 +2,7 @@
  * audio_output.h : audio output interface
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: audio_output.h,v 1.70 2002/11/11 14:39:11 sam Exp $
+ * $Id: audio_output.h,v 1.71 2002/11/14 22:38:46 massiot Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
  *****************************************************************************/
 struct audio_sample_format_t
 {
-    int                 i_format;
-    int                 i_rate;
-    int                 i_channels;
+    vlc_fourcc_t        i_format;
+    unsigned int        i_rate;
+    /* Describes the channels configuration of the samples (ie. number of
+     * channels which are available in the buffer, and positions). */
+    u32                 i_physical_channels;
+    /* Describes from which original channels, before downmixing, the
+     * buffer is derived. */
+    u32                 i_original_channels;
     /* Optional - for A52, SPDIF and DTS types */
-    int                 i_bytes_per_frame;
-    int                 i_frame_length;
+    unsigned int        i_bytes_per_frame;
+    unsigned int        i_frame_length;
     /* Please note that it may be completely arbitrary - buffers are not
      * obliged to contain a integral number of so-called "frames". It's
      * just here for the division :
@@ -43,14 +48,14 @@ struct audio_sample_format_t
 #define AOUT_FMTS_IDENTICAL( p_first, p_second ) (                          \
     ((p_first)->i_format == (p_second)->i_format)                           \
       && ((p_first)->i_rate == (p_second)->i_rate)                          \
-      && ((p_first)->i_channels == (p_second)->i_channels                   \
-           || (p_first)->i_channels == -1 || (p_second)->i_channels == -1) )
+      && ((p_first)->i_physical_channels == (p_second)->i_physical_channels)\
+      && ((p_first)->i_original_channels == (p_second)->i_original_channels) )
 
 /* Check if i_rate == i_rate and i_channels == i_channels */
 #define AOUT_FMTS_SIMILAR( p_first, p_second ) (                            \
     ((p_first)->i_rate == (p_second)->i_rate)                               \
-      && ((p_first)->i_channels == (p_second)->i_channels                   \
-           || (p_first)->i_channels == -1 || (p_second)->i_channels == -1) )
+      && ((p_first)->i_physical_channels == (p_second)->i_physical_channels)\
+      && ((p_first)->i_original_channels == (p_second)->i_original_channels) )
 
 #ifdef WORDS_BIGENDIAN
 #   define AOUT_FMT_S16_NE VLC_FOURCC('s','1','6','b')
@@ -92,33 +97,24 @@ typedef int32_t vlc_fixed_t;
 #define FIXED32_ONE ((vlc_fixed_t) 0x10000000)
 
 
-/* Dual mono. Two independant mono channels */
-#define AOUT_CHAN_CHANNEL   0x0000000B
-#define AOUT_CHAN_MONO      0x00000001
-#define AOUT_CHAN_STEREO    0x00000002
-/* 3 front channels (left, center, right) */
-#define AOUT_CHAN_3F        0x00000003
-/* 2 front, 1 rear surround channels (L, R, S) */
-#define AOUT_CHAN_2F1R      0x00000004
-/* 3 front, 1 rear surround channels (L, C, R, S) */
-#define AOUT_CHAN_3F1R      0x00000005
-/* 2 front, 2 rear surround channels (L, R, LS, RS) */
-#define AOUT_CHAN_2F2R      0x00000006
-/* 3 front, 2 rear surround channels (L, C, R, LS, RS) */
-#define AOUT_CHAN_3F2R      0x00000007
-/* First of two mono channels */
-#define AOUT_CHAN_CHANNEL1  0x00000008
-/* Second of two mono channels */
-#define AOUT_CHAN_CHANNEL2  0x00000009
-/* Dolby surround compatible stereo */
-#define AOUT_CHAN_DOLBY     0x0000000A
-
-#define AOUT_CHAN_MASK      0x0000000F
-
-/* Low frequency effects channel. Normally used to connect a subwoofer.
- * Can be combined with any of the above channels. For example :
- * AOUT_CHAN_3F2R | AOUT_CHAN_LFE -> 3 front, 2 rear, 1 LFE (5.1) */
-#define AOUT_CHAN_LFE       0x00000010
+/*
+ * Channels descriptions
+ */
+
+/* Values available for physical and original channels */
+#define AOUT_CHAN_CENTER            0x1
+#define AOUT_CHAN_LEFT              0x2
+#define AOUT_CHAN_RIGHT             0x4
+#define AOUT_CHAN_REARCENTER        0x10
+#define AOUT_CHAN_REARLEFT          0x20
+#define AOUT_CHAN_REARRIGHT         0x40
+#define AOUT_CHAN_LFE               0x100
+
+/* Values available for original channels only */
+#define AOUT_CHAN_DOLBYSTEREO       0x10000
+#define AOUT_CHAN_DUALMONO          0x20000
+
+#define AOUT_CHAN_PHYSMASK          0xFFFF
 
 
 /*****************************************************************************
@@ -140,6 +136,9 @@ struct aout_buffer_t
 /* Size of a frame for S/PDIF output. */
 #define AOUT_SPDIF_SIZE 6144
 
+/* Number of samples in an A/52 frame. */
+#define A52_FRAME_NB 1536 
+
 /*****************************************************************************
  * audio_date_t : date incrementation without long-term rounding errors
  *****************************************************************************/
@@ -179,4 +178,5 @@ VLC_EXPORT( int, aout_VolumeUp, ( aout_instance_t *, int, audio_volume_t * ) );
 VLC_EXPORT( int, aout_VolumeDown, ( aout_instance_t *, int, audio_volume_t * ) );
 VLC_EXPORT( int, aout_Restart, ( aout_instance_t * p_aout ) );
 VLC_EXPORT( void, aout_FindAndRestart, ( vlc_object_t * p_this ) );
+VLC_EXPORT( int, aout_ChannelsRestart, ( vlc_object_t *, const char *, vlc_value_t, vlc_value_t, void * ) );
 
index 7f7748e..dccc057 100644 (file)
@@ -2,7 +2,7 @@
  * trivial.c : trivial channel mixer plug-in (drops unwanted channels)
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: trivial.c,v 1.5 2002/10/16 23:12:46 massiot Exp $
+ * $Id: trivial.c,v 1.6 2002/11/14 22:38:46 massiot Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -56,7 +56,10 @@ static int Create( vlc_object_t *p_this )
 {
     aout_filter_t * p_filter = (aout_filter_t *)p_this;
 
-    if ( p_filter->input.i_channels == p_filter->output.i_channels
+    if ( (p_filter->input.i_physical_channels
+           == p_filter->output.i_physical_channels
+           && p_filter->input.i_original_channels
+               == p_filter->output.i_original_channels)
           || p_filter->input.i_format != p_filter->output.i_format
           || p_filter->input.i_rate != p_filter->output.i_rate
           || (p_filter->input.i_format != VLC_FOURCC('f','l','3','2')
@@ -66,7 +69,8 @@ static int Create( vlc_object_t *p_this )
     }
 
     p_filter->pf_do_work = DoWork;
-    if ( p_filter->input.i_channels > p_filter->output.i_channels )
+    if ( aout_FormatNbChannels( &p_filter->input )
+           > aout_FormatNbChannels( &p_filter->output ) )
     {
         /* Downmixing */
        p_filter->b_in_place = 1;
@@ -109,11 +113,43 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter,
     int i_output_nb = aout_FormatNbChannels( &p_filter->output );
     s32 * p_dest = (s32 *)p_out_buf->p_buffer;
     s32 * p_src = (s32 *)p_in_buf->p_buffer;
-    if ( p_filter->output.i_channels == AOUT_CHAN_CHANNEL2 )
-        p_src++;
 
-    SparseCopy( p_dest, p_src, p_in_buf->i_nb_samples, i_output_nb,
-                i_input_nb );
+    if ( p_filter->output.i_original_channels & AOUT_CHAN_DUALMONO )
+    { 
+        int i;
+        /* This is a bit special. */
+        if ( !(p_filter->output.i_original_channels & AOUT_CHAN_LEFT) )
+        {
+            p_src++;
+        }
+        if ( p_filter->output.i_physical_channels == AOUT_CHAN_CENTER )
+        {
+            /* Mono mode */
+            for ( i = p_in_buf->i_nb_samples; i--; )
+            {
+                *p_dest = *p_src;
+                p_dest++;
+                p_src += 2;
+            }
+        }
+        else
+        {
+            /* Fake-stereo mode */
+            for ( i = p_in_buf->i_nb_samples; i--; )
+            {
+                *p_dest = *p_src;
+                p_dest++;
+                *p_dest = *p_src;
+                p_dest++;
+                p_src += 2;
+            }
+        }
+    }
+    else
+    {
+        SparseCopy( p_dest, p_src, p_in_buf->i_nb_samples, i_output_nb,
+                    i_input_nb );
+    }
 
     p_out_buf->i_nb_samples = p_in_buf->i_nb_samples;
     p_out_buf->i_nb_bytes = p_in_buf->i_nb_bytes * i_output_nb / i_input_nb;
index 96e67a7..dc70e63 100644 (file)
@@ -4,7 +4,7 @@
  *   (http://liba52.sf.net/).
  *****************************************************************************
  * Copyright (C) 2001, 2002 VideoLAN
- * $Id: a52tofloat32.c,v 1.5 2002/10/22 23:08:00 massiot Exp $
+ * $Id: a52tofloat32.c,v 1.6 2002/11/14 22:38:46 massiot Exp $
  *
  * Authors: Gildas Bazin <gbazin@netcourrier.com>
  *          Christophe Massiot <massiot@via.ecp.fr>
@@ -119,25 +119,78 @@ static int Create( vlc_object_t * _p_filter )
 
     /* We'll do our own downmixing, thanks. */
     p_sys->i_nb_channels = aout_FormatNbChannels( &p_filter->output );
-    switch ( p_filter->output.i_channels & AOUT_CHAN_MASK )
+    switch ( (p_filter->output.i_physical_channels & AOUT_CHAN_PHYSMASK)
+              & ~AOUT_CHAN_LFE )
     {
-    case AOUT_CHAN_CHANNEL: p_sys->i_flags = A52_CHANNEL; break;
-    case AOUT_CHAN_CHANNEL1: p_sys->i_flags = A52_CHANNEL1; break;
-    case AOUT_CHAN_CHANNEL2: p_sys->i_flags = A52_CHANNEL2; break;
-    case AOUT_CHAN_MONO: p_sys->i_flags = A52_MONO; break;
-    case AOUT_CHAN_STEREO: p_sys->i_flags = A52_STEREO; break;
-    case AOUT_CHAN_DOLBY: p_sys->i_flags = A52_DOLBY; break;
-    case AOUT_CHAN_3F: p_sys->i_flags = A52_3F; break;
-    case AOUT_CHAN_2F1R: p_sys->i_flags = A52_2F1R; break;
-    case AOUT_CHAN_3F1R: p_sys->i_flags = A52_3F1R; break;
-    case AOUT_CHAN_2F2R: p_sys->i_flags = A52_2F2R; break;
-    case AOUT_CHAN_3F2R: p_sys->i_flags = A52_3F2R; break;
+    case AOUT_CHAN_CENTER:
+        if ( (p_filter->output.i_original_channels & AOUT_CHAN_CENTER)
+              || (p_filter->output.i_original_channels
+                   & (AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT)) )
+        {
+            p_sys->i_flags = A52_MONO;
+        }
+        else if ( p_filter->output.i_original_channels & AOUT_CHAN_LEFT )
+        {
+            p_sys->i_flags = A52_CHANNEL1;
+        }
+        else
+        {
+            p_sys->i_flags = A52_CHANNEL2;
+        }
+        break;
+
+    case AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT:
+        if ( p_filter->output.i_original_channels & AOUT_CHAN_DOLBYSTEREO )
+        {
+            p_sys->i_flags = A52_DOLBY;
+        }
+        else if ( p_filter->input.i_original_channels & AOUT_CHAN_DUALMONO )
+        {
+            p_sys->i_flags = A52_CHANNEL;
+        }
+        else if ( !(p_filter->output.i_original_channels & AOUT_CHAN_RIGHT) )
+        {
+            p_sys->i_flags = A52_CHANNEL1;
+        }
+        else if ( !(p_filter->output.i_original_channels & AOUT_CHAN_LEFT) )
+        {
+            p_sys->i_flags = A52_CHANNEL2;
+        }
+        else
+        {
+            p_sys->i_flags = A52_STEREO;
+        }
+        break;
+
+    case AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER:
+        p_sys->i_flags = A52_3F;
+        break;
+
+    case AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARCENTER:
+        p_sys->i_flags = A52_2F1R;
+        break;
+
+    case AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
+          | AOUT_CHAN_REARCENTER:
+        p_sys->i_flags = A52_3F1R;
+        break;
+
+    case AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
+          | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT:
+        p_sys->i_flags = A52_2F2R;
+        break;
+
+    case AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
+          | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT:
+        p_sys->i_flags = A52_3F2R;
+        break;
+
     default:
         msg_Err( p_filter, "unknow sample format !" );
         free( p_sys );
         return -1;
     }
-    if ( p_filter->output.i_channels & AOUT_CHAN_LFE )
+    if ( p_filter->output.i_physical_channels & AOUT_CHAN_LFE )
     {
         p_sys->i_flags |= A52_LFE;
     }
@@ -160,19 +213,34 @@ static int Create( vlc_object_t * _p_filter )
 /*****************************************************************************
  * Interleave: helper function to interleave channels
  *****************************************************************************/
-static void Interleave( float * p_out, const float * p_in, int i_channels )
+static void Interleave( float * p_out, const float * p_in, int i_nb_channels )
 {
     int i, j;
 
-    for ( j = 0; j < i_channels; j++ )
+    for ( j = 0; j < i_nb_channels; j++ )
     {
         for ( i = 0; i < 256; i++ )
         {
-            p_out[i * i_channels + j] = p_in[j * 256 + i];
+            p_out[i * i_nb_channels + j] = p_in[j * 256 + i];
         }
     }
 }
 
+/*****************************************************************************
+ * Duplicate: helper function to duplicate a unique channel
+ *****************************************************************************/
+static void Duplicate( float * p_out, const float * p_in )
+{
+    int i;
+
+    for ( i = 256; i--; )
+    {
+        *p_out++ = *p_in;
+        *p_out++ = *p_in;
+        p_in++;
+    }
+}
+
 /*****************************************************************************
  * DoWork: decode an ATSC A/52 frame.
  *****************************************************************************/
@@ -221,9 +289,20 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter,
 
         p_samples = a52_samples( p_sys->p_liba52 );
 
-        /* Interleave the *$£%ù samples. */
-        Interleave( (float *)(p_out_buf->p_buffer + i * i_bytes_per_block),
-                    p_samples, p_sys->i_nb_channels );
+        if ( ((p_sys->i_flags & A52_CHANNEL1) || (p_sys->i_flags & A52_CHANNEL2)
+               || (p_sys->i_flags & A52_MONO))
+              && (p_filter->output.i_physical_channels 
+                   & (AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT)) )
+        {
+            Duplicate( (float *)(p_out_buf->p_buffer + i * i_bytes_per_block),
+                       p_samples );
+        }
+        else
+        {
+            /* Interleave the *$£%ù samples. */
+            Interleave( (float *)(p_out_buf->p_buffer + i * i_bytes_per_block),
+                        p_samples, p_sys->i_nb_channels );
+        }
     }
 
     p_out_buf->i_nb_samples = p_in_buf->i_nb_samples;
index 47486d9..416f4f8 100644 (file)
@@ -2,7 +2,7 @@
  * trivial.c : trivial resampler (skips samples or pads with zeroes)
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: trivial.c,v 1.8 2002/11/11 22:27:01 gbazin Exp $
+ * $Id: trivial.c,v 1.9 2002/11/14 22:38:46 massiot Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -58,7 +58,10 @@ static int Create( vlc_object_t *p_this )
 
     if ( p_filter->input.i_rate == p_filter->output.i_rate
           || p_filter->input.i_format != p_filter->output.i_format
-          || p_filter->input.i_channels != p_filter->output.i_channels
+          || p_filter->input.i_physical_channels
+              != p_filter->output.i_physical_channels
+          || p_filter->input.i_original_channels
+              != p_filter->output.i_original_channels
           || (p_filter->input.i_format != VLC_FOURCC('f','l','3','2')
                && p_filter->input.i_format != VLC_FOURCC('f','i','3','2')) )
     {
index a1a414f..035b998 100644 (file)
@@ -2,7 +2,7 @@
  * ugly.c : ugly resampler (changes pitch)
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: ugly.c,v 1.5 2002/11/11 22:27:01 gbazin Exp $
+ * $Id: ugly.c,v 1.6 2002/11/14 22:38:46 massiot Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
@@ -58,7 +58,10 @@ static int Create( vlc_object_t *p_this )
 
     if ( p_filter->input.i_rate == p_filter->output.i_rate
           || p_filter->input.i_format != p_filter->output.i_format
-          || p_filter->input.i_channels != p_filter->output.i_channels
+          || p_filter->input.i_physical_channels
+              != p_filter->output.i_physical_channels
+          || p_filter->input.i_original_channels
+              != p_filter->output.i_original_channels
           || (p_filter->input.i_format != VLC_FOURCC('f','l','3','2')
                && p_filter->input.i_format != VLC_FOURCC('f','i','3','2')) )
     {
index 1e72e9a..84b4fc2 100644 (file)
@@ -2,7 +2,7 @@
  * float32.c : precise float32 audio mixer implementation
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: float32.c,v 1.6 2002/10/15 23:10:54 massiot Exp $
+ * $Id: float32.c,v 1.7 2002/11/14 22:38:47 massiot Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -49,7 +49,7 @@ vlc_module_begin();
 vlc_module_end();
 
 /*****************************************************************************
- * Create: allocate trivial mixer
+ * Create: allocate mixer
  *****************************************************************************/
 static int Create( vlc_object_t *p_this )
 {
index 736ebfb..c718cd4 100644 (file)
@@ -2,7 +2,7 @@
  * oss.c : OSS /dev/dsp module for vlc
  *****************************************************************************
  * Copyright (C) 2000-2002 VideoLAN
- * $Id: oss.c,v 1.32 2002/10/25 15:21:42 gbazin Exp $
+ * $Id: oss.c,v 1.33 2002/11/14 22:38:47 massiot Exp $
  *
  * Authors: Michel Kaempf <maxx@via.ecp.fr>
  *          Samuel Hocevar <sam@zoy.org>
@@ -70,7 +70,6 @@ struct aout_sys_t
 /* This must be a power of 2. */
 #define FRAME_SIZE 1024
 #define FRAME_COUNT 4
-#define A52_FRAME_NB 1536
 
 /*****************************************************************************
  * Local prototypes
@@ -103,6 +102,111 @@ vlc_module_begin();
     set_callbacks( Open, Close );
 vlc_module_end();
 
+/*****************************************************************************
+ * Probe: probe the audio device for available formats and channels
+ *****************************************************************************/
+static void Probe( aout_instance_t * p_aout )
+{
+    struct aout_sys_t * p_sys = p_aout->output.p_sys;
+    vlc_value_t val;
+    int i_format, i_nb_channels;
+
+    var_Create( p_aout, "audio-device", VLC_VAR_STRING | VLC_VAR_ISLIST );
+
+    if( ioctl( p_sys->i_fd, SNDCTL_DSP_RESET, NULL ) < 0 )
+    {
+        msg_Err( p_aout, "cannot reset OSS audio device" );
+        var_Destroy( p_aout, "audio-device" );
+        return;
+    }
+
+    if ( AOUT_FMT_NON_LINEAR( &p_aout->output.output ) )
+    {
+        i_format = AFMT_AC3;
+
+        if( ioctl( p_sys->i_fd, SNDCTL_DSP_SETFMT, &i_format ) >= 0
+             && i_format == AFMT_AC3 )
+        {
+            val.psz_string = N_("S/PDIF");
+            var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val );
+        }
+    }
+
+    /* Go to PCM mode. */
+    i_format = AFMT_S16_NE;
+    if( ioctl( p_sys->i_fd, SNDCTL_DSP_RESET, NULL ) < 0 ||
+        ioctl( p_sys->i_fd, SNDCTL_DSP_SETFMT, &i_format ) < 0 )
+    {
+        return;
+    }
+
+#ifdef SNDCTL_DSP_GETCHANNELMASK
+    if ( aout_FormatNbChannels( &p_aout->output.output ) > 2 )
+    {
+        /* Check that the device supports this. */
+
+        int i_chanmask;
+        if ( ioctl( p_sys->i_fd, SNDCTL_DSP_GETCHANNELMASK,
+                    &i_chanmask ) == 0 )
+        {
+            if ( !(i_chanmask & DSP_BIND_FRONT) )
+            {
+                msg_Err( p_aout, "No front channels ! (%x)",
+                         i_chanmask );
+                return;
+            }
+
+            if ( (i_chanmask & (DSP_BIND_SURR | DSP_BIND_CENTER_LFE))
+                  && (p_aout->output.output.i_physical_channels ==
+                       (AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
+                         | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
+                         | AOUT_CHAN_LFE)) )
+            {
+                val.psz_string = N_("5.1");
+                var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val );
+            }
+
+            if ( (i_chanmask & DSP_BIND_SURR)
+                  && (p_aout->output.output.i_physical_channels &
+                       (AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
+                         | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT)) )
+            {
+                val.psz_string = N_("2 Front 2 Rear");
+                var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val );
+            }
+        }
+    }
+#endif
+
+    /* Test for stereo. */
+    i_nb_channels = 2;
+    if( ioctl( p_sys->i_fd, SNDCTL_DSP_CHANNELS, &i_nb_channels ) >= 0
+         && i_nb_channels == 2 )
+    {
+        val.psz_string = N_("Stereo");
+        var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val );
+    }
+
+    /* Reset all. */
+    i_format = AFMT_S16_NE;
+    if( ioctl( p_sys->i_fd, SNDCTL_DSP_RESET, NULL ) < 0 ||
+        ioctl( p_sys->i_fd, SNDCTL_DSP_SETFMT, &i_format ) < 0 )
+    {
+        msg_Err( p_aout, "cannot reset OSS audio device" );
+        var_Destroy( p_aout, "audio-device" );
+        return;
+    }
+
+    /* Test for mono. */
+    i_nb_channels = 1;
+    if( ioctl( p_sys->i_fd, SNDCTL_DSP_CHANNELS, &i_nb_channels ) >= 0  
+         && i_nb_channels == 1 )
+    {
+        val.psz_string = N_("Mono");
+        var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val );        
+    }
+}
+
 /*****************************************************************************
  * Open: open the audio device (the digital sound processor)
  *****************************************************************************
@@ -114,6 +218,7 @@ static int Open( vlc_object_t *p_this )
     aout_instance_t * p_aout = (aout_instance_t *)p_this;
     struct aout_sys_t * p_sys;
     char * psz_device;
+    vlc_value_t val;
 
     /* Allocate structure */
     p_aout->output.p_sys = p_sys = malloc( sizeof( aout_sys_t ) );
@@ -143,6 +248,50 @@ static int Open( vlc_object_t *p_this )
 
     p_aout->output.pf_play = Play;
 
+    if ( var_Type( p_aout, "audio-device" ) < 0 )
+    {
+        Probe( p_aout );
+    }
+
+    if ( var_Get( p_aout, "audio-device", &val ) < 0 )
+    {
+        /* Probe() has failed. */
+        free( p_sys );
+        return VLC_EGENERIC;
+    }
+
+    if ( !strcmp( val.psz_string, N_("S/PDIF") ) )
+    {
+        p_aout->output.output.i_format = VLC_FOURCC('s','p','d','i');
+    }
+    else if ( !strcmp( val.psz_string, N_("5.1") ) )
+    {
+        p_aout->output.output.i_format = AOUT_FMT_S16_NE;
+        p_aout->output.output.i_physical_channels
+            = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
+               | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARLEFT
+               | AOUT_CHAN_LFE;
+    }
+    else if ( !strcmp( val.psz_string, N_("2 Front 2 Rear") ) )
+    {
+        p_aout->output.output.i_format = AOUT_FMT_S16_NE;
+        p_aout->output.output.i_physical_channels
+            = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
+               | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARLEFT;
+    }
+    else if ( !strcmp( val.psz_string, "Stereo" ) )
+    {
+        p_aout->output.output.i_format = AOUT_FMT_S16_NE;
+        p_aout->output.output.i_physical_channels
+            = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
+    }
+    else if ( !strcmp( val.psz_string, "Mono" ) )
+    {
+        p_aout->output.output.i_format = AOUT_FMT_S16_NE;
+        p_aout->output.output.i_physical_channels = AOUT_CHAN_CENTER;
+    }
+    free( val.psz_string );
+
     /* Reset the DSP device */
     if( ioctl( p_sys->i_fd, SNDCTL_DSP_RESET, NULL ) < 0 )
     {
@@ -151,7 +300,7 @@ static int Open( vlc_object_t *p_this )
         free( p_sys );
         return VLC_EGENERIC;
     }
-    
+
     /* Set the output format */
     if ( AOUT_FMT_NON_LINEAR( &p_aout->output.output ) )
     {
@@ -160,17 +309,18 @@ static int Open( vlc_object_t *p_this )
         if( ioctl( p_sys->i_fd, SNDCTL_DSP_SETFMT, &i_format ) < 0
              || i_format != AFMT_AC3 )
         {
-            p_aout->output.output.i_format = AOUT_FMT_S16_NE;
+            msg_Err( p_aout, "cannot reset OSS audio device" );
+            close( p_sys->i_fd );
+            free( p_sys );
+            return VLC_EGENERIC;
         }
-        else
-        {
-            p_aout->output.output.i_format = VLC_FOURCC('s','p','d','i');
-            p_aout->output.i_nb_samples = A52_FRAME_NB;
-            p_aout->output.output.i_bytes_per_frame = AOUT_SPDIF_SIZE;
-            p_aout->output.output.i_frame_length = A52_FRAME_NB;
 
-            aout_VolumeNoneInit( p_aout );
-        }
+        p_aout->output.output.i_format = VLC_FOURCC('s','p','d','i');
+        p_aout->output.i_nb_samples = A52_FRAME_NB;
+        p_aout->output.output.i_bytes_per_frame = AOUT_SPDIF_SIZE;
+        p_aout->output.output.i_frame_length = A52_FRAME_NB;
+
+        aout_VolumeNoneInit( p_aout );
     }
 
     if ( !AOUT_FMT_NON_LINEAR( &p_aout->output.output ) )
@@ -217,100 +367,19 @@ static int Open( vlc_object_t *p_this )
             return VLC_EGENERIC;
         }
 
-        /* These cases are desperate because of the OSS API and A/52 spec. */
-        switch ( p_aout->output.output.i_channels )
-        {
-            case AOUT_CHAN_3F:
-            case AOUT_CHAN_2F1R:
-            case AOUT_CHAN_3F1R:
-            case AOUT_CHAN_STEREO | AOUT_CHAN_LFE:
-            case AOUT_CHAN_2F1R | AOUT_CHAN_LFE:
-            case AOUT_CHAN_3F1R | AOUT_CHAN_LFE:
-            case AOUT_CHAN_DOLBY | AOUT_CHAN_LFE:
-                p_aout->output.output.i_channels = AOUT_CHAN_STEREO;
-                break;
-            case AOUT_CHAN_CHANNEL | AOUT_CHAN_LFE:
-            case AOUT_CHAN_CHANNEL1 | AOUT_CHAN_LFE:
-            case AOUT_CHAN_CHANNEL2 | AOUT_CHAN_LFE:
-            case AOUT_CHAN_MONO | AOUT_CHAN_LFE:
-            case AOUT_CHAN_2F2R | AOUT_CHAN_LFE:
-                p_aout->output.output.i_channels &= ~AOUT_CHAN_LFE;
-                break;
-            case AOUT_CHAN_3F2R:
-                p_aout->output.output.i_channels = AOUT_CHAN_2F2R;
-                break;
-        }
-        /* In a nutshell, possible types : AOUT_CHAN_STEREO (and al.),
-           AOUT_CHAN_2F2R, AOUT_CHAN_3F1R | AOUT_CHAN_LFE. */
-
         i_nb_channels = aout_FormatNbChannels( &p_aout->output.output );
 
-        if ( i_nb_channels > 2 )
-        {
-            /* Check that the device supports this. */
-
-#ifdef SNDCTL_DSP_GETCHANNELMASK
-            int i_chanmask;
-            if ( ioctl( p_sys->i_fd, SNDCTL_DSP_GETCHANNELMASK,
-                        &i_chanmask ) == 0 )
-            {
-                if ( !(i_chanmask & DSP_BIND_FRONT) )
-                {
-                    msg_Err( p_aout, "No front channels ! (%x)",
-                             i_chanmask );
-                    close( p_sys->i_fd );
-                    free( p_sys );
-                    return VLC_EGENERIC;
-                }
-
-                if ( !(i_chanmask & DSP_BIND_SURR) )
-                {
-                    p_aout->output.output.i_channels = AOUT_CHAN_STEREO;
-                    i_nb_channels = 2;
-                }
-                if ( p_aout->output.output.i_channels ==
-                         (AOUT_CHAN_3F2R | AOUT_CHAN_LFE)
-                      && !(i_chanmask & DSP_BIND_CENTER_LFE) )
-                {
-                    p_aout->output.output.i_channels = AOUT_CHAN_2F2R;
-                    i_nb_channels = 4;
-                }
-            }
-            else
-#endif
-            {
-                /* The driver doesn't support this call, assume it is stereo. */
-                p_aout->output.output.i_channels = AOUT_CHAN_STEREO;
-                i_nb_channels = 2;
-            }
-        }
-
         /* Set the number of channels */
-        if( ioctl( p_sys->i_fd, SNDCTL_DSP_CHANNELS, &i_nb_channels ) < 0 )
+        if( ioctl( p_sys->i_fd, SNDCTL_DSP_CHANNELS, &i_nb_channels ) < 0 ||
+            i_nb_channels != aout_FormatNbChannels( &p_aout->output.output ) )
         {
-            msg_Err( p_aout, "cannot set number of audio channels (%i)",
-                              p_aout->output.output.i_channels );
+            msg_Err( p_aout, "cannot set number of audio channels (%x)",
+                     aout_FormatPrintChannels( &p_aout->output.output) );
             close( p_sys->i_fd );
             free( p_sys );
             return VLC_EGENERIC;
         }
 
-        if ( i_nb_channels != aout_FormatNbChannels( &p_aout->output.output ) )
-        {
-            switch ( i_nb_channels )
-            {
-            case 1: p_aout->output.output.i_channels = AOUT_CHAN_MONO; break;
-            case 2: p_aout->output.output.i_channels = AOUT_CHAN_STEREO; break;
-            case 4: p_aout->output.output.i_channels = AOUT_CHAN_2F2R; break;
-            default:
-                msg_Err( p_aout, "Unsupported downmixing (%d)", i_nb_channels );
-                close( p_sys->i_fd );
-                free( p_sys );
-                return VLC_EGENERIC;
-            }
-        }
-
         /* Set the output rate */
         i_rate = p_aout->output.output.i_rate;
         if( ioctl( p_sys->i_fd, SNDCTL_DSP_SPEED, &i_rate ) < 0 )
@@ -346,7 +415,7 @@ static int Open( vlc_object_t *p_this )
 
         if( ioctl( p_sys->i_fd, SNDCTL_DSP_GETOSPACE, &audio_buf ) < 0 )
         {
-            msg_Warn( p_aout, "cannot get fragment size" );
+            msg_Err( p_aout, "cannot get fragment size" );
             close( p_sys->i_fd );
             free( p_sys );
             return VLC_EGENERIC;
@@ -370,6 +439,9 @@ static int Open( vlc_object_t *p_this )
         aout_VolumeSoftInit( p_aout );
     }
 
+    p_aout->output.p_sys->b_workaround_buggy_driver =
+        config_GetInt( p_aout, "oss-buggy" );
+
     /* Create OSS thread and wait for its readiness. */
     if( vlc_thread_create( p_aout, "aout", OSSThread,
                            VLC_THREAD_PRIORITY_OUTPUT, VLC_FALSE ) )
@@ -380,9 +452,6 @@ static int Open( vlc_object_t *p_this )
         return VLC_ETHREAD;
     }
 
-    p_aout->output.p_sys->b_workaround_buggy_driver =
-        config_GetInt( p_aout, "oss-buggy" );
-
     return VLC_SUCCESS;
 }
 
index 8620022..30eb018 100644 (file)
@@ -2,7 +2,7 @@
  * sdl.c : SDL audio output plugin for vlc
  *****************************************************************************
  * Copyright (C) 2000-2002 VideoLAN
- * $Id: sdl.c,v 1.14 2002/10/16 23:12:45 massiot Exp $
+ * $Id: sdl.c,v 1.15 2002/11/14 22:38:47 massiot Exp $
  *
  * Authors: Michel Kaempf <maxx@via.ecp.fr>
  *          Samuel Hocevar <sam@zoy.org>
@@ -59,7 +59,7 @@ struct aout_sys_t
 static int  Open        ( vlc_object_t * );
 static void Close       ( vlc_object_t * );
 static void Play        ( aout_instance_t * );
-static void SDLCallback ( void *, Uint8 *, int );
+static void SDLCallback ( void *, byte_t *, int );
 
 /*****************************************************************************
  * Module descriptor
@@ -104,12 +104,31 @@ static int Open ( vlc_object_t *p_this )
         return VLC_EGENERIC;
     }
 
+    if ( var_Type( p_aout, "audio-device" ) ==
+             (VLC_VAR_STRING | VLC_VAR_ISLIST) )
+    {
+        /* The user has selected an audio device. */
+        vlc_value_t val;
+        var_Get( p_aout, "audio-device", &val );
+        if ( !strcmp( val.psz_string, N_("Stereo") ) )
+        {
+            p_aout->output.output.i_physical_channels
+                = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
+        }
+        else if ( !strcmp( val.psz_string, N_("Mono") ) )
+        {
+            p_aout->output.output.i_physical_channels = AOUT_CHAN_CENTER;
+        }
+        free( val.psz_string );
+    }
+
     i_nb_channels = aout_FormatNbChannels( &p_aout->output.output );
     if ( i_nb_channels > 2 )
     {
         /* SDL doesn't support more than two channels. */
         i_nb_channels = 2;
-        p_aout->output.output.i_channels = AOUT_CHAN_STEREO;
+        p_aout->output.output.i_physical_channels
+            = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
     }
     desired.freq       = p_aout->output.output.i_rate;
     desired.format     = AUDIO_S16SYS;
@@ -147,10 +166,44 @@ static int Open ( vlc_object_t *p_this )
 
     if ( obtained.channels != i_nb_channels )
     {
-        p_aout->output.output.i_channels = (obtained.channels == 2 ?
-                                            AOUT_CHAN_STEREO :
-                                            AOUT_CHAN_MONO);
+        p_aout->output.output.i_physical_channels = (obtained.channels == 2 ?
+                                            AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT :
+                                            AOUT_CHAN_CENTER);
+
+        if ( var_Type( p_aout, "audio-device" ) < 0 )
+        {
+            vlc_value_t val;
+            var_Create( p_aout, "audio-device", VLC_VAR_STRING | VLC_VAR_ISLIST );
+            val.psz_string = (obtained.channels == 2) ? N_("Stereo") :
+                              N_("Mono");
+            var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val );
+            var_AddCallback( p_aout, "audio-device", aout_ChannelsRestart,
+                             NULL );
+        }
+    }
+    else if ( var_Type( p_aout, "audio-device" ) < 0 )
+    {
+        /* First launch. */
+        vlc_value_t val;
+        var_Create( p_aout, "audio-device", VLC_VAR_STRING | VLC_VAR_ISLIST );
+        val.psz_string = N_("Stereo");
+        var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val );
+        val.psz_string = N_("Mono");
+        var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val );
+        if ( i_nb_channels == 2 )
+        {
+            val.psz_string = N_("Stereo");
+        }
+        else
+        {
+            val.psz_string = N_("Mono");
+        }
+        var_Change( p_aout, "audio-device", VLC_VAR_SETDEFAULT, &val );
+
+        var_AddCallback( p_aout, "audio-device", aout_ChannelsRestart,
+                         NULL );
     }
+
     p_aout->output.output.i_rate = obtained.freq;
     p_aout->output.i_nb_samples = obtained.samples;
     p_aout->output.pf_play = Play;
index 30d3628..24fb533 100644 (file)
@@ -2,7 +2,7 @@
  * a52.c: A/52 basic parser
  *****************************************************************************
  * Copyright (C) 2001-2002 VideoLAN
- * $Id: a52.c,v 1.17 2002/10/28 22:23:23 gbazin Exp $
+ * $Id: a52.c,v 1.18 2002/11/14 22:38:47 massiot Exp $
  *
  * Authors: Stéphane Borel <stef@via.ecp.fr>
  *          Christophe Massiot <massiot@via.ecp.fr>
@@ -40,8 +40,6 @@
 #   include <unistd.h>
 #endif
 
-#define A52_FRAME_NB 1536 
-
 /*****************************************************************************
  * dec_thread_t : A52 pass-through thread descriptor
  *****************************************************************************/
@@ -142,7 +140,7 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
     /* decoder thread's main loop */
     while ( !p_dec->p_fifo->b_die && !p_dec->p_fifo->b_error )
     {
-        int i_frame_size, i_channels, i_rate, i_bit_rate;
+        int i_frame_size, i_original_channels, i_rate, i_bit_rate;
         mtime_t pts;
         byte_t p_header[7];
         aout_buffer_t * p_buffer;
@@ -167,7 +165,7 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
         if( p_dec->p_fifo->b_die ) break;
 
         /* Check if frame is valid and get frame info */
-        i_frame_size = SyncInfo( p_header, &i_channels, &i_rate,
+        i_frame_size = SyncInfo( p_header, &i_original_channels, &i_rate,
                                  &i_bit_rate );
 
         if( !i_frame_size )
@@ -178,7 +176,8 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
 
         if( (p_dec->p_aout_input != NULL) &&
             ( (p_dec->output_format.i_rate != i_rate)
-                || (p_dec->output_format.i_channels != i_channels)
+                || (p_dec->output_format.i_original_channels
+                      != i_original_channels)
                 || (p_dec->output_format.i_bytes_per_frame != i_frame_size) ) )
         {
             /* Parameters changed - this should not happen. */
@@ -190,7 +189,9 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
         if( p_dec->p_aout_input == NULL )
         {
             p_dec->output_format.i_rate = i_rate;
-            p_dec->output_format.i_channels = i_channels;
+            p_dec->output_format.i_original_channels = i_original_channels;
+            p_dec->output_format.i_physical_channels
+                       = i_original_channels & AOUT_CHAN_PHYSMASK;
             p_dec->output_format.i_bytes_per_frame = i_frame_size;
             p_dec->output_format.i_frame_length = A52_FRAME_NB;
             aout_DateInit( &end_date, i_rate );
@@ -262,13 +263,13 @@ static void EndThread( dec_thread_t * p_dec )
     free( p_dec );
 }
 
-/****************************************************************************
+/*****************************************************************************
  * SyncInfo: parse A52 sync info
- ****************************************************************************
+ *****************************************************************************
  * This code is borrowed from liba52 by Aaron Holtzman & Michel Lespinasse,
  * since we don't want to oblige S/PDIF people to use liba52 just to get
  * their SyncInfo...
- ****************************************************************************/
+ *****************************************************************************/
 int SyncInfo( const byte_t * p_buf, int * pi_channels, int * pi_sample_rate,
               int * pi_bit_rate)
 {
@@ -293,20 +294,50 @@ int SyncInfo( const byte_t * p_buf, int * pi_channels, int * pi_sample_rate,
     acmod = p_buf[6] >> 5;
     if ( (p_buf[6] & 0xf8) == 0x50 )
     {
-        *pi_channels = AOUT_CHAN_DOLBY;
+        /* Dolby surround = stereo + Dolby */
+        *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
+                        | AOUT_CHAN_DOLBYSTEREO;
     }
     else switch ( acmod )
     {
-    case 0x0: *pi_channels = AOUT_CHAN_CHANNEL; break;
-    case 0x1: *pi_channels = AOUT_CHAN_MONO; break;
-    case 0x2: *pi_channels = AOUT_CHAN_STEREO; break;
-    case 0x3: *pi_channels = AOUT_CHAN_3F; break;
-    case 0x4: *pi_channels = AOUT_CHAN_2F1R; break;
-    case 0x5: *pi_channels = AOUT_CHAN_3F1R; break;
-    case 0x6: *pi_channels = AOUT_CHAN_2F2R; break;
-    case 0x7: *pi_channels = AOUT_CHAN_3F2R; break;
-    case 0x8: *pi_channels = AOUT_CHAN_CHANNEL1; break;
-    case 0x9: *pi_channels = AOUT_CHAN_CHANNEL2; break;
+    case 0x0:
+        /* Dual-mono = stereo + dual-mono */
+        *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
+                        | AOUT_CHAN_DUALMONO;
+        break;
+    case 0x1:
+        /* Mono */
+        *pi_channels = AOUT_CHAN_CENTER;
+        break;
+    case 0x2:
+        /* Stereo */
+        *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
+        break;
+    case 0x3:
+        /* 3F */
+        *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER;
+        break;
+    case 0x4:
+        /* 2F1R */
+        *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARCENTER;
+        break;
+    case 0x5:
+        /* 3F1R */
+        *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
+                        | AOUT_CHAN_REARCENTER;
+        break;
+    case 0x6:
+        /* 2F2R */
+        *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
+                        | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
+        break;
+    case 0x7:
+        /* 3F2R */
+        *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
+                        | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
+        break;
+    default:
+        return 0;
     }
    
     if ( p_buf[6] & lfeon[acmod] ) *pi_channels |= AOUT_CHAN_LFE;
index 4615fae..fd70266 100644 (file)
@@ -2,7 +2,7 @@
  * araw.c: Pseudo audio decoder; for raw pcm data
  *****************************************************************************
  * Copyright (C) 2001, 2002 VideoLAN
- * $Id: araw.c,v 1.6 2002/11/08 14:23:49 gbazin Exp $
+ * $Id: araw.c,v 1.7 2002/11/14 22:38:47 massiot Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *      
@@ -85,12 +85,15 @@ vlc_module_begin();
 vlc_module_end();
 
 
-static int i_channels_maps[6] =
+static int pi_channels_maps[6] =
 {
     0,
-    AOUT_CHAN_MONO,     AOUT_CHAN_STEREO,
-    AOUT_CHAN_3F,       AOUT_CHAN_2F2R,
-    AOUT_CHAN_3F2R
+    AOUT_CHAN_CENTER,
+    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
+    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER,
+    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARLEFT,
+    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
+     | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARLEFT 
 };
 
 /*****************************************************************************
@@ -249,8 +252,9 @@ static int InitThread( adec_thread_t * p_adec )
         return( -1 );
     }
 
-    p_adec->output_format.i_channels = 
-            i_channels_maps[p_adec->format.i_channels];
+    p_adec->output_format.i_physical_channels = 
+            p_adec->output_format.i_original_channels =
+            pi_channels_maps[p_adec->format.i_channels];
     p_adec->p_aout = NULL;
     p_adec->p_aout_input = NULL;
 
index 87988ae..adf7538 100644 (file)
@@ -2,7 +2,7 @@
  * decoder.c: AAC decoder using libfaad2
  *****************************************************************************
  * Copyright (C) 2001, 2002 VideoLAN
- * $Id: decoder.c,v 1.11 2002/11/10 02:47:27 fenrir Exp $
+ * $Id: decoder.c,v 1.12 2002/11/14 22:38:47 massiot Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *      
@@ -120,8 +120,17 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
     return( 0 );
 }
 
-
-#define FREE( p ) if( p ) free( p ); p = NULL
+static int pi_channels_maps[6] =
+{
+    0,
+    AOUT_CHAN_CENTER,   AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
+    AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
+    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
+    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
+     | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
+};
+
+#define FREE( p ) if( p != NULL ) free( p ); p = NULL
 #define GetWLE( p ) \
     ( *(u8*)(p) + ( *((u8*)(p)+1) << 8 ) )
 
@@ -134,7 +143,7 @@ static void faac_GetWaveFormatEx( waveformatex_t *p_wh,
 {
 
     p_wh->i_formattag     = GetWLE( p_data );
-    p_wh->i_channels      = GetWLE( p_data + 2 );
+    p_wh->i_nb_channels   = GetWLE( p_data + 2 );
     p_wh->i_samplespersec = GetDWLE( p_data + 4 );
     p_wh->i_avgbytespersec= GetDWLE( p_data + 8 );
     p_wh->i_blockalign    = GetWLE( p_data + 12 );
@@ -188,7 +197,7 @@ static int InitThread( adec_thread_t * p_adec )
 {
     int i_status;
     unsigned long i_rate;
-    unsigned char i_channels;
+    unsigned char i_nb_channels;
             
     faacDecConfiguration *p_faad_config;
 
@@ -215,7 +224,7 @@ static int InitThread( adec_thread_t * p_adec )
         return( -1 );
     }
     
-    if( !p_adec->format.p_data )
+    if( p_adec->format.p_data == NULL )
     {
         int i_frame_size;
         pes_packet_t *p_pes;
@@ -254,7 +263,7 @@ static int InitThread( adec_thread_t * p_adec )
                                 p_adec->p_buffer,
                                 i_frame_size,
                                 &i_rate,
-                                &i_channels );
+                                &i_nb_channels );
     }
     else
     {
@@ -262,7 +271,7 @@ static int InitThread( adec_thread_t * p_adec )
                                  p_adec->format.p_data,
                                  p_adec->format.i_size,
                                  &i_rate,
-                                 &i_channels );
+                                 &i_nb_channels );
     }
 
     if( i_status < 0 )
@@ -275,7 +284,7 @@ static int InitThread( adec_thread_t * p_adec )
     msg_Dbg( p_adec->p_fifo,
              "faad intitialized, samplerate:%dHz channels:%d",
              i_rate, 
-             i_channels );
+             i_nb_channels );
 
 
     /* set default configuration */
@@ -287,7 +296,7 @@ static int InitThread( adec_thread_t * p_adec )
     /* Initialize the thread properties */
     p_adec->output_format.i_format = VLC_FOURCC('f','l','3','2');
     p_adec->output_format.i_rate = i_rate;
-    p_adec->output_format.i_channels = i_channels;
+    p_adec->output_format.i_channels = pi_channels_maps[i_nb_channels];
     p_adec->p_aout = NULL;
     p_adec->p_aout_input = NULL;
 
@@ -380,7 +389,8 @@ static void DecodeThread( adec_thread_t *p_adec )
     
     /* **** First check if we have a valid output **** */
     if( ( !p_adec->p_aout_input )||
-        ( p_adec->output_format.i_channels != faad_frame.channels ) )
+        ( p_adec->output_format.i_channels !=
+             pi_channels_maps[faad_frame.channels] ) )
     {
         if( p_adec->p_aout_input )
         {
@@ -390,7 +400,7 @@ static void DecodeThread( adec_thread_t *p_adec )
 
         /* **** Create a new audio output **** */
         p_adec->output_format.i_channels = 
-                i_channels_maps[faad_frame.channels];
+                pi_channels_maps[faad_frame.channels];
         aout_DateInit( &p_adec->date, p_adec->output_format.i_rate );
         p_adec->p_aout_input = aout_DecNew( p_adec->p_fifo,
                                             &p_adec->p_aout,
index 17cfae7..6786476 100644 (file)
@@ -3,7 +3,7 @@
  *
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: decoder.h,v 1.4 2002/10/27 18:06:33 fenrir Exp $
+ * $Id: decoder.h,v 1.5 2002/11/14 22:38:47 massiot Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *      
@@ -27,7 +27,7 @@
 typedef struct waveformatex_s
 {
     u16 i_formattag;
-    u16 i_channels;
+    u16 i_nb_channels;
     u32 i_samplespersec;
     u32 i_avgbytespersec;
     u16 i_blockalign;
@@ -70,13 +70,3 @@ typedef struct adec_thread_s
 
 } adec_thread_t;
 
-
-static int i_channels_maps[6] = 
-{
-    0,
-    AOUT_CHAN_MONO,     AOUT_CHAN_STEREO,
-    AOUT_CHAN_3F,       AOUT_CHAN_2F2R,
-    AOUT_CHAN_3F2R
-};
-
-
index 17da3d5..6c0cb47 100644 (file)
@@ -2,7 +2,7 @@
  * audio.c: audio decoder using ffmpeg library
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: audio.c,v 1.2 2002/10/29 10:22:32 gbazin Exp $
+ * $Id: audio.c,v 1.3 2002/11/14 22:38:47 massiot Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
@@ -57,12 +57,14 @@ int      E_( InitThread_Audio )   ( adec_thread_t * );
 void     E_( EndThread_Audio )    ( adec_thread_t * );
 void     E_( DecodeThread_Audio ) ( adec_thread_t * );
 
-static int i_channels_maps[6] =
+static int pi_channels_maps[6] =
 {
     0,
-    AOUT_CHAN_MONO,     AOUT_CHAN_STEREO,
-    AOUT_CHAN_3F,       AOUT_CHAN_2F2R,
-    AOUT_CHAN_3F2R
+    AOUT_CHAN_CENTER,   AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
+    AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
+    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
+    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
+     | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
 };  
 
 /*****************************************************************************
@@ -73,7 +75,7 @@ static void ffmpeg_GetWaveFormatEx( waveformatex_t *p_wh,
                                     u8 *p_data )
 {
     p_wh->i_formattag     = GetWLE( p_data );
-    p_wh->i_channels      = GetWLE( p_data + 2 );
+    p_wh->i_nb_channels   = GetWLE( p_data + 2 );
     p_wh->i_samplespersec = GetDWLE( p_data + 4 );
     p_wh->i_avgbytespersec= GetDWLE( p_data + 8 );
     p_wh->i_blockalign    = GetWLE( p_data + 12 );
@@ -121,7 +123,7 @@ int E_( InitThread_Audio )( adec_thread_t *p_adec )
 
     /* ***** Fill p_context with init values ***** */
     p_adec->p_context->sample_rate = p_adec->format.i_samplespersec;
-    p_adec->p_context->channels = p_adec->format.i_channels;
+    p_adec->p_context->channels = p_adec->format.i_nb_channels;
 #if LIBAVCODEC_BUILD >= 4618
     p_adec->p_context->block_align = p_adec->format.i_blockalign;
 #endif
@@ -157,7 +159,9 @@ int E_( InitThread_Audio )( adec_thread_t *p_adec )
 
     p_adec->output_format.i_format = AOUT_FMT_S16_NE;
     p_adec->output_format.i_rate = p_adec->format.i_samplespersec;
-    p_adec->output_format.i_channels = p_adec->format.i_channels;
+    p_adec->output_format.i_physical_channels
+        = p_adec->output_format.i_original_channels
+        = p_adec->format.i_nb_channels;
     
     p_adec->p_aout = NULL;
     p_adec->p_aout_input = NULL;
@@ -234,21 +238,23 @@ void  E_( DecodeThread_Audio )( adec_thread_t *p_adec )
     }
 
     /* **** Now we can output these samples **** */
-    i_samplesperchannel = i_output_size / 2 /  p_adec->output_format.i_channels;
+    i_samplesperchannel = i_output_size / 2
+                           / aout_FormatNbChannels( &p_adec->output_format );
     /* **** First check if we have a valid output **** */
-    if( ( !p_adec->p_aout_input )||
-        ( p_adec->output_format.i_channels != 
-                    p_adec->p_context->channels ) )
+    if( ( p_adec->p_aout_input == NULL )||
+        ( p_adec->output_format.i_original_channels != 
+                    pi_channels_maps[p_adec->p_context->channels] ) )
     {
-        if( p_adec->p_aout_input )
+        if( p_adec->p_aout_input != NULL )
         {
             /* **** Delete the old **** */
             aout_DecDelete( p_adec->p_aout, p_adec->p_aout_input );
         }
 
         /* **** Create a new audio output **** */
-        p_adec->output_format.i_channels = 
-                i_channels_maps[p_adec->p_context->channels];
+        p_adec->output_format.i_physical_channels = 
+            p_adec->output_format.i_original_channels = 
+                pi_channels_maps[p_adec->p_context->channels];
 
         aout_DateInit( &p_adec->date, p_adec->output_format.i_rate );
         p_adec->p_aout_input = aout_DecNew( p_adec->p_fifo,
index 5ad5ca9..01ceb39 100644 (file)
@@ -2,7 +2,7 @@
  * audio.h: video decoder using ffmpeg library
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: audio.h,v 1.1 2002/10/28 06:26:11 fenrir Exp $
+ * $Id: audio.h,v 1.2 2002/11/14 22:38:47 massiot Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
@@ -26,7 +26,7 @@
 typedef struct waveformatex_s
 {
     u16 i_formattag;
-    u16 i_channels;
+    u16 i_nb_channels;
     u32 i_samplespersec;
     u32 i_avgbytespersec;
     u16 i_blockalign;
index 62ac7aa..da12096 100644 (file)
@@ -2,7 +2,7 @@
  * lpcm.c: lpcm decoder module
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: lpcm.c,v 1.6 2002/10/27 16:58:14 gbazin Exp $
+ * $Id: lpcm.c,v 1.7 2002/11/14 22:38:47 massiot Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *          Henri Fallon <henri@videolan.org>
@@ -133,7 +133,9 @@ static int RunDecoder( decoder_fifo_t * p_fifo )
     /* FIXME : I suppose the number of channel and sampling rate 
      * are somewhere in the headers */
     p_dec->output_format.i_format = VLC_FOURCC('s','1','6','b');
-    p_dec->output_format.i_channels = AOUT_CHAN_STEREO;
+    p_dec->output_format.i_physical_channels
+           = p_dec->output_format.i_original_channels
+           = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
     p_dec->output_format.i_rate = 48000;
     
     aout_DateInit( &p_dec->end_date, 48000 );
index f0a8395..f9aa1ce 100644 (file)
@@ -148,14 +148,15 @@ enum mad_flow libmad_output( void *p_data, struct mad_header const *p_header,
     mad_fixed_t const * p_right = p_pcm->samples[1];
     int                 i_samples = p_pcm->length;
     mad_fixed_t *       p_samples;
-    int                 i_channels = (p_pcm->channels == 2) ? AOUT_CHAN_STEREO :
-                                     AOUT_CHAN_MONO;
+    int                 i_channels = (p_pcm->channels == 2) ?
+                                     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT :
+                                     AOUT_CHAN_CENTER;
 
     /* Creating the audio output fifo. Assume the samplerate and nr of channels
      * from the first decoded frame is right for the entire audio track. */
     if( (p_dec->p_aout_input != NULL) &&
         (p_dec->output_format.i_rate != p_pcm->samplerate
-           || p_dec->output_format.i_channels != i_channels) )
+           || p_dec->output_format.i_physical_channels != i_channels) )
     {
         /* Parameters changed - this should not happen. */
         aout_DecDelete( p_dec->p_aout, p_dec->p_aout_input );
@@ -166,7 +167,8 @@ enum mad_flow libmad_output( void *p_data, struct mad_header const *p_header,
     if( p_dec->p_aout_input == NULL )
     {
         p_dec->output_format.i_rate = p_pcm->samplerate;
-        p_dec->output_format.i_channels = i_channels;
+        p_dec->output_format.i_physical_channels = i_channels;
+        p_dec->output_format.i_original_channels = i_channels;
         aout_DateInit( &p_dec->end_date, p_pcm->samplerate );
         p_dec->p_aout_input = aout_DecNew( p_dec->p_fifo,
                                            &p_dec->p_aout,
index 6602077..e382a43 100644 (file)
@@ -2,7 +2,7 @@
  * decoder.c: MPEG audio decoder thread
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: decoder.c,v 1.7 2002/10/27 16:58:13 gbazin Exp $
+ * $Id: decoder.c,v 1.8 2002/11/14 22:38:47 massiot Exp $
  *
  * Authors: Michel Kaempf <maxx@via.ecp.fr>
  *          Michel Lespinasse <walken@via.ecp.fr>
@@ -173,8 +173,9 @@ static void DecodeThread( adec_thread_t * p_dec )
     {
         /* Create the output fifo if it doesn't exist yet */
         if( ( p_dec->p_aout_input == NULL ) ||
-            ( p_dec->output_format.i_channels !=
-               ( sync_info.b_stereo ? AOUT_CHAN_STEREO : AOUT_CHAN_MONO ) ) ||
+            ( p_dec->output_format.i_physical_channels !=
+               ( sync_info.b_stereo ? AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT :
+                 AOUT_CHAN_CENTER ) ) ||
             ( p_dec->output_format.i_rate != sync_info.sample_rate ) )
         {
             if( p_dec->p_aout_input )
@@ -186,8 +187,10 @@ static void DecodeThread( adec_thread_t * p_dec )
 
             /* Set output configuration */
             p_dec->output_format.i_format   = VLC_FOURCC('f','l','3','2');
-            p_dec->output_format.i_channels =
-               ( sync_info.b_stereo ? AOUT_CHAN_STEREO : AOUT_CHAN_MONO );
+            p_dec->output_format.i_physical_channels =
+               p_dec->output_format.i_original_channels =
+               ( sync_info.b_stereo ? AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT :
+                 AOUT_CHAN_CENTER );
             p_dec->output_format.i_rate     = sync_info.sample_rate;
             aout_DateInit( &p_dec->end_date, sync_info.sample_rate );
             p_dec->p_aout_input = aout_DecNew( p_dec->p_fifo,
index 0fa0d8f..a7a4038 100644 (file)
@@ -2,7 +2,7 @@
  * vorbis.c: vorbis decoder module making use of libvorbis.
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: vorbis.c,v 1.4 2002/11/03 13:22:44 gbazin Exp $
+ * $Id: vorbis.c,v 1.5 2002/11/14 22:38:47 massiot Exp $
  *
  * Authors: Gildas Bazin <gbazin@netcourrier.com>
  *
@@ -74,6 +74,16 @@ typedef struct dec_thread_t
 
 } dec_thread_t;
 
+static int pi_channels_maps[6] =
+{
+    0,
+    AOUT_CHAN_CENTER,   AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
+    AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
+    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
+    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
+     | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
+};
+
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
@@ -174,7 +184,7 @@ static int RunDecoder( decoder_fifo_t * p_fifo )
     vorbis_block_init( &p_dec->vd, &p_dec->vb );
 
     p_dec->output_format.i_format = VLC_FOURCC('f','l','3','2');
-    p_dec->output_format.i_channels = p_dec->vi.channels;
+    p_dec->output_format.i_channels = pi_channels_maps[p_dec->vi.channels];
     p_dec->output_format.i_rate = p_dec->vi.rate;
 
     aout_DateInit( &p_dec->end_date, p_dec->vi.rate );
@@ -311,16 +321,16 @@ static int GetOggPacket( dec_thread_t *p_dec, ogg_packet *p_oggpacket,
 /*****************************************************************************
  * Interleave: helper function to interleave channels
  *****************************************************************************/
-static void Interleave( float *p_out, const float **pp_in, int i_channels,
+static void Interleave( float *p_out, const float **pp_in, int i_nb_channels,
                         int i_samples )
 {
     int i, j;
 
     for ( j = 0; j < i_samples; j++ )
     {
-        for ( i = 0; i < i_channels; i++ )
+        for ( i = 0; i < i_nb_channels; i++ )
         {
-            p_out[j * i_channels + i] = pp_in[i][j];
+            p_out[j * i_nb_channels + i] = pp_in[i][j];
         }
     }
 }
index 12dac6b..8196694 100644 (file)
@@ -2,7 +2,7 @@
  * rc.c : remote control stdin/stdout plugin for vlc
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: rc.c,v 1.9 2002/10/14 16:46:55 sam Exp $
+ * $Id: rc.c,v 1.10 2002/11/14 22:38:47 massiot Exp $
  *
  * Authors: Peter Surda <shurdeek@panorama.sth.ac.at>
  *
@@ -60,6 +60,9 @@ static void Run          ( intf_thread_t *p_intf );
 static int  Playlist     ( vlc_object_t *, char *, char * );
 static int  Quit         ( vlc_object_t *, char *, char * );
 static int  Intf         ( vlc_object_t *, char *, char * );
+static int  Volume       ( vlc_object_t *, char *, char * );
+static int  VolumeMove   ( vlc_object_t *, char *, char * );
+static int  AudioConfig  ( vlc_object_t *, char *, char * );
 
 /*****************************************************************************
  * Module descriptor
@@ -150,6 +153,17 @@ static void Run( intf_thread_t *p_intf )
     var_Create( p_intf, "next", VLC_VAR_COMMAND );
     var_Set( p_intf, "next", (vlc_value_t)(void*)Playlist );
 
+    var_Create( p_intf, "volume", VLC_VAR_COMMAND );
+    var_Set( p_intf, "volume", (vlc_value_t)(void*)Volume );
+    var_Create( p_intf, "volup", VLC_VAR_COMMAND );
+    var_Set( p_intf, "volup", (vlc_value_t)(void*)VolumeMove );
+    var_Create( p_intf, "voldown", VLC_VAR_COMMAND );
+    var_Set( p_intf, "voldown", (vlc_value_t)(void*)VolumeMove );
+    var_Create( p_intf, "adev", VLC_VAR_COMMAND );
+    var_Set( p_intf, "adev", (vlc_value_t)(void*)AudioConfig );
+    var_Create( p_intf, "achan", VLC_VAR_COMMAND );
+    var_Set( p_intf, "achan", (vlc_value_t)(void*)AudioConfig );
+
     while( !p_intf->b_die )
     {
         fd_set         fds;
@@ -378,6 +392,12 @@ static void Run( intf_thread_t *p_intf )
                 printf("| f  . . . . . . . . . . . . . . toggle fullscreen\n");
                 printf("| info . . .  information about the current stream\n");
                 printf("| \n");
+                printf("| volume [X] . . . . . . . .  set/get audio volume\n");
+                printf("| volup [X]  . . . . .  raise audio volume X steps\n");
+                printf("| voldown [X]  . . . .  lower audio volume X steps\n");
+                printf("| adev [X] . . . . . . . . .  set/get audio device\n");
+                printf("| achan [X]. . . . . . . .  set/get audio channels\n");
+                printf("| \n");
                 printf("| help . . . . . . . . . . . . . this help message\n");
                 printf("| quit . . . . . . . . . . . . . . . . .  quit vlc\n");
                 printf("| \n");
@@ -495,4 +515,145 @@ static int Signal( vlc_object_t *p_this, char *psz_cmd, char *psz_arg )
     return VLC_SUCCESS;
 }
 
+static int Volume( vlc_object_t *p_this, char *psz_cmd, char *psz_arg )
+{
+    aout_instance_t * p_aout;
+    int i_error;
+    p_aout = vlc_object_find( p_this, VLC_OBJECT_AOUT, FIND_ANYWHERE );
+    if ( p_aout == NULL ) return VLC_ENOOBJ;
+
+    if ( *psz_arg )
+    {
+        /* Set. */
+        audio_volume_t i_volume = atoi( psz_arg );
+        if ( i_volume > AOUT_VOLUME_MAX )
+        {
+            printf( "Volume must be in the range %d-%d\n", AOUT_VOLUME_MIN,
+                    AOUT_VOLUME_MAX );
+            i_error = VLC_EBADVAR;
+        }
+        else i_error = aout_VolumeSet( p_aout, i_volume );
+    }
+    else
+    {
+        /* Get. */
+        audio_volume_t i_volume;
+        if ( aout_VolumeGet( p_aout, &i_volume ) < 0 )
+        {
+            i_error = VLC_EGENERIC;
+        }
+        else
+        {
+            printf( "Volume is %d\n", i_volume );
+            i_error = VLC_SUCCESS;
+        }
+    }
+    vlc_object_release( (vlc_object_t *)p_aout );
+
+    return i_error;
+}
+
+static int VolumeMove( vlc_object_t * p_this, char * psz_cmd, char * psz_arg )
+{
+    aout_instance_t * p_aout;
+    audio_volume_t i_volume;
+    int i_nb_steps = atoi(psz_arg);
+    int i_error = VLC_SUCCESS;
+
+    if ( i_nb_steps <= 0 || i_nb_steps > (AOUT_VOLUME_MAX/AOUT_VOLUME_STEP) )
+    {
+        i_nb_steps = 1;
+    }
+
+    p_aout = vlc_object_find( p_this, VLC_OBJECT_AOUT, FIND_ANYWHERE );
+    if ( p_aout == NULL ) return VLC_ENOOBJ;
+
+    if ( !strcmp(psz_cmd, "volup") )
+    {
+        if ( aout_VolumeUp( p_aout, i_nb_steps, &i_volume ) < 0 )
+            i_error = VLC_EGENERIC;
+    }
+    else
+    {
+        if ( aout_VolumeDown( p_aout, i_nb_steps, &i_volume ) < 0 )
+            i_error = VLC_EGENERIC;
+    }
+    vlc_object_release( (vlc_object_t *)p_aout );
+
+    if ( !i_error ) printf( "Volume is %d\n", i_volume );
+    return i_error;
+}
+
+static int AudioConfig( vlc_object_t * p_this, char * psz_cmd, char * psz_arg )
+{
+    aout_instance_t * p_aout;
+    const char * psz_variable;
+    const char * psz_name;
+    int i_error;
+
+    p_aout = vlc_object_find( p_this, VLC_OBJECT_AOUT, FIND_ANYWHERE );
+    if ( p_aout == NULL ) return VLC_ENOOBJ;
+
+    if ( !strcmp( psz_cmd, "adev" ) )
+    {
+        psz_variable = "audio-device";
+        psz_name = "audio devices";
+    }
+    else
+    {
+        psz_variable = "audio-channels";
+        psz_name = "audio channels";
+    }
+
+    if ( !*psz_arg )
+    {
+        /* Retrieve all registered ***. */
+        vlc_value_t val;
+        int i, i_vals;
+        vlc_value_t * p_vals;
+        char * psz_value;
+
+        if ( var_Get( (vlc_object_t *)p_aout, psz_variable, &val ) < 0 )
+        {
+            vlc_object_release( (vlc_object_t *)p_aout );
+            return VLC_EGENERIC;
+        }
+        psz_value = val.psz_string;
+
+        if ( var_Change( (vlc_object_t *)p_aout, psz_variable,
+                         VLC_VAR_GETLIST, &val ) < 0 )
+        {
+            free( psz_value );
+            vlc_object_release( (vlc_object_t *)p_aout );
+            return VLC_EGENERIC;
+        }
+
+        printf( "+----[ %s ]\n", psz_name );
+        i_vals = ((vlc_value_t *)val.p_address)[0].i_int;
+        p_vals = &((vlc_value_t *)val.p_address)[1]; /* Starts at index 1 */
+        for ( i = 0; i < i_vals; i++ )
+        {
+            if ( !strcmp( psz_value, p_vals[i].psz_string ) )
+                printf( "| %s *\n", p_vals[i].psz_string );
+            else
+                printf( "| %s\n", p_vals[i].psz_string );
+        }
+        var_Change( (vlc_object_t *)p_aout, psz_variable, VLC_VAR_FREELIST,
+                    &val );
+        printf( "+----[ end of %s ]\n", psz_name );
+
+        free( psz_value );
+        i_error = VLC_SUCCESS;
+    }
+    else
+    {
+        vlc_value_t val;
+        val.psz_string = psz_arg;
+
+        i_error = var_Set( (vlc_object_t *)p_aout, psz_variable, val );
+    }
+    vlc_object_release( (vlc_object_t *)p_aout );
+
+    return i_error;
+}
 
index 2d00a7a..7ffe9d8 100644 (file)
@@ -2,7 +2,7 @@
  * aout.m: CoreAudio output plugin
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: aout.m,v 1.13 2002/10/21 20:00:09 massiot Exp $
+ * $Id: aout.m,v 1.14 2002/11/14 22:38:48 massiot Exp $
  *
  * Authors: Colin Delacroix <colin@zoy.org>
  *          Jon Lech Johansen <jon-vl@nanocrew.net>
@@ -82,7 +82,6 @@ int E_(OpenAudio)( vlc_object_t * p_this )
     UInt32 i_param_size;
     aout_instance_t * p_aout = (aout_instance_t *)p_this;
     struct aout_sys_t * p_sys;
-    msg_Dbg(p_aout, "************************* ENTER OpenAudio ****************************");
     
     /* Allocate instance */
     p_sys = p_aout->output.p_sys = malloc( sizeof( struct aout_sys_t ) );
index 1c72b97..cb03388 100644 (file)
@@ -2,7 +2,7 @@
  * ipv4.c: IPv4 network abstraction layer
  *****************************************************************************
  * Copyright (C) 2001, 2002 VideoLAN
- * $Id: ipv4.c,v 1.4 2002/10/01 22:29:08 massiot Exp $
+ * $Id: ipv4.c,v 1.5 2002/11/14 22:38:48 massiot Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *          Mathias Kretschmer <mathias@research.att.com>
@@ -249,7 +249,8 @@ static int OpenUDP( vlc_object_t * p_this, network_socket_t * p_socket )
         char * psz_if_addr = config_GetPsz( p_this, "iface-addr" );
         imr.imr_multiaddr.s_addr = inet_addr(psz_bind_addr);
 #endif
-        if ( *psz_if_addr && inet_addr(psz_if_addr) != -1 )
+        if ( psz_if_addr != NULL && *psz_if_addr
+              && inet_addr(psz_if_addr) != -1 )
         {
             imr.imr_interface.s_addr = inet_addr(psz_if_addr);
         }
@@ -257,7 +258,7 @@ static int OpenUDP( vlc_object_t * p_this, network_socket_t * p_socket )
         {
             imr.imr_interface.s_addr = INADDR_ANY;
         }
-        free( psz_if_addr );
+        if ( psz_if_addr != NULL ) free( psz_if_addr );
 
         if( setsockopt( i_handle, IPPROTO_IP, IP_ADD_MEMBERSHIP,
                         (char*)&imr, sizeof(struct ip_mreq) ) == -1 )
index b3fffe4..1004cd0 100644 (file)
@@ -2,7 +2,7 @@
  * xcommon.c: Functions common to the X11 and XVideo plugins
  *****************************************************************************
  * Copyright (C) 1998-2001 VideoLAN
- * $Id: xcommon.c,v 1.6 2002/10/17 16:48:41 sam Exp $
+ * $Id: xcommon.c,v 1.7 2002/11/14 22:38:48 massiot Exp $
  *
  * Authors: Vincent Seguin <seguin@via.ecp.fr>
  *          Samuel Hocevar <sam@zoy.org>
@@ -145,7 +145,7 @@ int E_(Activate) ( vlc_object_t *p_this )
         return VLC_ENOMEM;
     }
 
-    /* Open display, unsing the "display" config variable or the DISPLAY
+    /* Open display, using the "display" config variable or the DISPLAY
      * environment variable */
     psz_display = config_GetPsz( p_vout, MODULE_STRING "-display" );
 
index 97155f4..39990c2 100644 (file)
@@ -2,7 +2,7 @@
  * common.c : audio output management of common data structures
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: common.c,v 1.8 2002/11/13 20:51:04 sam Exp $
+ * $Id: common.c,v 1.9 2002/11/14 22:38:48 massiot Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -62,6 +62,13 @@ aout_instance_t * __aout_New( vlc_object_t * p_parent )
 
     vlc_object_attach( p_aout, p_parent->p_vlc );
 
+    var_Create( p_aout, "physical-channels", VLC_VAR_INTEGER );
+    var_AddCallback( p_aout, "physical-channels", aout_ChannelsRestart,
+                     NULL );
+    var_Create( p_aout, "original-channels", VLC_VAR_INTEGER );
+    var_AddCallback( p_aout, "original-channels", aout_ChannelsRestart,
+                     NULL );
+
     return p_aout;
 }
 
@@ -70,6 +77,8 @@ aout_instance_t * __aout_New( vlc_object_t * p_parent )
  *****************************************************************************/
 void aout_Delete( aout_instance_t * p_aout )
 {
+    var_Destroy( p_aout, "channels" );
+
     vlc_mutex_destroy( &p_aout->input_fifos_lock );
     vlc_mutex_destroy( &p_aout->mixer_lock );
     vlc_mutex_destroy( &p_aout->output_fifo_lock );
@@ -86,46 +95,20 @@ void aout_Delete( aout_instance_t * p_aout )
 /*****************************************************************************
  * aout_FormatNbChannels : return the number of channels
  *****************************************************************************/
-int aout_FormatNbChannels( audio_sample_format_t * p_format )
+int aout_FormatNbChannels( const audio_sample_format_t * p_format )
 {
-    int i_nb;
+    static const u32 pi_channels[] =
+        { AOUT_CHAN_CENTER, AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT,
+          AOUT_CHAN_REARCENTER, AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT,
+          AOUT_CHAN_LFE };
+    int i_nb = 0, i;
 
-    switch ( p_format->i_channels & AOUT_CHAN_MASK )
+    for ( i = 0; i < sizeof(pi_channels)/sizeof(u32); i++ )
     {
-    case AOUT_CHAN_CHANNEL1:
-    case AOUT_CHAN_CHANNEL2:
-    case AOUT_CHAN_MONO:
-        i_nb = 1;
-        break;
-
-    case AOUT_CHAN_CHANNEL:
-    case AOUT_CHAN_STEREO:
-    case AOUT_CHAN_DOLBY:
-        i_nb = 2;
-        break;
-
-    case AOUT_CHAN_3F:
-    case AOUT_CHAN_2F1R:
-        i_nb = 3;
-        break;
-
-    case AOUT_CHAN_3F1R:
-    case AOUT_CHAN_2F2R:
-        i_nb = 4;
-        break;
-
-    case AOUT_CHAN_3F2R:
-        i_nb = 5;
-        break;
-
-    default:
-        i_nb = 0;
+        if ( p_format->i_physical_channels & pi_channels[i] ) i_nb++;
     }
 
-    if ( p_format->i_channels & AOUT_CHAN_LFE )
-        return i_nb + 1;
-    else
-        return i_nb;
+    return i_nb;
 }
 
 /*****************************************************************************
@@ -168,34 +151,76 @@ void aout_FormatPrepare( audio_sample_format_t * p_format )
 }
 
 /*****************************************************************************
- * FormatPrintChannels : print a channel in a human-readable form
+ * aout_FormatPrintChannels : print a channel in a human-readable form
  *****************************************************************************/
-static const char * FormatPrintChannels( int i_channels )
+const char * aout_FormatPrintChannels( const audio_sample_format_t * p_format )
 {
-    switch ( i_channels )
+    switch ( p_format->i_physical_channels & AOUT_CHAN_PHYSMASK )
     {
-    case AOUT_CHAN_CHANNEL: return "CHANNEL";
-    case AOUT_CHAN_CHANNEL1: return "CHANNEL1";
-    case AOUT_CHAN_CHANNEL2: return "CHANNEL2";
-    case AOUT_CHAN_MONO: return "MONO";
-    case AOUT_CHAN_STEREO: return "STEREO";
-    case AOUT_CHAN_3F: return "3F";
-    case AOUT_CHAN_2F1R: return "2F1R";
-    case AOUT_CHAN_3F1R: return "3F1R";
-    case AOUT_CHAN_2F2R: return "2F2R";
-    case AOUT_CHAN_3F2R: return "3F2R";
-    case AOUT_CHAN_DOLBY: return "DOLBY";
-    case AOUT_CHAN_CHANNEL | AOUT_CHAN_LFE: return "CHANNEL|LFE";
-    case AOUT_CHAN_CHANNEL1 | AOUT_CHAN_LFE: return "CHANNEL1|LFE";
-    case AOUT_CHAN_CHANNEL2 | AOUT_CHAN_LFE: return "CHANNEL2|LFE";
-    case AOUT_CHAN_MONO | AOUT_CHAN_LFE: return "MONO|LFE";
-    case AOUT_CHAN_STEREO | AOUT_CHAN_LFE: return "STEREO|LFE";
-    case AOUT_CHAN_3F | AOUT_CHAN_LFE: return "3F|LFE";
-    case AOUT_CHAN_2F1R | AOUT_CHAN_LFE: return "2F1R|LFE";
-    case AOUT_CHAN_3F1R | AOUT_CHAN_LFE: return "3F1R|LFE";
-    case AOUT_CHAN_2F2R | AOUT_CHAN_LFE: return "2F2R|LFE";
-    case AOUT_CHAN_3F2R | AOUT_CHAN_LFE: return "3F2R|LFE";
-    case AOUT_CHAN_DOLBY | AOUT_CHAN_LFE: return "DOLBY|LFE";
+    case AOUT_CHAN_CENTER:
+        if ( (p_format->i_original_channels & AOUT_CHAN_CENTER)
+              || (p_format->i_original_channels
+                   & (AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT)) )
+            return "Mono";
+        else if ( p_format->i_original_channels & AOUT_CHAN_LEFT )
+            return "Left";
+        return "Right";
+    case AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT:
+        if ( p_format->i_original_channels & AOUT_CHAN_DOLBYSTEREO )
+            return "Dolby";
+        else if ( p_format->i_original_channels & AOUT_CHAN_DUALMONO )
+            return "Dual-mono";
+        else if ( !(p_format->i_original_channels & AOUT_CHAN_RIGHT) )
+            return "Stereo/Left";
+        else if ( !(p_format->i_original_channels & AOUT_CHAN_LEFT) )
+            return "Stereo/Right";
+        return "Stereo";
+    case AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER:
+        return "3F";
+    case AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARCENTER:
+        return "2F1R";
+    case AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
+          | AOUT_CHAN_REARCENTER:
+        return "3F1R";
+    case AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
+          | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT:
+        return "2F2R";
+    case AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
+          | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT:
+        return "3F2R";
+
+    case AOUT_CHAN_CENTER | AOUT_CHAN_LFE:
+        if ( (p_format->i_original_channels & AOUT_CHAN_CENTER)
+              || (p_format->i_original_channels
+                   & (AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT)) )
+            return "Mono/LFE";
+        else if ( p_format->i_original_channels & AOUT_CHAN_LEFT )
+            return "Left/LFE";
+        return "Right/LFE";
+    case AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_LFE:
+        if ( p_format->i_original_channels & AOUT_CHAN_DOLBYSTEREO )
+            return "Dolby/LFE";
+        else if ( p_format->i_original_channels & AOUT_CHAN_DUALMONO )
+            return "Dual-mono/LFE";
+        else if ( !(p_format->i_original_channels & AOUT_CHAN_RIGHT) )
+            return "Stereo/Left/LFE";
+        else if ( !(p_format->i_original_channels & AOUT_CHAN_LEFT) )
+            return "Stereo/Right/LFE";
+         return "Stereo/LFE";
+    case AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_LFE:
+        return "3F/LFE";
+    case AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARCENTER
+          | AOUT_CHAN_LFE:
+        return "2F1R/LFE";
+    case AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
+          | AOUT_CHAN_REARCENTER | AOUT_CHAN_LFE:
+        return "3F1R/LFE";
+    case AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
+          | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE:
+        return "2F2R/LFE";
+    case AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
+          | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE:
+        return "3F2R/LFE";
     }
 
     return "ERROR";
@@ -209,7 +234,7 @@ void aout_FormatPrint( aout_instance_t * p_aout, const char * psz_text,
 {
     msg_Dbg( p_aout, "%s format='%4.4s' rate=%d channels=%s", psz_text,
              (char *)&p_format->i_format, p_format->i_rate,
-             FormatPrintChannels( p_format->i_channels ) );
+             aout_FormatPrintChannels( p_format ) );
 }
 
 /*****************************************************************************
@@ -223,8 +248,8 @@ void aout_FormatsPrint( aout_instance_t * p_aout, const char * psz_text,
              psz_text,
              (char *)&p_format1->i_format, (char *)&p_format2->i_format,
              p_format1->i_rate, p_format2->i_rate,
-             FormatPrintChannels( p_format1->i_channels ),
-             FormatPrintChannels( p_format2->i_channels ) );
+             aout_FormatPrintChannels( p_format1 ),
+             aout_FormatPrintChannels( p_format2 ) );
 }
 
 
index 7824b86..6dba143 100644 (file)
@@ -2,7 +2,7 @@
  * dec.c : audio output API towards decoders
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: dec.c,v 1.1 2002/09/26 22:40:25 massiot Exp $
+ * $Id: dec.c,v 1.2 2002/11/14 22:38:48 massiot Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -80,6 +80,15 @@ static aout_input_t * DecNew( aout_instance_t * p_aout,
     {
         int i;
 
+        if ( var_Type( p_aout, "audio-device" ) >= 0 )
+        {
+            var_Destroy( p_aout, "audio-device" );
+        }
+        if ( var_Type( p_aout, "audio-channels" ) >= 0 )
+        {
+            var_Destroy( p_aout, "audio-channels" );
+        }
+
         /* Recreate the output using the new format. */
         if ( aout_OutputNew( p_aout, p_format ) < 0 )
         {
index be5f7ae..aca27b7 100644 (file)
@@ -2,7 +2,7 @@
  * filters.c : audio output filters management
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: filters.c,v 1.13 2002/11/11 22:27:00 gbazin Exp $
+ * $Id: filters.c,v 1.14 2002/11/14 22:38:48 massiot Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -83,7 +83,10 @@ static int SplitConversion( aout_instance_t * p_aout,
              (p_input_format->i_format != p_output_format->i_format);
     vlc_bool_t b_rate = (p_input_format->i_rate != p_output_format->i_rate);
     vlc_bool_t b_channels =
-             (p_input_format->i_channels != p_output_format->i_channels);
+        (p_input_format->i_physical_channels
+          != p_output_format->i_physical_channels)
+     || (p_input_format->i_original_channels
+          != p_output_format->i_original_channels);
     int i_nb_conversions = b_format + b_rate + b_channels;
 
     if ( i_nb_conversions <= 1 ) return 0;
@@ -99,7 +102,10 @@ static int SplitConversion( aout_instance_t * p_aout,
         }
 
         /* !b_rate */
-        p_middle_format->i_channels = p_input_format->i_channels;
+        p_middle_format->i_physical_channels
+             = p_input_format->i_physical_channels;
+        p_middle_format->i_original_channels
+             = p_input_format->i_original_channels;
         return 1;
     }
 
index 9e1914c..6ddc1fe 100644 (file)
@@ -2,7 +2,7 @@
  * intf.c : audio output API towards the interface modules
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: intf.c,v 1.7 2002/11/14 14:08:01 gbazin Exp $
+ * $Id: intf.c,v 1.8 2002/11/14 22:38:48 massiot Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -103,7 +103,7 @@ int aout_VolumeSet( aout_instance_t * p_aout, audio_volume_t i_volume )
 }
 
 /*****************************************************************************
- * aout_VolumeInfos : get the boundaries pi_low_soft and pi_high_soft
+ * aout_VolumeInfos : get the boundary pi_soft
  *****************************************************************************/
 int aout_VolumeInfos( aout_instance_t * p_aout, audio_volume_t * pi_soft )
 {
@@ -323,6 +323,7 @@ int aout_Restart( aout_instance_t * p_aout )
 
     /* Re-open the output plug-in. */
     aout_OutputDelete( p_aout );
+
     if ( aout_OutputNew( p_aout, &p_aout->pp_inputs[0]->input ) == -1 )
     {
         /* Release all locks and report the error. */
@@ -361,6 +362,10 @@ int aout_Restart( aout_instance_t * p_aout )
 
 /*****************************************************************************
  * aout_FindAndRestart : find the audio output instance and restart
+ *****************************************************************************
+ * This is used for callbacks of the configuration variables, and we believe
+ * that when those are changed, it is a significant change which implies
+ * rebuilding the audio-device and audio-channels variables.
  *****************************************************************************/
 void aout_FindAndRestart( vlc_object_t * p_this )
 {
@@ -369,6 +374,37 @@ void aout_FindAndRestart( vlc_object_t * p_this )
 
     if ( p_aout == NULL ) return;
 
+    if ( var_Type( p_aout, "audio-device" ) >= 0 )
+    {
+        var_Destroy( p_aout, "audio-device" );
+    }
+    if ( var_Type( p_aout, "audio-channels" ) >= 0 )
+    {
+        var_Destroy( p_aout, "audio-channels" );
+    }
+
     aout_Restart( p_aout );
     vlc_object_release( p_aout );
 }
+
+/*****************************************************************************
+ * aout_ChannelsRestart : change the audio device or channels and restart
+ *****************************************************************************/
+int aout_ChannelsRestart( vlc_object_t * p_this, const char * psz_variable,
+                          vlc_value_t old_value, vlc_value_t new_value,
+                          void * unused )
+{
+    aout_instance_t * p_aout = (aout_instance_t *)p_this;
+
+    if ( !strcmp( psz_variable, "audio-device" ) )
+    {
+        /* This is supposed to be a significant change and supposes
+         * rebuilding the channel choices. */
+        if ( var_Type( p_aout, "audio-channels" ) >= 0 )
+        {
+            var_Destroy( p_aout, "audio-channels" );
+        }
+    }
+    aout_Restart( p_aout );
+    return 0;
+}
index fd0204e..025338c 100644 (file)
@@ -2,7 +2,7 @@
  * output.c : internal management of output streams for the audio output
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: output.c,v 1.23 2002/11/10 14:31:46 gbazin Exp $
+ * $Id: output.c,v 1.24 2002/11/14 22:38:48 massiot Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -43,29 +43,10 @@ int aout_OutputNew( aout_instance_t * p_aout,
     /* Retrieve user defaults. */
     char * psz_name = config_GetPsz( p_aout, "aout" );
     int i_rate = config_GetInt( p_aout, "aout-rate" );
-    int i_channels = config_GetInt( p_aout, "aout-channels" );
 
     memcpy( &p_aout->output.output, p_format, sizeof(audio_sample_format_t) );
-    if ( i_rate != -1 ) p_aout->output.output.i_rate = i_rate;
-    if ( i_channels != -1 ) p_aout->output.output.i_channels = i_channels;
-    if ( AOUT_FMT_NON_LINEAR(&p_aout->output.output) )
-    {
-        p_aout->output.output.i_format = VLC_FOURCC('s','p','d','i');
-    }
-    else
-    {
-        /* Non-S/PDIF mixer only deals with float32 or fixed32. */
-        p_aout->output.output.i_format
-                     = (p_aout->p_libvlc->i_cpu & CPU_CAPABILITY_FPU) ?
-                        VLC_FOURCC('f','l','3','2') :
-                        VLC_FOURCC('f','i','3','2');
-
-        if ( p_aout->output.output.i_channels == AOUT_CHAN_DOLBY )
-        {
-            /* Do not do Dolby surround unless the user requests it. */
-            p_aout->output.output.i_channels = AOUT_CHAN_STEREO;
-        }
-    }
+    if ( i_rate != -1 )
+        p_aout->output.output.i_rate = i_rate;
     aout_FormatPrepare( &p_aout->output.output );
 
     vlc_mutex_lock( &p_aout->output_fifo_lock );
@@ -80,6 +61,80 @@ int aout_OutputNew( aout_instance_t * p_aout,
         vlc_mutex_unlock( &p_aout->output_fifo_lock );
         return -1;
     }
+
+    if ( var_Type( p_aout, "audio-channels" ) ==
+             (VLC_VAR_STRING | VLC_VAR_ISLIST) )
+    {
+        /* The user may have selected a different channels configuration. */
+        vlc_value_t val;
+        var_Get( p_aout, "audio-channels", &val );
+
+        if ( !strcmp( val.psz_string, N_("Both") ) )
+        {
+            p_aout->output.output.i_original_channels =
+                AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
+        }
+        else if ( !strcmp( val.psz_string, N_("Left") ) )
+        {
+            p_aout->output.output.i_original_channels = AOUT_CHAN_LEFT;
+        }
+        else if ( !strcmp( val.psz_string, N_("Right") ) )
+        {
+            p_aout->output.output.i_original_channels = AOUT_CHAN_RIGHT;
+        }
+        else if ( !strcmp( val.psz_string, N_("Dolby Surround") ) )
+        {
+            p_aout->output.output.i_original_channels
+                = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_DOLBYSTEREO;
+        }
+        free( val.psz_string );
+    }
+    else if ( p_aout->output.output.i_physical_channels == AOUT_CHAN_CENTER )
+    {
+        /* Mono - create the audio-channels variable. */
+        vlc_value_t val;
+        var_Create( p_aout, "audio-channels", VLC_VAR_STRING | VLC_VAR_ISLIST );
+        if ( p_aout->output.output.i_original_channels & AOUT_CHAN_DUALMONO )
+        {
+            /* Go directly to the left channel. */
+            p_aout->output.output.i_original_channels = AOUT_CHAN_LEFT;
+        }
+        else
+        {
+            val.psz_string = N_("Both");
+            var_Change( p_aout, "audio-channels", VLC_VAR_ADDCHOICE, &val );
+        }
+        val.psz_string = N_("Left");
+        var_Change( p_aout, "audio-channels", VLC_VAR_ADDCHOICE, &val );
+        val.psz_string = N_("Right");
+        var_Change( p_aout, "audio-channels", VLC_VAR_ADDCHOICE, &val );
+        var_AddCallback( p_aout, "audio-channels", aout_ChannelsRestart,
+                         NULL );
+    }
+    else if ( p_aout->output.output.i_physical_channels == 
+                 (AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT)
+              && p_aout->output.output.i_original_channels == 
+                 (AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT) )
+    {
+        /* Stereo - create the audio-channels variable. */
+        vlc_value_t val;
+        var_Create( p_aout, "audio-channels", VLC_VAR_STRING | VLC_VAR_ISLIST );
+        val.psz_string = N_("Both");
+        var_Change( p_aout, "audio-channels", VLC_VAR_ADDCHOICE, &val );
+        val.psz_string = N_("Left");
+        var_Change( p_aout, "audio-channels", VLC_VAR_ADDCHOICE, &val );
+        val.psz_string = N_("Right");
+        var_Change( p_aout, "audio-channels", VLC_VAR_ADDCHOICE, &val );
+        if ( p_aout->output.output.i_original_channels & AOUT_CHAN_DOLBYSTEREO )
+        {
+            val.psz_string = N_("Dolby Surround");
+            var_Change( p_aout, "audio-channels", VLC_VAR_ADDCHOICE, &val );
+        }
+        p_aout->output.output.i_original_channels &= ~AOUT_CHAN_DOLBYSTEREO;
+        var_AddCallback( p_aout, "audio-channels", aout_ChannelsRestart,
+                         NULL );
+    }
+
     aout_FormatPrepare( &p_aout->output.output );
 
     /* Prepare FIFO. */