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++;
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, SparseCopy( p_dest, p_src, p_in_buf->i_nb_samples, i_output_nb,
i_input_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_CHANNEL1: p_sys->i_flags = A52_CHANNEL1; break; case AOUT_CHAN_CENTER:
case AOUT_CHAN_CHANNEL2: p_sys->i_flags = A52_CHANNEL2; break; if ( (p_filter->output.i_original_channels & AOUT_CHAN_CENTER)
case AOUT_CHAN_MONO: p_sys->i_flags = A52_MONO; break; || (p_filter->output.i_original_channels
case AOUT_CHAN_STEREO: p_sys->i_flags = A52_STEREO; break; & (AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT)) )
case AOUT_CHAN_DOLBY: p_sys->i_flags = A52_DOLBY; break; {
case AOUT_CHAN_3F: p_sys->i_flags = A52_3F; break; p_sys->i_flags = A52_MONO;
case AOUT_CHAN_2F1R: p_sys->i_flags = A52_2F1R; break; }
case AOUT_CHAN_3F1R: p_sys->i_flags = A52_3F1R; break; else if ( p_filter->output.i_original_channels & AOUT_CHAN_LEFT )
case AOUT_CHAN_2F2R: p_sys->i_flags = A52_2F2R; break; {
case AOUT_CHAN_3F2R: p_sys->i_flags = A52_3F2R; break; 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: 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,10 +289,21 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter, ...@@ -221,10 +289,21 @@ 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 );
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 the *$% samples. */
Interleave( (float *)(p_out_buf->p_buffer + i * i_bytes_per_block), Interleave( (float *)(p_out_buf->p_buffer + i * i_bytes_per_block),
p_samples, p_sys->i_nb_channels ); 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;
p_out_buf->i_nb_bytes = i_bytes_per_block * 6; p_out_buf->i_nb_bytes = i_bytes_per_block * 6;
......
...@@ -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 $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -49,7 +49,7 @@ vlc_module_begin(); ...@@ -49,7 +49,7 @@ vlc_module_begin();
vlc_module_end(); vlc_module_end();
/***************************************************************************** /*****************************************************************************
* Create: allocate trivial mixer * Create: allocate mixer
*****************************************************************************/ *****************************************************************************/
static int Create( vlc_object_t *p_this ) static int Create( vlc_object_t *p_this )
{ {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* oss.c : OSS /dev/dsp module for vlc * oss.c : OSS /dev/dsp module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2000-2002 VideoLAN * 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> * Authors: Michel Kaempf <maxx@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org> * Samuel Hocevar <sam@zoy.org>
...@@ -70,7 +70,6 @@ struct aout_sys_t ...@@ -70,7 +70,6 @@ struct aout_sys_t
/* This must be a power of 2. */ /* This must be a power of 2. */
#define FRAME_SIZE 1024 #define FRAME_SIZE 1024
#define FRAME_COUNT 4 #define FRAME_COUNT 4
#define A52_FRAME_NB 1536
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
...@@ -103,6 +102,111 @@ vlc_module_begin(); ...@@ -103,6 +102,111 @@ vlc_module_begin();
set_callbacks( Open, Close ); set_callbacks( Open, Close );
vlc_module_end(); 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) * Open: open the audio device (the digital sound processor)
***************************************************************************** *****************************************************************************
...@@ -114,6 +218,7 @@ static int Open( vlc_object_t *p_this ) ...@@ -114,6 +218,7 @@ static int Open( vlc_object_t *p_this )
aout_instance_t * p_aout = (aout_instance_t *)p_this; aout_instance_t * p_aout = (aout_instance_t *)p_this;
struct aout_sys_t * p_sys; struct aout_sys_t * p_sys;
char * psz_device; char * psz_device;
vlc_value_t val;
/* Allocate structure */ /* Allocate structure */
p_aout->output.p_sys = p_sys = malloc( sizeof( aout_sys_t ) ); p_aout->output.p_sys = p_sys = malloc( sizeof( aout_sys_t ) );
...@@ -143,6 +248,50 @@ static int Open( vlc_object_t *p_this ) ...@@ -143,6 +248,50 @@ static int Open( vlc_object_t *p_this )
p_aout->output.pf_play = Play; 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 */ /* Reset the DSP device */
if( ioctl( p_sys->i_fd, SNDCTL_DSP_RESET, NULL ) < 0 ) if( ioctl( p_sys->i_fd, SNDCTL_DSP_RESET, NULL ) < 0 )
{ {
...@@ -160,10 +309,12 @@ static int Open( vlc_object_t *p_this ) ...@@ -160,10 +309,12 @@ static int Open( vlc_object_t *p_this )
if( ioctl( p_sys->i_fd, SNDCTL_DSP_SETFMT, &i_format ) < 0 if( ioctl( p_sys->i_fd, SNDCTL_DSP_SETFMT, &i_format ) < 0
|| i_format != AFMT_AC3 ) || 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.output.i_format = VLC_FOURCC('s','p','d','i');
p_aout->output.i_nb_samples = A52_FRAME_NB; 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_bytes_per_frame = AOUT_SPDIF_SIZE;
...@@ -171,7 +322,6 @@ static int Open( vlc_object_t *p_this ) ...@@ -171,7 +322,6 @@ static int Open( vlc_object_t *p_this )
aout_VolumeNoneInit( p_aout ); aout_VolumeNoneInit( p_aout );
} }
}
if ( !AOUT_FMT_NON_LINEAR( &p_aout->output.output ) ) if ( !AOUT_FMT_NON_LINEAR( &p_aout->output.output ) )
{ {
...@@ -217,100 +367,19 @@ static int Open( vlc_object_t *p_this ) ...@@ -217,100 +367,19 @@ static int Open( vlc_object_t *p_this )
return VLC_EGENERIC; 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 ); 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 */ /* 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)", msg_Err( p_aout, "cannot set number of audio channels (%x)",
p_aout->output.output.i_channels ); aout_FormatPrintChannels( &p_aout->output.output) );
close( p_sys->i_fd ); close( p_sys->i_fd );
free( p_sys ); free( p_sys );
return VLC_EGENERIC; 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 */ /* Set the output rate */
i_rate = p_aout->output.output.i_rate; i_rate = p_aout->output.output.i_rate;
if( ioctl( p_sys->i_fd, SNDCTL_DSP_SPEED, &i_rate ) < 0 ) if( ioctl( p_sys->i_fd, SNDCTL_DSP_SPEED, &i_rate ) < 0 )
...@@ -346,7 +415,7 @@ static int Open( vlc_object_t *p_this ) ...@@ -346,7 +415,7 @@ static int Open( vlc_object_t *p_this )
if( ioctl( p_sys->i_fd, SNDCTL_DSP_GETOSPACE, &audio_buf ) < 0 ) 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 ); close( p_sys->i_fd );
free( p_sys ); free( p_sys );
return VLC_EGENERIC; return VLC_EGENERIC;
...@@ -370,6 +439,9 @@ static int Open( vlc_object_t *p_this ) ...@@ -370,6 +439,9 @@ static int Open( vlc_object_t *p_this )
aout_VolumeSoftInit( p_aout ); 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. */ /* Create OSS thread and wait for its readiness. */
if( vlc_thread_create( p_aout, "aout", OSSThread, if( vlc_thread_create( p_aout, "aout", OSSThread,
VLC_THREAD_PRIORITY_OUTPUT, VLC_FALSE ) ) VLC_THREAD_PRIORITY_OUTPUT, VLC_FALSE ) )
...@@ -380,9 +452,6 @@ static int Open( vlc_object_t *p_this ) ...@@ -380,9 +452,6 @@ static int Open( vlc_object_t *p_this )
return VLC_ETHREAD; return VLC_ETHREAD;
} }
p_aout->output.p_sys->b_workaround_buggy_driver =
config_GetInt( p_aout, "oss-buggy" );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* sdl.c : SDL audio output plugin for vlc * sdl.c : SDL audio output plugin for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2000-2002 VideoLAN * 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> * Authors: Michel Kaempf <maxx@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org> * Samuel Hocevar <sam@zoy.org>
...@@ -59,7 +59,7 @@ struct aout_sys_t ...@@ -59,7 +59,7 @@ struct aout_sys_t
static int Open ( vlc_object_t * ); static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * ); static void Close ( vlc_object_t * );
static void Play ( aout_instance_t * ); static void Play ( aout_instance_t * );
static void SDLCallback ( void *, Uint8 *, int ); static void SDLCallback ( void *, byte_t *, int );
/***************************************************************************** /*****************************************************************************
* Module descriptor * Module descriptor
...@@ -104,12 +104,31 @@ static int Open ( vlc_object_t *p_this ) ...@@ -104,12 +104,31 @@ static int Open ( vlc_object_t *p_this )
return VLC_EGENERIC; 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 ); i_nb_channels = aout_FormatNbChannels( &p_aout->output.output );
if ( i_nb_channels > 2 ) if ( i_nb_channels > 2 )
{ {
/* SDL doesn't support more than two channels. */ /* SDL doesn't support more than two channels. */
i_nb_channels = 2; 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.freq = p_aout->output.output.i_rate;
desired.format = AUDIO_S16SYS; desired.format = AUDIO_S16SYS;
...@@ -147,10 +166,44 @@ static int Open ( vlc_object_t *p_this ) ...@@ -147,10 +166,44 @@ static int Open ( vlc_object_t *p_this )
if ( obtained.channels != i_nb_channels ) if ( obtained.channels != i_nb_channels )
{ {
p_aout->output.output.i_channels = (obtained.channels == 2 ? p_aout->output.output.i_physical_channels = (obtained.channels == 2 ?
AOUT_CHAN_STEREO : AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT :
AOUT_CHAN_MONO); 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.output.i_rate = obtained.freq;
p_aout->output.i_nb_samples = obtained.samples; p_aout->output.i_nb_samples = obtained.samples;
p_aout->output.pf_play = Play; p_aout->output.pf_play = Play;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* a52.c: A/52 basic parser * a52.c: A/52 basic parser
***************************************************************************** *****************************************************************************
* Copyright (C) 2001-2002 VideoLAN * 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: Stphane Borel <stef@via.ecp.fr> * Authors: Stphane Borel <stef@via.ecp.fr>
* Christophe Massiot <massiot@via.ecp.fr> * Christophe Massiot <massiot@via.ecp.fr>
...@@ -40,8 +40,6 @@ ...@@ -40,8 +40,6 @@
# include <unistd.h> # include <unistd.h>
#endif #endif
#define A52_FRAME_NB 1536
/***************************************************************************** /*****************************************************************************
* dec_thread_t : A52 pass-through thread descriptor * dec_thread_t : A52 pass-through thread descriptor
*****************************************************************************/ *****************************************************************************/
...@@ -142,7 +140,7 @@ static int RunDecoder( decoder_fifo_t *p_fifo ) ...@@ -142,7 +140,7 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
/* decoder thread's main loop */ /* decoder thread's main loop */
while ( !p_dec->p_fifo->b_die && !p_dec->p_fifo->b_error ) 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; mtime_t pts;
byte_t p_header[7]; byte_t p_header[7];
aout_buffer_t * p_buffer; aout_buffer_t * p_buffer;
...@@ -167,7 +165,7 @@ static int RunDecoder( decoder_fifo_t *p_fifo ) ...@@ -167,7 +165,7 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
if( p_dec->p_fifo->b_die ) break; if( p_dec->p_fifo->b_die ) break;
/* Check if frame is valid and get frame info */ /* 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 ); &i_bit_rate );
if( !i_frame_size ) if( !i_frame_size )
...@@ -178,7 +176,8 @@ static int RunDecoder( decoder_fifo_t *p_fifo ) ...@@ -178,7 +176,8 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
if( (p_dec->p_aout_input != NULL) && if( (p_dec->p_aout_input != NULL) &&
( (p_dec->output_format.i_rate != i_rate) ( (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) ) ) || (p_dec->output_format.i_bytes_per_frame != i_frame_size) ) )
{ {
/* Parameters changed - this should not happen. */ /* Parameters changed - this should not happen. */
...@@ -190,7 +189,9 @@ static int RunDecoder( decoder_fifo_t *p_fifo ) ...@@ -190,7 +189,9 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
if( p_dec->p_aout_input == NULL ) if( p_dec->p_aout_input == NULL )
{ {
p_dec->output_format.i_rate = i_rate; 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_bytes_per_frame = i_frame_size;
p_dec->output_format.i_frame_length = A52_FRAME_NB; p_dec->output_format.i_frame_length = A52_FRAME_NB;
aout_DateInit( &end_date, i_rate ); aout_DateInit( &end_date, i_rate );
...@@ -262,13 +263,13 @@ static void EndThread( dec_thread_t * p_dec ) ...@@ -262,13 +263,13 @@ static void EndThread( dec_thread_t * p_dec )
free( p_dec ); free( p_dec );
} }
/**************************************************************************** /*****************************************************************************
* SyncInfo: parse A52 sync info * SyncInfo: parse A52 sync info
**************************************************************************** *****************************************************************************
* This code is borrowed from liba52 by Aaron Holtzman & Michel Lespinasse, * 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 * since we don't want to oblige S/PDIF people to use liba52 just to get
* their SyncInfo... * their SyncInfo...
****************************************************************************/ *****************************************************************************/
int SyncInfo( const byte_t * p_buf, int * pi_channels, int * pi_sample_rate, int SyncInfo( const byte_t * p_buf, int * pi_channels, int * pi_sample_rate,
int * pi_bit_rate) int * pi_bit_rate)
{ {
...@@ -293,20 +294,50 @@ int SyncInfo( const byte_t * p_buf, int * pi_channels, int * pi_sample_rate, ...@@ -293,20 +294,50 @@ int SyncInfo( const byte_t * p_buf, int * pi_channels, int * pi_sample_rate,
acmod = p_buf[6] >> 5; acmod = p_buf[6] >> 5;
if ( (p_buf[6] & 0xf8) == 0x50 ) 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 ) else switch ( acmod )
{ {
case 0x0: *pi_channels = AOUT_CHAN_CHANNEL; break; case 0x0:
case 0x1: *pi_channels = AOUT_CHAN_MONO; break; /* Dual-mono = stereo + dual-mono */
case 0x2: *pi_channels = AOUT_CHAN_STEREO; break; *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
case 0x3: *pi_channels = AOUT_CHAN_3F; break; | AOUT_CHAN_DUALMONO;
case 0x4: *pi_channels = AOUT_CHAN_2F1R; break; break;
case 0x5: *pi_channels = AOUT_CHAN_3F1R; break; case 0x1:
case 0x6: *pi_channels = AOUT_CHAN_2F2R; break; /* Mono */
case 0x7: *pi_channels = AOUT_CHAN_3F2R; break; *pi_channels = AOUT_CHAN_CENTER;
case 0x8: *pi_channels = AOUT_CHAN_CHANNEL1; break; break;
case 0x9: *pi_channels = AOUT_CHAN_CHANNEL2; 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; if ( p_buf[6] & lfeon[acmod] ) *pi_channels |= AOUT_CHAN_LFE;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* araw.c: Pseudo audio decoder; for raw pcm data * araw.c: Pseudo audio decoder; for raw pcm data
***************************************************************************** *****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN * 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> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -85,12 +85,15 @@ vlc_module_begin(); ...@@ -85,12 +85,15 @@ vlc_module_begin();
vlc_module_end(); vlc_module_end();
static int i_channels_maps[6] = static int pi_channels_maps[6] =
{ {
0, 0,
AOUT_CHAN_MONO, AOUT_CHAN_STEREO, AOUT_CHAN_CENTER,
AOUT_CHAN_3F, AOUT_CHAN_2F2R, AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
AOUT_CHAN_3F2R 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 ) ...@@ -249,8 +252,9 @@ static int InitThread( adec_thread_t * p_adec )
return( -1 ); return( -1 );
} }
p_adec->output_format.i_channels = p_adec->output_format.i_physical_channels =
i_channels_maps[p_adec->format.i_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 = NULL;
p_adec->p_aout_input = NULL; p_adec->p_aout_input = NULL;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* decoder.c: AAC decoder using libfaad2 * decoder.c: AAC decoder using libfaad2
***************************************************************************** *****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN * 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> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -120,8 +120,17 @@ static int RunDecoder( decoder_fifo_t *p_fifo ) ...@@ -120,8 +120,17 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
return( 0 ); return( 0 );
} }
static int pi_channels_maps[6] =
#define FREE( p ) if( p ) free( p ); p = NULL {
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 ) \ #define GetWLE( p ) \
( *(u8*)(p) + ( *((u8*)(p)+1) << 8 ) ) ( *(u8*)(p) + ( *((u8*)(p)+1) << 8 ) )
...@@ -134,7 +143,7 @@ static void faac_GetWaveFormatEx( waveformatex_t *p_wh, ...@@ -134,7 +143,7 @@ static void faac_GetWaveFormatEx( waveformatex_t *p_wh,
{ {
p_wh->i_formattag = GetWLE( 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_samplespersec = GetDWLE( p_data + 4 );
p_wh->i_avgbytespersec= GetDWLE( p_data + 8 ); p_wh->i_avgbytespersec= GetDWLE( p_data + 8 );
p_wh->i_blockalign = GetWLE( p_data + 12 ); p_wh->i_blockalign = GetWLE( p_data + 12 );
...@@ -188,7 +197,7 @@ static int InitThread( adec_thread_t * p_adec ) ...@@ -188,7 +197,7 @@ static int InitThread( adec_thread_t * p_adec )
{ {
int i_status; int i_status;
unsigned long i_rate; unsigned long i_rate;
unsigned char i_channels; unsigned char i_nb_channels;
faacDecConfiguration *p_faad_config; faacDecConfiguration *p_faad_config;
...@@ -215,7 +224,7 @@ static int InitThread( adec_thread_t * p_adec ) ...@@ -215,7 +224,7 @@ static int InitThread( adec_thread_t * p_adec )
return( -1 ); return( -1 );
} }
if( !p_adec->format.p_data ) if( p_adec->format.p_data == NULL )
{ {
int i_frame_size; int i_frame_size;
pes_packet_t *p_pes; pes_packet_t *p_pes;
...@@ -254,7 +263,7 @@ static int InitThread( adec_thread_t * p_adec ) ...@@ -254,7 +263,7 @@ static int InitThread( adec_thread_t * p_adec )
p_adec->p_buffer, p_adec->p_buffer,
i_frame_size, i_frame_size,
&i_rate, &i_rate,
&i_channels ); &i_nb_channels );
} }
else else
{ {
...@@ -262,7 +271,7 @@ static int InitThread( adec_thread_t * p_adec ) ...@@ -262,7 +271,7 @@ static int InitThread( adec_thread_t * p_adec )
p_adec->format.p_data, p_adec->format.p_data,
p_adec->format.i_size, p_adec->format.i_size,
&i_rate, &i_rate,
&i_channels ); &i_nb_channels );
} }
if( i_status < 0 ) if( i_status < 0 )
...@@ -275,7 +284,7 @@ static int InitThread( adec_thread_t * p_adec ) ...@@ -275,7 +284,7 @@ static int InitThread( adec_thread_t * p_adec )
msg_Dbg( p_adec->p_fifo, msg_Dbg( p_adec->p_fifo,
"faad intitialized, samplerate:%dHz channels:%d", "faad intitialized, samplerate:%dHz channels:%d",
i_rate, i_rate,
i_channels ); i_nb_channels );
/* set default configuration */ /* set default configuration */
...@@ -287,7 +296,7 @@ static int InitThread( adec_thread_t * p_adec ) ...@@ -287,7 +296,7 @@ static int InitThread( adec_thread_t * p_adec )
/* Initialize the thread properties */ /* Initialize the thread properties */
p_adec->output_format.i_format = VLC_FOURCC('f','l','3','2'); 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_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 = NULL;
p_adec->p_aout_input = NULL; p_adec->p_aout_input = NULL;
...@@ -380,7 +389,8 @@ static void DecodeThread( adec_thread_t *p_adec ) ...@@ -380,7 +389,8 @@ static void DecodeThread( adec_thread_t *p_adec )
/* **** First check if we have a valid output **** */ /* **** First check if we have a valid output **** */
if( ( !p_adec->p_aout_input )|| 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 ) if( p_adec->p_aout_input )
{ {
...@@ -390,7 +400,7 @@ static void DecodeThread( adec_thread_t *p_adec ) ...@@ -390,7 +400,7 @@ static void DecodeThread( adec_thread_t *p_adec )
/* **** Create a new audio output **** */ /* **** Create a new audio output **** */
p_adec->output_format.i_channels = 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 ); 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_input = aout_DecNew( p_adec->p_fifo,
&p_adec->p_aout, &p_adec->p_aout,
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * 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> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
typedef struct waveformatex_s typedef struct waveformatex_s
{ {
u16 i_formattag; u16 i_formattag;
u16 i_channels; u16 i_nb_channels;
u32 i_samplespersec; u32 i_samplespersec;
u32 i_avgbytespersec; u32 i_avgbytespersec;
u16 i_blockalign; u16 i_blockalign;
...@@ -70,13 +70,3 @@ typedef struct adec_thread_s ...@@ -70,13 +70,3 @@ typedef struct adec_thread_s
} adec_thread_t; } 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
};
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* audio.c: audio decoder using ffmpeg library * audio.c: audio decoder using ffmpeg library
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * 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> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -57,12 +57,14 @@ int E_( InitThread_Audio ) ( adec_thread_t * ); ...@@ -57,12 +57,14 @@ int E_( InitThread_Audio ) ( adec_thread_t * );
void E_( EndThread_Audio ) ( adec_thread_t * ); void E_( EndThread_Audio ) ( adec_thread_t * );
void E_( DecodeThread_Audio ) ( adec_thread_t * ); void E_( DecodeThread_Audio ) ( adec_thread_t * );
static int i_channels_maps[6] = static int pi_channels_maps[6] =
{ {
0, 0,
AOUT_CHAN_MONO, AOUT_CHAN_STEREO, AOUT_CHAN_CENTER, AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
AOUT_CHAN_3F, AOUT_CHAN_2F2R, AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
AOUT_CHAN_3F2R 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, ...@@ -73,7 +75,7 @@ static void ffmpeg_GetWaveFormatEx( waveformatex_t *p_wh,
u8 *p_data ) u8 *p_data )
{ {
p_wh->i_formattag = GetWLE( 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_samplespersec = GetDWLE( p_data + 4 );
p_wh->i_avgbytespersec= GetDWLE( p_data + 8 ); p_wh->i_avgbytespersec= GetDWLE( p_data + 8 );
p_wh->i_blockalign = GetWLE( p_data + 12 ); p_wh->i_blockalign = GetWLE( p_data + 12 );
...@@ -121,7 +123,7 @@ int E_( InitThread_Audio )( adec_thread_t *p_adec ) ...@@ -121,7 +123,7 @@ int E_( InitThread_Audio )( adec_thread_t *p_adec )
/* ***** Fill p_context with init values ***** */ /* ***** Fill p_context with init values ***** */
p_adec->p_context->sample_rate = p_adec->format.i_samplespersec; 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 #if LIBAVCODEC_BUILD >= 4618
p_adec->p_context->block_align = p_adec->format.i_blockalign; p_adec->p_context->block_align = p_adec->format.i_blockalign;
#endif #endif
...@@ -157,7 +159,9 @@ int E_( InitThread_Audio )( adec_thread_t *p_adec ) ...@@ -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_format = AOUT_FMT_S16_NE;
p_adec->output_format.i_rate = p_adec->format.i_samplespersec; 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 = NULL;
p_adec->p_aout_input = NULL; p_adec->p_aout_input = NULL;
...@@ -234,21 +238,23 @@ void E_( DecodeThread_Audio )( adec_thread_t *p_adec ) ...@@ -234,21 +238,23 @@ void E_( DecodeThread_Audio )( adec_thread_t *p_adec )
} }
/* **** Now we can output these samples **** */ /* **** 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 **** */ /* **** First check if we have a valid output **** */
if( ( !p_adec->p_aout_input )|| if( ( p_adec->p_aout_input == NULL )||
( p_adec->output_format.i_channels != ( p_adec->output_format.i_original_channels !=
p_adec->p_context->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 **** */ /* **** Delete the old **** */
aout_DecDelete( p_adec->p_aout, p_adec->p_aout_input ); aout_DecDelete( p_adec->p_aout, p_adec->p_aout_input );
} }
/* **** Create a new audio output **** */ /* **** Create a new audio output **** */
p_adec->output_format.i_channels = p_adec->output_format.i_physical_channels =
i_channels_maps[p_adec->p_context->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 ); 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_input = aout_DecNew( p_adec->p_fifo,
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* audio.h: video decoder using ffmpeg library * audio.h: video decoder using ffmpeg library
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * 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> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
typedef struct waveformatex_s typedef struct waveformatex_s
{ {
u16 i_formattag; u16 i_formattag;
u16 i_channels; u16 i_nb_channels;
u32 i_samplespersec; u32 i_samplespersec;
u32 i_avgbytespersec; u32 i_avgbytespersec;
u16 i_blockalign; u16 i_blockalign;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* lpcm.c: lpcm decoder module * lpcm.c: lpcm decoder module
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * 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> * Authors: Samuel Hocevar <sam@zoy.org>
* Henri Fallon <henri@videolan.org> * Henri Fallon <henri@videolan.org>
...@@ -133,7 +133,9 @@ static int RunDecoder( decoder_fifo_t * p_fifo ) ...@@ -133,7 +133,9 @@ static int RunDecoder( decoder_fifo_t * p_fifo )
/* FIXME : I suppose the number of channel and sampling rate /* FIXME : I suppose the number of channel and sampling rate
* are somewhere in the headers */ * are somewhere in the headers */
p_dec->output_format.i_format = VLC_FOURCC('s','1','6','b'); 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; p_dec->output_format.i_rate = 48000;
aout_DateInit( &p_dec->end_date, 48000 ); aout_DateInit( &p_dec->end_date, 48000 );
......
...@@ -148,14 +148,15 @@ enum mad_flow libmad_output( void *p_data, struct mad_header const *p_header, ...@@ -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]; mad_fixed_t const * p_right = p_pcm->samples[1];
int i_samples = p_pcm->length; int i_samples = p_pcm->length;
mad_fixed_t * p_samples; mad_fixed_t * p_samples;
int i_channels = (p_pcm->channels == 2) ? AOUT_CHAN_STEREO : int i_channels = (p_pcm->channels == 2) ?
AOUT_CHAN_MONO; AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT :
AOUT_CHAN_CENTER;
/* Creating the audio output fifo. Assume the samplerate and nr of channels /* Creating the audio output fifo. Assume the samplerate and nr of channels
* from the first decoded frame is right for the entire audio track. */ * from the first decoded frame is right for the entire audio track. */
if( (p_dec->p_aout_input != NULL) && if( (p_dec->p_aout_input != NULL) &&
(p_dec->output_format.i_rate != p_pcm->samplerate (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. */ /* Parameters changed - this should not happen. */
aout_DecDelete( p_dec->p_aout, p_dec->p_aout_input ); 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, ...@@ -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 ) if( p_dec->p_aout_input == NULL )
{ {
p_dec->output_format.i_rate = p_pcm->samplerate; 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 ); aout_DateInit( &p_dec->end_date, p_pcm->samplerate );
p_dec->p_aout_input = aout_DecNew( p_dec->p_fifo, p_dec->p_aout_input = aout_DecNew( p_dec->p_fifo,
&p_dec->p_aout, &p_dec->p_aout,
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* decoder.c: MPEG audio decoder thread * decoder.c: MPEG audio decoder thread
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * 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> * Authors: Michel Kaempf <maxx@via.ecp.fr>
* Michel Lespinasse <walken@via.ecp.fr> * Michel Lespinasse <walken@via.ecp.fr>
...@@ -173,8 +173,9 @@ static void DecodeThread( adec_thread_t * p_dec ) ...@@ -173,8 +173,9 @@ static void DecodeThread( adec_thread_t * p_dec )
{ {
/* Create the output fifo if it doesn't exist yet */ /* Create the output fifo if it doesn't exist yet */
if( ( p_dec->p_aout_input == NULL ) || if( ( p_dec->p_aout_input == NULL ) ||
( p_dec->output_format.i_channels != ( p_dec->output_format.i_physical_channels !=
( sync_info.b_stereo ? AOUT_CHAN_STEREO : AOUT_CHAN_MONO ) ) || ( sync_info.b_stereo ? AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT :
AOUT_CHAN_CENTER ) ) ||
( p_dec->output_format.i_rate != sync_info.sample_rate ) ) ( p_dec->output_format.i_rate != sync_info.sample_rate ) )
{ {
if( p_dec->p_aout_input ) if( p_dec->p_aout_input )
...@@ -186,8 +187,10 @@ static void DecodeThread( adec_thread_t * p_dec ) ...@@ -186,8 +187,10 @@ static void DecodeThread( adec_thread_t * p_dec )
/* Set output configuration */ /* Set output configuration */
p_dec->output_format.i_format = VLC_FOURCC('f','l','3','2'); p_dec->output_format.i_format = VLC_FOURCC('f','l','3','2');
p_dec->output_format.i_channels = p_dec->output_format.i_physical_channels =
( sync_info.b_stereo ? AOUT_CHAN_STEREO : AOUT_CHAN_MONO ); 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; p_dec->output_format.i_rate = sync_info.sample_rate;
aout_DateInit( &p_dec->end_date, 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, p_dec->p_aout_input = aout_DecNew( p_dec->p_fifo,
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* vorbis.c: vorbis decoder module making use of libvorbis. * vorbis.c: vorbis decoder module making use of libvorbis.
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * 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> * Authors: Gildas Bazin <gbazin@netcourrier.com>
* *
...@@ -74,6 +74,16 @@ typedef struct dec_thread_t ...@@ -74,6 +74,16 @@ typedef struct dec_thread_t
} 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 * Local prototypes
*****************************************************************************/ *****************************************************************************/
...@@ -174,7 +184,7 @@ static int RunDecoder( decoder_fifo_t * p_fifo ) ...@@ -174,7 +184,7 @@ static int RunDecoder( decoder_fifo_t * p_fifo )
vorbis_block_init( &p_dec->vd, &p_dec->vb ); 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_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; p_dec->output_format.i_rate = p_dec->vi.rate;
aout_DateInit( &p_dec->end_date, 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, ...@@ -311,16 +321,16 @@ static int GetOggPacket( dec_thread_t *p_dec, ogg_packet *p_oggpacket,
/***************************************************************************** /*****************************************************************************
* Interleave: helper function to interleave channels * 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_samples )
{ {
int i, j; int i, j;
for ( j = 0; j < i_samples; 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];
} }
} }
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* rc.c : remote control stdin/stdout plugin for vlc * rc.c : remote control stdin/stdout plugin for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * 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> * Authors: Peter Surda <shurdeek@panorama.sth.ac.at>
* *
...@@ -60,6 +60,9 @@ static void Run ( intf_thread_t *p_intf ); ...@@ -60,6 +60,9 @@ static void Run ( intf_thread_t *p_intf );
static int Playlist ( vlc_object_t *, char *, char * ); static int Playlist ( vlc_object_t *, char *, char * );
static int Quit ( vlc_object_t *, char *, char * ); static int Quit ( vlc_object_t *, char *, char * );
static int Intf ( 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 * Module descriptor
...@@ -150,6 +153,17 @@ static void Run( intf_thread_t *p_intf ) ...@@ -150,6 +153,17 @@ static void Run( intf_thread_t *p_intf )
var_Create( p_intf, "next", VLC_VAR_COMMAND ); var_Create( p_intf, "next", VLC_VAR_COMMAND );
var_Set( p_intf, "next", (vlc_value_t)(void*)Playlist ); 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 ) while( !p_intf->b_die )
{ {
fd_set fds; fd_set fds;
...@@ -378,6 +392,12 @@ static void Run( intf_thread_t *p_intf ) ...@@ -378,6 +392,12 @@ static void Run( intf_thread_t *p_intf )
printf("| f . . . . . . . . . . . . . . toggle fullscreen\n"); printf("| f . . . . . . . . . . . . . . toggle fullscreen\n");
printf("| info . . . information about the current stream\n"); printf("| info . . . information about the current stream\n");
printf("| \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("| help . . . . . . . . . . . . . this help message\n");
printf("| quit . . . . . . . . . . . . . . . . . quit vlc\n"); printf("| quit . . . . . . . . . . . . . . . . . quit vlc\n");
printf("| \n"); printf("| \n");
...@@ -495,4 +515,145 @@ static int Signal( vlc_object_t *p_this, char *psz_cmd, char *psz_arg ) ...@@ -495,4 +515,145 @@ static int Signal( vlc_object_t *p_this, char *psz_cmd, char *psz_arg )
return VLC_SUCCESS; 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;
}
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* aout.m: CoreAudio output plugin * aout.m: CoreAudio output plugin
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * 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> * Authors: Colin Delacroix <colin@zoy.org>
* Jon Lech Johansen <jon-vl@nanocrew.net> * Jon Lech Johansen <jon-vl@nanocrew.net>
...@@ -82,7 +82,6 @@ int E_(OpenAudio)( vlc_object_t * p_this ) ...@@ -82,7 +82,6 @@ int E_(OpenAudio)( vlc_object_t * p_this )
UInt32 i_param_size; UInt32 i_param_size;
aout_instance_t * p_aout = (aout_instance_t *)p_this; aout_instance_t * p_aout = (aout_instance_t *)p_this;
struct aout_sys_t * p_sys; struct aout_sys_t * p_sys;
msg_Dbg(p_aout, "************************* ENTER OpenAudio ****************************");
/* Allocate instance */ /* Allocate instance */
p_sys = p_aout->output.p_sys = malloc( sizeof( struct aout_sys_t ) ); p_sys = p_aout->output.p_sys = malloc( sizeof( struct aout_sys_t ) );
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ipv4.c: IPv4 network abstraction layer * ipv4.c: IPv4 network abstraction layer
***************************************************************************** *****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN * 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> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* Mathias Kretschmer <mathias@research.att.com> * Mathias Kretschmer <mathias@research.att.com>
...@@ -249,7 +249,8 @@ static int OpenUDP( vlc_object_t * p_this, network_socket_t * p_socket ) ...@@ -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" ); char * psz_if_addr = config_GetPsz( p_this, "iface-addr" );
imr.imr_multiaddr.s_addr = inet_addr(psz_bind_addr); imr.imr_multiaddr.s_addr = inet_addr(psz_bind_addr);
#endif #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); 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 ) ...@@ -257,7 +258,7 @@ static int OpenUDP( vlc_object_t * p_this, network_socket_t * p_socket )
{ {
imr.imr_interface.s_addr = INADDR_ANY; 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, if( setsockopt( i_handle, IPPROTO_IP, IP_ADD_MEMBERSHIP,
(char*)&imr, sizeof(struct ip_mreq) ) == -1 ) (char*)&imr, sizeof(struct ip_mreq) ) == -1 )
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* xcommon.c: Functions common to the X11 and XVideo plugins * xcommon.c: Functions common to the X11 and XVideo plugins
***************************************************************************** *****************************************************************************
* Copyright (C) 1998-2001 VideoLAN * 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> * Authors: Vincent Seguin <seguin@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org> * Samuel Hocevar <sam@zoy.org>
...@@ -145,7 +145,7 @@ int E_(Activate) ( vlc_object_t *p_this ) ...@@ -145,7 +145,7 @@ int E_(Activate) ( vlc_object_t *p_this )
return VLC_ENOMEM; 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 */ * environment variable */
psz_display = config_GetPsz( p_vout, MODULE_STRING "-display" ); psz_display = config_GetPsz( p_vout, MODULE_STRING "-display" );
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* common.c : audio output management of common data structures * common.c : audio output management of common data structures
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * 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> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -62,6 +62,13 @@ aout_instance_t * __aout_New( vlc_object_t * p_parent ) ...@@ -62,6 +62,13 @@ aout_instance_t * __aout_New( vlc_object_t * p_parent )
vlc_object_attach( p_aout, p_parent->p_vlc ); 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; return p_aout;
} }
...@@ -70,6 +77,8 @@ aout_instance_t * __aout_New( vlc_object_t * p_parent ) ...@@ -70,6 +77,8 @@ aout_instance_t * __aout_New( vlc_object_t * p_parent )
*****************************************************************************/ *****************************************************************************/
void aout_Delete( aout_instance_t * p_aout ) 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->input_fifos_lock );
vlc_mutex_destroy( &p_aout->mixer_lock ); vlc_mutex_destroy( &p_aout->mixer_lock );
vlc_mutex_destroy( &p_aout->output_fifo_lock ); vlc_mutex_destroy( &p_aout->output_fifo_lock );
...@@ -86,45 +95,19 @@ void aout_Delete( aout_instance_t * p_aout ) ...@@ -86,45 +95,19 @@ void aout_Delete( aout_instance_t * p_aout )
/***************************************************************************** /*****************************************************************************
* aout_FormatNbChannels : return the number of channels * 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: if ( p_format->i_physical_channels & pi_channels[i] ) i_nb++;
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_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 ) ...@@ -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_CENTER:
case AOUT_CHAN_CHANNEL1: return "CHANNEL1"; if ( (p_format->i_original_channels & AOUT_CHAN_CENTER)
case AOUT_CHAN_CHANNEL2: return "CHANNEL2"; || (p_format->i_original_channels
case AOUT_CHAN_MONO: return "MONO"; & (AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT)) )
case AOUT_CHAN_STEREO: return "STEREO"; return "Mono";
case AOUT_CHAN_3F: return "3F"; else if ( p_format->i_original_channels & AOUT_CHAN_LEFT )
case AOUT_CHAN_2F1R: return "2F1R"; return "Left";
case AOUT_CHAN_3F1R: return "3F1R"; return "Right";
case AOUT_CHAN_2F2R: return "2F2R"; case AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT:
case AOUT_CHAN_3F2R: return "3F2R"; if ( p_format->i_original_channels & AOUT_CHAN_DOLBYSTEREO )
case AOUT_CHAN_DOLBY: return "DOLBY"; return "Dolby";
case AOUT_CHAN_CHANNEL | AOUT_CHAN_LFE: return "CHANNEL|LFE"; else if ( p_format->i_original_channels & AOUT_CHAN_DUALMONO )
case AOUT_CHAN_CHANNEL1 | AOUT_CHAN_LFE: return "CHANNEL1|LFE"; return "Dual-mono";
case AOUT_CHAN_CHANNEL2 | AOUT_CHAN_LFE: return "CHANNEL2|LFE"; else if ( !(p_format->i_original_channels & AOUT_CHAN_RIGHT) )
case AOUT_CHAN_MONO | AOUT_CHAN_LFE: return "MONO|LFE"; return "Stereo/Left";
case AOUT_CHAN_STEREO | AOUT_CHAN_LFE: return "STEREO|LFE"; else if ( !(p_format->i_original_channels & AOUT_CHAN_LEFT) )
case AOUT_CHAN_3F | AOUT_CHAN_LFE: return "3F|LFE"; return "Stereo/Right";
case AOUT_CHAN_2F1R | AOUT_CHAN_LFE: return "2F1R|LFE"; return "Stereo";
case AOUT_CHAN_3F1R | AOUT_CHAN_LFE: return "3F1R|LFE"; case AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER:
case AOUT_CHAN_2F2R | AOUT_CHAN_LFE: return "2F2R|LFE"; return "3F";
case AOUT_CHAN_3F2R | AOUT_CHAN_LFE: return "3F2R|LFE"; case AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARCENTER:
case AOUT_CHAN_DOLBY | AOUT_CHAN_LFE: return "DOLBY|LFE"; 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"; return "ERROR";
...@@ -209,7 +234,7 @@ void aout_FormatPrint( aout_instance_t * p_aout, const char * psz_text, ...@@ -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, msg_Dbg( p_aout, "%s format='%4.4s' rate=%d channels=%s", psz_text,
(char *)&p_format->i_format, p_format->i_rate, (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, ...@@ -223,8 +248,8 @@ void aout_FormatsPrint( aout_instance_t * p_aout, const char * psz_text,
psz_text, psz_text,
(char *)&p_format1->i_format, (char *)&p_format2->i_format, (char *)&p_format1->i_format, (char *)&p_format2->i_format,
p_format1->i_rate, p_format2->i_rate, p_format1->i_rate, p_format2->i_rate,
FormatPrintChannels( p_format1->i_channels ), aout_FormatPrintChannels( p_format1 ),
FormatPrintChannels( p_format2->i_channels ) ); aout_FormatPrintChannels( p_format2 ) );
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* dec.c : audio output API towards decoders * dec.c : audio output API towards decoders
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * 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> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -80,6 +80,15 @@ static aout_input_t * DecNew( aout_instance_t * p_aout, ...@@ -80,6 +80,15 @@ static aout_input_t * DecNew( aout_instance_t * p_aout,
{ {
int i; 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. */ /* Recreate the output using the new format. */
if ( aout_OutputNew( p_aout, p_format ) < 0 ) if ( aout_OutputNew( p_aout, p_format ) < 0 )
{ {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* filters.c : audio output filters management * filters.c : audio output filters management
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * 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> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -83,7 +83,10 @@ static int SplitConversion( aout_instance_t * p_aout, ...@@ -83,7 +83,10 @@ static int SplitConversion( aout_instance_t * p_aout,
(p_input_format->i_format != p_output_format->i_format); (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_rate = (p_input_format->i_rate != p_output_format->i_rate);
vlc_bool_t b_channels = 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; int i_nb_conversions = b_format + b_rate + b_channels;
if ( i_nb_conversions <= 1 ) return 0; if ( i_nb_conversions <= 1 ) return 0;
...@@ -99,7 +102,10 @@ static int SplitConversion( aout_instance_t * p_aout, ...@@ -99,7 +102,10 @@ static int SplitConversion( aout_instance_t * p_aout,
} }
/* !b_rate */ /* !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; return 1;
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* intf.c : audio output API towards the interface modules * intf.c : audio output API towards the interface modules
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * 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> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -103,7 +103,7 @@ int aout_VolumeSet( aout_instance_t * p_aout, audio_volume_t i_volume ) ...@@ -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 ) 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 ) ...@@ -323,6 +323,7 @@ int aout_Restart( aout_instance_t * p_aout )
/* Re-open the output plug-in. */ /* Re-open the output plug-in. */
aout_OutputDelete( p_aout ); aout_OutputDelete( p_aout );
if ( aout_OutputNew( p_aout, &p_aout->pp_inputs[0]->input ) == -1 ) if ( aout_OutputNew( p_aout, &p_aout->pp_inputs[0]->input ) == -1 )
{ {
/* Release all locks and report the error. */ /* Release all locks and report the error. */
...@@ -361,6 +362,10 @@ int aout_Restart( aout_instance_t * p_aout ) ...@@ -361,6 +362,10 @@ int aout_Restart( aout_instance_t * p_aout )
/***************************************************************************** /*****************************************************************************
* aout_FindAndRestart : find the audio output instance and restart * 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 ) void aout_FindAndRestart( vlc_object_t * p_this )
{ {
...@@ -369,6 +374,37 @@ 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 ( 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 ); aout_Restart( p_aout );
vlc_object_release( 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;
}
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* output.c : internal management of output streams for the audio output * output.c : internal management of output streams for the audio output
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * 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> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -43,29 +43,10 @@ int aout_OutputNew( aout_instance_t * p_aout, ...@@ -43,29 +43,10 @@ int aout_OutputNew( aout_instance_t * p_aout,
/* Retrieve user defaults. */ /* Retrieve user defaults. */
char * psz_name = config_GetPsz( p_aout, "aout" ); char * psz_name = config_GetPsz( p_aout, "aout" );
int i_rate = config_GetInt( p_aout, "aout-rate" ); 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) ); 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_rate != -1 )
if ( i_channels != -1 ) p_aout->output.output.i_channels = i_channels; p_aout->output.output.i_rate = i_rate;
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;
}
}
aout_FormatPrepare( &p_aout->output.output ); aout_FormatPrepare( &p_aout->output.output );
vlc_mutex_lock( &p_aout->output_fifo_lock ); vlc_mutex_lock( &p_aout->output_fifo_lock );
...@@ -80,6 +61,80 @@ int aout_OutputNew( aout_instance_t * p_aout, ...@@ -80,6 +61,80 @@ int aout_OutputNew( aout_instance_t * p_aout,
vlc_mutex_unlock( &p_aout->output_fifo_lock ); vlc_mutex_unlock( &p_aout->output_fifo_lock );
return -1; 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 ); aout_FormatPrepare( &p_aout->output.output );
/* Prepare FIFO. */ /* Prepare FIFO. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment