/*****************************************************************************
* waveout.c : Windows waveOut plugin for vlc
*****************************************************************************
- * Copyright (C) 2001-2009 the VideoLAN team
+ * Copyright (C) 2001-2009 VLC authors and VideoLAN
* $Id$
*
* Authors: Gildas Bazin <gbazin@videolan.org>
* André Weber
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
+ * You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_aout.h>
-#include <vlc_aout_intf.h>
#include <vlc_charset.h> /* FromWide() */
#include <vlc_atomic.h>
*****************************************************************************/
static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * );
-static void Play ( audio_output_t *, block_t *, mtime_t * );
+static void Play ( audio_output_t *, block_t * );
/*****************************************************************************
* notification_thread_t: waveOut event thread
*****************************************************************************/
/* local functions */
-static void Probe ( audio_output_t * );
+static void Probe ( audio_output_t *, const audio_sample_format_t * );
static int OpenWaveOut ( audio_output_t *, uint32_t,
int, int, int, int, bool );
static int OpenWaveOutPCM( audio_output_t *, uint32_t,
static int WaveOutClearDoneBuffers(aout_sys_t *p_sys);
-static int ReloadWaveoutDevices( vlc_object_t *, char const *,
- vlc_value_t, vlc_value_t, void * );
+static int ReloadWaveoutDevices( vlc_object_t *, const char *,
+ char ***, char *** );
static uint32_t findDeviceID(char *);
static const wchar_t device_name_fmt[] = L"%ls ($%x,$%x)";
-static const char *const ppsz_adev[] = { "wavemapper", };
-static const char *const ppsz_adev_text[] = { N_("Microsoft Soundmapper") };
-
/*****************************************************************************
* aout_sys_t: waveOut audio output method descriptor
*****************************************************************************
bool soft_mute;
};
- bool b_chan_reorder; /* do we need channel reordering */
- int pi_chan_table[AOUT_CHAN_MAX];
+ uint8_t chans_to_reorder; /* do we need channel reordering */
+ uint8_t chan_table[AOUT_CHAN_MAX];
};
#include "volume.h"
add_string( "waveout-audio-device", "wavemapper",
DEVICE_TEXT, DEVICE_LONG, false )
- change_string_list( ppsz_adev, ppsz_adev_text, ReloadWaveoutDevices )
- change_action_add( ReloadWaveoutDevices, N_("Refresh list") )
+ change_string_cb( ReloadWaveoutDevices )
add_sw_gain( )
add_bool( "waveout-float32", true, FLOAT_TEXT, FLOAT_LONGTEXT, true )
vlc_module_end ()
/*****************************************************************************
- * Open: open the audio device
+ * Opens the audio device
*****************************************************************************
* This function opens and setups Win32 waveOut
*****************************************************************************/
-static int Open( vlc_object_t *p_this )
+static int Start( audio_output_t *p_aout, audio_sample_format_t *restrict fmt )
{
- audio_output_t *p_aout = (audio_output_t *)p_this;
vlc_value_t val;
- /* Allocate structure */
- p_aout->sys = malloc( sizeof( aout_sys_t ) );
-
- if( p_aout->sys == NULL )
- return VLC_ENOMEM;
-
- p_aout->pf_play = Play;
- p_aout->pf_pause = aout_PacketPause;
- p_aout->pf_flush = aout_PacketFlush;
-
- /*
- initialize/update Device selection List
- */
- ReloadWaveoutDevices( p_this, "waveout-audio-device", val, val, NULL);
+ p_aout->time_get = aout_PacketTimeGet;
+ p_aout->play = Play;
+ p_aout->pause = NULL;
+ p_aout->flush = aout_PacketFlush;
/*
check for configured audio device!
if( var_Type( p_aout, "audio-device" ) == 0 )
{
- Probe( p_aout );
+ Probe( p_aout, fmt );
}
if( var_Get( p_aout, "audio-device", &val ) < 0 )
/* Open the device */
if( val.i_int == AOUT_VAR_SPDIF )
{
- p_aout->format.i_format = VLC_CODEC_SPDIFL;
-
- if( OpenWaveOut( p_aout,
- p_aout->sys->i_wave_device_id,
- VLC_CODEC_SPDIFL,
- p_aout->format.i_physical_channels,
- aout_FormatNbChannels( &p_aout->format ),
- p_aout->format.i_rate, false )
+ fmt->i_format = VLC_CODEC_SPDIFL;
+
+ if( OpenWaveOut( p_aout, p_aout->sys->i_wave_device_id,
+ VLC_CODEC_SPDIFL, fmt->i_physical_channels,
+ aout_FormatNbChannels( fmt ), fmt->i_rate, false )
!= VLC_SUCCESS )
{
msg_Err( p_aout, "cannot open waveout audio device" );
}
/* Calculate the frame size in bytes */
- p_aout->format.i_bytes_per_frame = AOUT_SPDIF_SIZE;
- p_aout->format.i_frame_length = A52_FRAME_NB;
- p_aout->sys->i_buffer_size =
- p_aout->format.i_bytes_per_frame;
-
- aout_PacketInit( p_aout, &p_aout->sys->packet, A52_FRAME_NB );
- p_aout->volume_set = NULL;
- p_aout->mute_set = NULL;
+ fmt->i_bytes_per_frame = AOUT_SPDIF_SIZE;
+ fmt->i_frame_length = A52_FRAME_NB;
+ p_aout->sys->i_buffer_size = fmt->i_bytes_per_frame;
+
+ aout_PacketInit( p_aout, &p_aout->sys->packet, A52_FRAME_NB, fmt );
}
else
{
switch( val.i_int )
{
case AOUT_VAR_5_1:
- p_aout->format.i_physical_channels
+ fmt->i_physical_channels
= AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
| AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
| AOUT_CHAN_LFE;
break;
case AOUT_VAR_2F2R:
- p_aout->format.i_physical_channels
+ fmt->i_physical_channels
= AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
| AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
break;
case AOUT_VAR_MONO:
- p_aout->format.i_physical_channels = AOUT_CHAN_CENTER;
+ fmt->i_physical_channels = AOUT_CHAN_CENTER;
break;
default:
- p_aout->format.i_physical_channels
- = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
+ fmt->i_physical_channels = AOUT_CHANS_STEREO;
}
- if( OpenWaveOutPCM( p_aout,
- p_aout->sys->i_wave_device_id,
- &p_aout->format.i_format,
- p_aout->format.i_physical_channels,
- aout_FormatNbChannels( &p_aout->format ),
- p_aout->format.i_rate, false )
+ if( OpenWaveOutPCM( p_aout, p_aout->sys->i_wave_device_id,
+ &fmt->i_format, fmt->i_physical_channels,
+ aout_FormatNbChannels( fmt ), fmt->i_rate, false )
!= VLC_SUCCESS )
{
msg_Err( p_aout, "cannot open waveout audio device" );
}
/* Calculate the frame size in bytes */
- aout_FormatPrepare( &p_aout->format );
- p_aout->sys->i_buffer_size = FRAME_SIZE *
- p_aout->format.i_bytes_per_frame;
+ aout_FormatPrepare( fmt );
+ p_aout->sys->i_buffer_size = FRAME_SIZE * fmt->i_bytes_per_frame;
- aout_PacketInit( p_aout, &p_aout->sys->packet, FRAME_SIZE );
+ aout_PacketInit( p_aout, &p_aout->sys->packet, FRAME_SIZE, fmt );
-#ifndef UNDER_CE
/* Check for hardware volume support */
if( waveOutGetDevCaps( (UINT_PTR)p_aout->sys->h_waveout,
&wocaps, sizeof(wocaps) ) == MMSYSERR_NOERROR
&& (wocaps.dwSupport & WAVECAPS_VOLUME) )
- {
+ { /* FIXME: this needs to be moved to Open() */
p_aout->volume_set = VolumeSet;
p_aout->mute_set = MuteSet;
p_aout->sys->volume = 0xffff.fp0;
p_aout->sys->mute = false;
}
else
-#endif
aout_SoftVolumeInit( p_aout );
}
/*****************************************************************************
* Probe: probe the audio device for available formats and channels
*****************************************************************************/
-static void Probe( audio_output_t * p_aout )
+static void Probe( audio_output_t * p_aout, const audio_sample_format_t *fmt )
{
vlc_value_t val, text;
vlc_fourcc_t i_format;
i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT |
AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE;
- if( p_aout->format.i_physical_channels == i_physical_channels )
+ if( fmt->i_physical_channels == i_physical_channels )
{
- if( OpenWaveOutPCM( p_aout,
- p_aout->sys->i_wave_device_id,
- &i_format,
- i_physical_channels, 6,
- p_aout->format.i_rate, true )
+ if( OpenWaveOutPCM( p_aout, p_aout->sys->i_wave_device_id,
+ &i_format, i_physical_channels, 6,
+ fmt->i_rate, true )
== VLC_SUCCESS )
{
val.i_int = AOUT_VAR_5_1;
/* Test for 2 Front 2 Rear support */
i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
- if( ( p_aout->format.i_physical_channels & i_physical_channels )
+ if( ( fmt->i_physical_channels & i_physical_channels )
== i_physical_channels )
{
- if( OpenWaveOutPCM( p_aout,
- p_aout->sys->i_wave_device_id,
- &i_format,
- i_physical_channels, 4,
- p_aout->format.i_rate, true )
+ if( OpenWaveOutPCM( p_aout,p_aout->sys->i_wave_device_id,
+ &i_format, i_physical_channels, 4,
+ fmt->i_rate, true )
== VLC_SUCCESS )
{
val.i_int = AOUT_VAR_2F2R;
/* Test for stereo support */
i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
- if( OpenWaveOutPCM( p_aout,
- p_aout->sys->i_wave_device_id,
- &i_format,
- i_physical_channels, 2,
- p_aout->format.i_rate, true )
+ if( OpenWaveOutPCM( p_aout, p_aout->sys->i_wave_device_id,
+ &i_format,i_physical_channels, 2,
+ fmt->i_rate, true )
== VLC_SUCCESS )
{
val.i_int = AOUT_VAR_STEREO;
/* Test for mono support */
i_physical_channels = AOUT_CHAN_CENTER;
- if( OpenWaveOutPCM( p_aout,
- p_aout->sys->i_wave_device_id,
- &i_format,
- i_physical_channels, 1,
- p_aout->format.i_rate, true )
+ if( OpenWaveOutPCM( p_aout, p_aout->sys->i_wave_device_id,
+ &i_format, i_physical_channels, 1, fmt->i_rate, true )
== VLC_SUCCESS )
{
val.i_int = AOUT_VAR_MONO;
}
/* Test for SPDIF support */
- if ( AOUT_FMT_SPDIF( &p_aout->format ) )
+ if ( AOUT_FMT_SPDIF( fmt ) )
{
- if( OpenWaveOut( p_aout,
- p_aout->sys->i_wave_device_id,
- VLC_CODEC_SPDIFL,
- p_aout->format.i_physical_channels,
- aout_FormatNbChannels( &p_aout->format ),
- p_aout->format.i_rate, true )
+ if( OpenWaveOut( p_aout, p_aout->sys->i_wave_device_id,
+ VLC_CODEC_SPDIFL, fmt->i_physical_channels,
+ aout_FormatNbChannels( fmt ), fmt->i_rate, true )
== VLC_SUCCESS )
{
msg_Dbg( p_aout, "device supports A/52 over S/PDIF" );
* This doesn't actually play the buffer. This just stores the buffer so it
* can be played by the callback thread.
*****************************************************************************/
-static void Play( audio_output_t *_p_aout, block_t *block,
- mtime_t *restrict drift )
+static void Play( audio_output_t *_p_aout, block_t *block )
{
if( !_p_aout->sys->b_playing )
{
SetEvent( _p_aout->sys->new_buffer_event );
}
- aout_PacketPlay( _p_aout, block, drift );
+ aout_PacketPlay( _p_aout, block );
}
/*****************************************************************************
* Close: close the audio device
*****************************************************************************/
-static void Close( vlc_object_t *p_this )
+static void Stop( audio_output_t *p_aout )
{
- audio_output_t *p_aout = (audio_output_t *)p_this;
aout_sys_t *p_sys = p_aout->sys;
/* Before calling waveOutClose we must reset the device */
free( p_sys->p_silence_buffer );
aout_PacketDestroy( p_aout );
- free( p_sys );
}
/*****************************************************************************
return VLC_EGENERIC;
}
- p_aout->sys->b_chan_reorder =
+ p_aout->sys->chans_to_reorder =
aout_CheckChannelReorder( pi_channels_in, pi_channels_out,
- waveformat.dwChannelMask, i_nb_channels,
- p_aout->sys->pi_chan_table );
-
- if( p_aout->sys->b_chan_reorder )
- {
+ waveformat.dwChannelMask,
+ p_aout->sys->chan_table );
+ if( p_aout->sys->chans_to_reorder )
msg_Dbg( p_aout, "channel reordering needed" );
- }
return VLC_SUCCESS;
int canc = vlc_savecancel ();
/* We don't want any resampling when using S/PDIF */
- b_sleek = p_aout->format.i_format == VLC_CODEC_SPDIFL;
+ b_sleek = p_sys->packet.format.i_format == VLC_CODEC_SPDIFL;
// wait for first call to "play()"
while( !p_sys->start_date && !vlc_atomic_get(&p_aout->sys->abort) )
}
/* Do the channel reordering */
- if( p_buffer && p_sys->b_chan_reorder )
+ if( p_buffer && p_sys->chans_to_reorder )
{
aout_ChannelReorder( p_buffer->p_buffer,
p_buffer->i_buffer,
p_sys->waveformat.Format.nChannels,
- p_sys->pi_chan_table,
+ p_sys->chan_table,
p_sys->waveformat.Format.wBitsPerSample );
}
return NULL;
}
-#ifndef UNDER_CE
static int VolumeSet( audio_output_t *aout, float volume )
{
aout_sys_t *sys = aout->sys;
waveOutSetVolume( hwo, vol | (vol << 16) );
return 0;
}
-#endif
/*
reload the configuration drop down list, of the Audio Devices
*/
static int ReloadWaveoutDevices( vlc_object_t *p_this, char const *psz_name,
- vlc_value_t newval, vlc_value_t oldval, void *data )
+ char ***values, char ***descs )
{
- VLC_UNUSED( newval ); VLC_UNUSED( oldval ); VLC_UNUSED( data );
+ int n = 0, nb_devices = waveOutGetNumDevs();
- module_config_t *p_item = config_FindConfig( p_this, psz_name );
- if( !p_item ) return VLC_SUCCESS;
+ VLC_UNUSED( p_this); VLC_UNUSED( psz_name );
- /* Clear-up the current list */
- if( p_item->i_list )
- {
- int i;
+ *values = xmalloc( (nb_devices + 1) * sizeof(char *) );
+ *descs = xmalloc( (nb_devices + 1) * sizeof(char *) );
- /* Keep the first entry */
- for( i = 1; i < p_item->i_list; i++ )
- {
- free((char *)(p_item->ppsz_list[i]) );
- free((char *)(p_item->ppsz_list_text[i]) );
- }
- /* TODO: Remove when no more needed */
- p_item->ppsz_list[i] = NULL;
- p_item->ppsz_list_text[i] = NULL;
- }
- p_item->i_list = 1;
-
- int wave_devices = waveOutGetNumDevs();
-
- p_item->ppsz_list = xrealloc( p_item->ppsz_list,
- (wave_devices+2) * sizeof(char *) );
- p_item->ppsz_list_text = xrealloc( p_item->ppsz_list_text,
- (wave_devices+2) * sizeof(char *) );
+ (*values)[n] = strdup( "wavemapper" );
+ (*descs)[n] = strdup( _("Microsoft Soundmapper") );
+ n++;
- int j=1;
- for(int i=0; i<wave_devices; i++)
+ for(int i = 0; i < nb_devices; i++)
{
WAVEOUTCAPS caps;
wchar_t dev_name[MAXPNAMELEN+32];
continue;
_snwprintf(dev_name, MAXPNAMELEN + 32, device_name_fmt,
- caps.szPname, caps.wMid, caps.wPid);
- p_item->ppsz_list[j] = FromWide( dev_name );
- p_item->ppsz_list_text[j] = FromWide( dev_name );
- p_item->i_list++;
- j++;
+ caps.szPname, caps.wMid, caps.wPid);
+ (*values)[n] = FromWide( dev_name );
+ (*descs)[n] = strdup( (*values)[n] );
+ n++;
}
- p_item->ppsz_list[j] = NULL;
- p_item->ppsz_list_text[j] = NULL;
- return VLC_SUCCESS;
+ return n;
}
/*
return WAVE_MAPPER;
}
+
+static int Open(vlc_object_t *obj)
+{
+ audio_output_t *aout = (audio_output_t *)obj;
+ aout_sys_t *sys = malloc(sizeof (*sys));
+
+ if (unlikely(sys == NULL))
+ return VLC_ENOMEM;
+ aout->sys = sys;
+ aout->start = Start;
+ aout->stop = Stop;
+ /* FIXME: volume handlers */
+ return VLC_SUCCESS;
+}
+
+static void Close(vlc_object_t *obj)
+{
+ audio_output_t *aout = (audio_output_t *)obj;
+ aout_sys_t *sys = aout->sys;
+
+ free(sys);
+}