Commit 8928554e authored by Christophe Massiot's avatar Christophe Massiot

Major change of the channels management. p_format->i_channels disappeares

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.
parent f5bc3cd8
...@@ -1755,7 +1755,7 @@ if test "x${enable_oss}" != "xno" && ...@@ -1755,7 +1755,7 @@ if test "x${enable_oss}" != "xno" &&
(test "x${SYS}" != "xmingw32" || test "x${enable_oss}" = "xyes") (test "x${SYS}" != "xmingw32" || test "x${enable_oss}" = "xyes")
then then
AC_CHECK_HEADERS(soundcard.h sys/soundcard.h machine/soundcard.h, [ 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") AC_CHECK_LIB(ossaudio,main,LDFLAGS_oss="${LDFLAGS_oss} -lossaudio")
]) ])
fi fi
...@@ -1770,7 +1770,7 @@ AC_ARG_ENABLE(esd, ...@@ -1770,7 +1770,7 @@ AC_ARG_ENABLE(esd,
AC_PATH_PROG(ESD_CONFIG, esd-config, no) AC_PATH_PROG(ESD_CONFIG, esd-config, no)
if test "x${ESD_CONFIG}" != "xno" if test "x${ESD_CONFIG}" != "xno"
then then
PLUGINS="${PLUGINS} esd" #PLUGINS="${PLUGINS} esd"
CFLAGS_esd="${CFLAGS_esd} `${ESD_CONFIG} --cflags`" CFLAGS_esd="${CFLAGS_esd} `${ESD_CONFIG} --cflags`"
LDFLAGS_esd="${LDFLAGS_esd} `${ESD_CONFIG} --libs`" LDFLAGS_esd="${LDFLAGS_esd} `${ESD_CONFIG} --libs`"
fi fi
...@@ -1786,7 +1786,7 @@ AC_ARG_ENABLE(arts, ...@@ -1786,7 +1786,7 @@ AC_ARG_ENABLE(arts,
AC_PATH_PROG(ARTS_CONFIG, artsc-config, no) AC_PATH_PROG(ARTS_CONFIG, artsc-config, no)
if test "x${ARTS_CONFIG}" != "xno" if test "x${ARTS_CONFIG}" != "xno"
then then
PLUGINS="${PLUGINS} arts" #PLUGINS="${PLUGINS} arts"
CFLAGS_arts="${CFLAGS_arts} `${ARTS_CONFIG} --cflags`" CFLAGS_arts="${CFLAGS_arts} `${ARTS_CONFIG} --cflags`"
LDFLAGS_arts="${LDFLAGS_arts} `${ARTS_CONFIG} --libs `" LDFLAGS_arts="${LDFLAGS_arts} `${ARTS_CONFIG} --libs `"
fi fi
...@@ -1802,7 +1802,7 @@ AC_ARG_ENABLE(alsa, ...@@ -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") 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" if test "x${have_alsa}" = "xtrue"
then then
PLUGINS="${PLUGINS} alsa" #PLUGINS="${PLUGINS} alsa"
LDFLAGS_alsa="${LDFLAGS_alsa} -lasound -lm -ldl" LDFLAGS_alsa="${LDFLAGS_alsa} -lasound -lm -ldl"
fi fi
fi]) fi])
...@@ -1814,7 +1814,7 @@ AC_ARG_ENABLE(waveout, ...@@ -1814,7 +1814,7 @@ AC_ARG_ENABLE(waveout,
[ --enable-waveout Win32 waveOut module (default enabled on Win32)]) [ --enable-waveout Win32 waveOut module (default enabled on Win32)])
if test "x${enable_waveout}" != "xno"; then if test "x${enable_waveout}" != "xno"; then
if test "x${SYS}" = "xmingw32" -o "x${SYS}" = "xcygwin"; then if test "x${SYS}" = "xmingw32" -o "x${SYS}" = "xcygwin"; then
PLUGINS="${PLUGINS} waveout" #PLUGINS="${PLUGINS} waveout"
LDFLAGS_waveout="-lwinmm" LDFLAGS_waveout="-lwinmm"
fi fi
fi fi
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* aout_internal.h : internal defines for audio output * aout_internal.h : internal defines for audio output
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * 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> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -275,10 +275,11 @@ void aout_OutputDelete( aout_instance_t * p_aout ); ...@@ -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 ) ); VLC_EXPORT( aout_buffer_t *, aout_OutputNextBuffer, ( aout_instance_t *, mtime_t, vlc_bool_t ) );
/* From common.c : */ /* 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_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_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( 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 ); void aout_FifoInit( aout_instance_t *, aout_fifo_t *, uint32_t );
mtime_t aout_FifoNextStart( aout_instance_t *, aout_fifo_t * ); mtime_t aout_FifoNextStart( aout_instance_t *, aout_fifo_t * );
void aout_FifoPush( aout_instance_t *, aout_fifo_t *, aout_buffer_t * ); void aout_FifoPush( aout_instance_t *, aout_fifo_t *, aout_buffer_t * );
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* audio_output.h : audio output interface * audio_output.h : audio output interface
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * 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> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -28,12 +28,17 @@ ...@@ -28,12 +28,17 @@
*****************************************************************************/ *****************************************************************************/
struct audio_sample_format_t struct audio_sample_format_t
{ {
int i_format; vlc_fourcc_t i_format;
int i_rate; unsigned int i_rate;
int i_channels; /* 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 */ /* Optional - for A52, SPDIF and DTS types */
int i_bytes_per_frame; unsigned int i_bytes_per_frame;
int i_frame_length; unsigned int i_frame_length;
/* Please note that it may be completely arbitrary - buffers are not /* Please note that it may be completely arbitrary - buffers are not
* obliged to contain a integral number of so-called "frames". It's * obliged to contain a integral number of so-called "frames". It's
* just here for the division : * just here for the division :
...@@ -43,14 +48,14 @@ struct audio_sample_format_t ...@@ -43,14 +48,14 @@ struct audio_sample_format_t
#define AOUT_FMTS_IDENTICAL( p_first, p_second ) ( \ #define AOUT_FMTS_IDENTICAL( p_first, p_second ) ( \
((p_first)->i_format == (p_second)->i_format) \ ((p_first)->i_format == (p_second)->i_format) \
&& ((p_first)->i_rate == (p_second)->i_rate) \ && ((p_first)->i_rate == (p_second)->i_rate) \
&& ((p_first)->i_channels == (p_second)->i_channels \ && ((p_first)->i_physical_channels == (p_second)->i_physical_channels)\
|| (p_first)->i_channels == -1 || (p_second)->i_channels == -1) ) && ((p_first)->i_original_channels == (p_second)->i_original_channels) )
/* Check if i_rate == i_rate and i_channels == i_channels */ /* Check if i_rate == i_rate and i_channels == i_channels */
#define AOUT_FMTS_SIMILAR( p_first, p_second ) ( \ #define AOUT_FMTS_SIMILAR( p_first, p_second ) ( \
((p_first)->i_rate == (p_second)->i_rate) \ ((p_first)->i_rate == (p_second)->i_rate) \
&& ((p_first)->i_channels == (p_second)->i_channels \ && ((p_first)->i_physical_channels == (p_second)->i_physical_channels)\
|| (p_first)->i_channels == -1 || (p_second)->i_channels == -1) ) && ((p_first)->i_original_channels == (p_second)->i_original_channels) )
#ifdef WORDS_BIGENDIAN #ifdef WORDS_BIGENDIAN
# define AOUT_FMT_S16_NE VLC_FOURCC('s','1','6','b') # define AOUT_FMT_S16_NE VLC_FOURCC('s','1','6','b')
...@@ -92,33 +97,24 @@ typedef int32_t vlc_fixed_t; ...@@ -92,33 +97,24 @@ typedef int32_t vlc_fixed_t;
#define FIXED32_ONE ((vlc_fixed_t) 0x10000000) #define FIXED32_ONE ((vlc_fixed_t) 0x10000000)
/* Dual mono. Two independant mono channels */ /*
#define AOUT_CHAN_CHANNEL 0x0000000B * Channels descriptions
#define AOUT_CHAN_MONO 0x00000001 */
#define AOUT_CHAN_STEREO 0x00000002
/* 3 front channels (left, center, right) */ /* Values available for physical and original channels */
#define AOUT_CHAN_3F 0x00000003 #define AOUT_CHAN_CENTER 0x1
/* 2 front, 1 rear surround channels (L, R, S) */ #define AOUT_CHAN_LEFT 0x2
#define AOUT_CHAN_2F1R 0x00000004 #define AOUT_CHAN_RIGHT 0x4
/* 3 front, 1 rear surround channels (L, C, R, S) */ #define AOUT_CHAN_REARCENTER 0x10
#define AOUT_CHAN_3F1R 0x00000005 #define AOUT_CHAN_REARLEFT 0x20
/* 2 front, 2 rear surround channels (L, R, LS, RS) */ #define AOUT_CHAN_REARRIGHT 0x40
#define AOUT_CHAN_2F2R 0x00000006 #define AOUT_CHAN_LFE 0x100
/* 3 front, 2 rear surround channels (L, C, R, LS, RS) */
#define AOUT_CHAN_3F2R 0x00000007 /* Values available for original channels only */
/* First of two mono channels */ #define AOUT_CHAN_DOLBYSTEREO 0x10000
#define AOUT_CHAN_CHANNEL1 0x00000008 #define AOUT_CHAN_DUALMONO 0x20000
/* Second of two mono channels */
#define AOUT_CHAN_CHANNEL2 0x00000009 #define AOUT_CHAN_PHYSMASK 0xFFFF
/* 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
/***************************************************************************** /*****************************************************************************
...@@ -140,6 +136,9 @@ struct aout_buffer_t ...@@ -140,6 +136,9 @@ struct aout_buffer_t
/* Size of a frame for S/PDIF output. */ /* Size of a frame for S/PDIF output. */
#define AOUT_SPDIF_SIZE 6144 #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 * 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 * ) ); ...@@ -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_VolumeDown, ( aout_instance_t *, int, audio_volume_t * ) );
VLC_EXPORT( int, aout_Restart, ( aout_instance_t * p_aout ) ); VLC_EXPORT( int, aout_Restart, ( aout_instance_t * p_aout ) );
VLC_EXPORT( void, aout_FindAndRestart, ( vlc_object_t * p_this ) ); 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 * ) );
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* trivial.c : trivial channel mixer plug-in (drops unwanted channels) * trivial.c : trivial channel mixer plug-in (drops unwanted channels)
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * 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> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -56,7 +56,10 @@ static int Create( vlc_object_t *p_this ) ...@@ -56,7 +56,10 @@ static int Create( vlc_object_t *p_this )
{ {
aout_filter_t * p_filter = (aout_filter_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_format != p_filter->output.i_format
|| p_filter->input.i_rate != p_filter->output.i_rate || p_filter->input.i_rate != p_filter->output.i_rate
|| (p_filter->input.i_format != VLC_FOURCC('f','l','3','2') || (p_filter->input.i_format != VLC_FOURCC('f','l','3','2')
...@@ -66,7 +69,8 @@ static int Create( vlc_object_t *p_this ) ...@@ -66,7 +69,8 @@ static int Create( vlc_object_t *p_this )
} }
p_filter->pf_do_work = DoWork; 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 */ /* Downmixing */
p_filter->b_in_place = 1; p_filter->b_in_place = 1;
...@@ -109,11 +113,43 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter, ...@@ -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 ); int i_output_nb = aout_FormatNbChannels( &p_filter->output );
s32 * p_dest = (s32 *)p_out_buf->p_buffer; s32 * p_dest = (s32 *)p_out_buf->p_buffer;
s32 * p_src = (s32 *)p_in_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, if ( p_filter->output.i_original_channels & AOUT_CHAN_DUALMONO )
i_input_nb ); {
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_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; p_out_buf->i_nb_bytes = p_in_buf->i_nb_bytes * i_output_nb / i_input_nb;
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* (http://liba52.sf.net/). * (http://liba52.sf.net/).
***************************************************************************** *****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN * 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> * Authors: Gildas Bazin <gbazin@netcourrier.com>
* Christophe Massiot <massiot@via.ecp.fr> * Christophe Massiot <massiot@via.ecp.fr>
...@@ -119,25 +119,78 @@ static int Create( vlc_object_t * _p_filter ) ...@@ -119,25 +119,78 @@ static int Create( vlc_object_t * _p_filter )
/* We'll do our own downmixing, thanks. */ /* We'll do our own downmixing, thanks. */
p_sys->i_nb_channels = aout_FormatNbChannels( &p_filter->output ); 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_CENTER:
case AOUT_CHAN_CHANNEL1: p_sys->i_flags = A52_CHANNEL1; break; if ( (p_filter->output.i_original_channels & AOUT_CHAN_CENTER)
case AOUT_CHAN_CHANNEL2: p_sys->i_flags = A52_CHANNEL2; break; || (p_filter->output.i_original_channels
case AOUT_CHAN_MONO: p_sys->i_flags = A52_MONO; break; & (AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT)) )
case AOUT_CHAN_STEREO: p_sys->i_flags = A52_STEREO; break; {
case AOUT_CHAN_DOLBY: p_sys->i_flags = A52_DOLBY; break; p_sys->i_flags = A52_MONO;
case AOUT_CHAN_3F: p_sys->i_flags = A52_3F; break; }
case AOUT_CHAN_2F1R: p_sys->i_flags = A52_2F1R; break; else if ( p_filter->output.i_original_channels & AOUT_CHAN_LEFT )
case AOUT_CHAN_3F1R: p_sys->i_flags = A52_3F1R; break; {
case AOUT_CHAN_2F2R: p_sys->i_flags = A52_2F2R; break; p_sys->i_flags = A52_CHANNEL1;
case AOUT_CHAN_3F2R: p_sys->i_flags = A52_3F2R; break; }
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: default:
msg_Err( p_filter, "unknow sample format !" ); msg_Err( p_filter, "unknow sample format !" );
free( p_sys ); free( p_sys );
return -1; 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; p_sys->i_flags |= A52_LFE;
} }
...@@ -160,19 +213,34 @@ static int Create( vlc_object_t * _p_filter ) ...@@ -160,19 +213,34 @@ static int Create( vlc_object_t * _p_filter )
/***************************************************************************** /*****************************************************************************
* Interleave: helper function to interleave channels * 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; int i, j;
for ( j = 0; j < i_channels; j++ ) for ( j = 0; j < i_nb_channels; j++ )
{ {
for ( i = 0; i < 256; i++ ) 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. * DoWork: decode an ATSC A/52 frame.
*****************************************************************************/ *****************************************************************************/
...@@ -221,9 +289,20 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter, ...@@ -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 ); p_samples = a52_samples( p_sys->p_liba52 );
/* Interleave the *$% samples. */ if ( ((p_sys->i_flags & A52_CHANNEL1) || (p_sys->i_flags & A52_CHANNEL2)
Interleave( (float *)(p_out_buf->p_buffer + i * i_bytes_per_block), || (p_sys->i_flags & A52_MONO))
p_samples, p_sys->i_nb_channels ); && (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; p_out_buf->i_nb_samples = p_in_buf->i_nb_samples;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* trivial.c : trivial resampler (skips samples or pads with zeroes) * trivial.c : trivial resampler (skips samples or pads with zeroes)
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * 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> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -58,7 +58,10 @@ static int Create( vlc_object_t *p_this ) ...@@ -58,7 +58,10 @@ static int Create( vlc_object_t *p_this )
if ( p_filter->input.i_rate == p_filter->output.i_rate 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_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','l','3','2')
&& p_filter->input.i_format != VLC_FOURCC('f','i','3','2')) ) && p_filter->input.i_format != VLC_FOURCC('f','i','3','2')) )
{ {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ugly.c : ugly resampler (changes pitch) * ugly.c : ugly resampler (changes pitch)
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * 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> * Authors: Samuel Hocevar <sam@zoy.org>
* *
...@@ -58,7 +58,10 @@ static int Create( vlc_object_t *p_this ) ...@@ -58,7 +58,10 @@ static int Create( vlc_object_t *p_this )
if ( p_filter->input.i_rate == p_filter->output.i_rate 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_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','l','3','2')
&& p_filter->input.i_format != VLC_FOURCC('f','i','3','2')) ) && p_filter->input.i_format != VLC_FOURCC('f','i','3','2')) )
{ {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* float32.c : precise float32 audio mixer implementation * float32.c : precise float32 audio mixer implementation
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * 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 $
* *