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