/*****************************************************************************
* 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 "config.h"
#endif
+#include <stdio.h>
+#include <math.h>
+#include <wchar.h>
+
+#define UNICODE
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_aout.h>
-#include <vlc_aout_intf.h>
-#include <vlc_charset.h> /* FromLocaleDup, LocaleFree */
+#include <vlc_charset.h> /* FromWide() */
#include <vlc_atomic.h>
#include "windows_audio_common.h"
*****************************************************************************/
static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * );
-static void Play ( audio_output_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,
vlc_fourcc_t*, int, int, int, bool );
static int PlayWaveOut ( audio_output_t *, HWAVEOUT, WAVEHDR *,
- aout_buffer_t *, bool );
+ block_t *, bool );
-static void CALLBACK WaveOutCallback ( HWAVEOUT, UINT, DWORD, DWORD, DWORD );
+static void CALLBACK WaveOutCallback ( HWAVEOUT, UINT, DWORD_PTR, DWORD_PTR, DWORD_PTR );
static void* WaveOutThread( void * );
-static int VolumeSet( audio_output_t *, float, bool );
+static int VolumeSet( audio_output_t *, float );
+static int MuteSet( audio_output_t *, bool );
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 char psz_device_name_fmt[] = "%s ($%x,$%x)";
-
-static const char *const ppsz_adev[] = { "wavemapper", };
-static const char *const ppsz_adev_text[] = { N_("Microsoft Soundmapper") };
-
-
-/*****************************************************************************
- * Module descriptor
- *****************************************************************************/
-#define DEVICE_TEXT N_("Select Audio Device")
-#define DEVICE_LONG N_("Select special Audio device, or let windows "\
- "decide (default), change needs VLC restart "\
- "to apply.")
-#define DEFAULT_AUDIO_DEVICE N_("Default Audio Device")
-
-vlc_module_begin ()
- set_shortname( "WaveOut" )
- set_description( N_("Win32 waveOut extension output") )
- set_capability( "audio output", 50 )
- set_category( CAT_AUDIO )
- set_subcategory( SUBCAT_AUDIO_AOUT )
- add_bool( "waveout-float32", true, FLOAT_TEXT, FLOAT_LONGTEXT, true )
-
- add_string( "waveout-audio-device", "wavemapper",
- DEVICE_TEXT, DEVICE_LONG, false )
- add_deprecated_alias( "waveout-dev" ) /* deprecated since 0.9.3 */
- change_string_list( ppsz_adev, ppsz_adev_text, ReloadWaveoutDevices )
- change_action_add( ReloadWaveoutDevices, N_("Refresh list") )
-
- set_callbacks( Open, Close )
-vlc_module_end ()
+static const wchar_t device_name_fmt[] = L"%ls ($%x,$%x)";
/*****************************************************************************
* aout_sys_t: waveOut audio output method descriptor
*****************************************************************************/
struct aout_sys_t
{
+ aout_packet_t packet;
uint32_t i_wave_device_id; /* ID of selected output device */
HWAVEOUT h_waveout; /* handle to waveout instance */
uint8_t *p_silence_buffer; /* buffer we use to play silence */
- bool b_chan_reorder; /* do we need channel reordering */
- int pi_chan_table[AOUT_CHAN_MAX];
+ union {
+ float volume;
+ float soft_gain;
+ };
+ union {
+ bool mute;
+ bool soft_mute;
+ };
+
+ uint8_t chans_to_reorder; /* do we need channel reordering */
+ uint8_t chan_table[AOUT_CHAN_MAX];
};
+#include "volume.h"
+
/*****************************************************************************
- * Open: open the audio device
- *****************************************************************************
- * This function opens and setups Win32 waveOut
+ * Module descriptor
*****************************************************************************/
-static int Open( vlc_object_t *p_this )
-{
- audio_output_t *p_aout = (audio_output_t *)p_this;
- vlc_value_t val;
+#define DEVICE_TEXT N_("Select Audio Device")
+#define DEVICE_LONG N_("Select special Audio device, or let windows "\
+ "decide (default), change needs VLC restart "\
+ "to apply.")
+#define DEFAULT_AUDIO_DEVICE N_("Default Audio Device")
+
+vlc_module_begin ()
+ set_shortname( "WaveOut" )
+ set_description( N_("Win32 waveOut extension output") )
+ set_capability( "audio output", 50 )
+ set_category( CAT_AUDIO )
+ set_subcategory( SUBCAT_AUDIO_AOUT )
- /* Allocate structure */
- p_aout->sys = malloc( sizeof( aout_sys_t ) );
+ add_string( "waveout-audio-device", "wavemapper",
+ DEVICE_TEXT, DEVICE_LONG, false )
+ change_string_cb( ReloadWaveoutDevices )
+ add_sw_gain( )
- if( p_aout->sys == NULL )
- return VLC_ENOMEM;
+ add_bool( "waveout-float32", true, FLOAT_TEXT, FLOAT_LONGTEXT, true )
- p_aout->pf_play = Play;
- p_aout->pf_pause = NULL;
+ set_callbacks( Open, Close )
+vlc_module_end ()
- /*
- initialize/update Device selection List
- */
- ReloadWaveoutDevices( p_this, "waveout-audio-device", val, val, NULL);
+/*****************************************************************************
+ * Opens the audio device
+ *****************************************************************************
+ * This function opens and setups Win32 waveOut
+ *****************************************************************************/
+static int Start( audio_output_t *p_aout, audio_sample_format_t *restrict fmt )
+{
+ vlc_value_t val;
+ p_aout->time_get = aout_PacketTimeGet;
+ p_aout->play = Play;
+ p_aout->pause = NULL;
+ p_aout->flush = aout_PacketFlush;
/*
check for configured audio device!
{
/* log debug some infos about driver, to know who to blame
if it doesn't work */
- msg_Dbg( p_aout, "Drivername: %s", waveoutcaps.szPname);
+ msg_Dbg( p_aout, "Drivername: %ls", waveoutcaps.szPname);
msg_Dbg( p_aout, "Driver Version: %d.%d",
(waveoutcaps.vDriverVersion>>8)&255,
waveoutcaps.vDriverVersion & 255);
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->i_nb_samples = A52_FRAME_NB;
- 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;
+ 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_VolumeNoneInit( p_aout );
+ 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 */
- p_aout->i_nb_samples = FRAME_SIZE;
- 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_VolumeSoftInit( p_aout );
+ aout_PacketInit( p_aout, &p_aout->sys->packet, FRAME_SIZE, fmt );
/* Check for hardware volume support */
if( waveOutGetDevCaps( (UINT_PTR)p_aout->sys->h_waveout,
- &wocaps, sizeof(wocaps) ) == MMSYSERR_NOERROR &&
- wocaps.dwSupport & WAVECAPS_VOLUME )
- {
- DWORD i_dummy;
- if( waveOutGetVolume( p_aout->sys->h_waveout, &i_dummy )
- == MMSYSERR_NOERROR )
- {
- p_aout->pf_volume_set = VolumeSet;
- }
+ &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
+ aout_SoftVolumeInit( p_aout );
}
-
waveOutReset( p_aout->sys->h_waveout );
/* Allocate silence buffer */
malloc( p_aout->sys->i_buffer_size );
if( p_aout->sys->p_silence_buffer == NULL )
{
+ aout_PacketDestroy( p_aout );
free( p_aout->sys );
return VLC_ENOMEM;
}
/*****************************************************************************
* 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_NON_LINEAR( &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" );
}
var_AddCallback( p_aout, "audio-device", aout_ChannelsRestart, NULL );
- var_TriggerCallback( p_aout, "intf-change" );
}
/*****************************************************************************
* 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 )
+static void Play( audio_output_t *_p_aout, block_t *block )
{
if( !_p_aout->sys->b_playing )
{
_p_aout->sys->b_playing = 1;
/* get the playing date of the first aout buffer */
- _p_aout->sys->start_date =
- aout_FifoFirstDate( &_p_aout->fifo );
+ _p_aout->sys->start_date = block->i_pts;
msg_Dbg( _p_aout, "Wakeup sleeping output thread.");
} else {
SetEvent( _p_aout->sys->new_buffer_event );
}
+
+ 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 */
CloseHandle( p_sys->new_buffer_event);
free( p_sys->p_silence_buffer );
- free( p_sys );
+ aout_PacketDestroy( p_aout );
}
/*****************************************************************************
#define waveformat p_aout->sys->waveformat
waveformat.dwChannelMask = 0;
- for( unsigned i = 0; i < sizeof(pi_channels_src)/sizeof(uint32_t); i++ )
- {
- if( i_channels & pi_channels_src[i] )
+ for( unsigned i = 0; pi_vlc_chan_order_wg4[i]; i++ )
+ if( i_channels & pi_vlc_chan_order_wg4[i] )
waveformat.dwChannelMask |= pi_channels_in[i];
- }
switch( i_format )
{
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;
* PlayWaveOut: play a buffer through the WaveOut device
*****************************************************************************/
static int PlayWaveOut( audio_output_t *p_aout, HWAVEOUT h_waveout,
- WAVEHDR *p_waveheader, aout_buffer_t *p_buffer,
- bool b_spdif)
+ WAVEHDR *p_waveheader, block_t *p_buffer, bool b_spdif)
{
MMRESULT result;
*/
if(b_spdif)
{
- vlc_memcpy( p_aout->sys->p_silence_buffer,
+ memcpy( p_aout->sys->p_silence_buffer,
p_buffer->p_buffer,
p_aout->sys->i_buffer_size );
p_aout->sys->i_repeat_counter = 2;
p_aout->sys->i_repeat_counter--;
if(!p_aout->sys->i_repeat_counter)
{
- vlc_memset( p_aout->sys->p_silence_buffer,
+ memset( p_aout->sys->p_silence_buffer,
0x00, p_aout->sys->i_buffer_size );
}
}
* WaveOutCallback: what to do once WaveOut has played its sound samples
*****************************************************************************/
static void CALLBACK WaveOutCallback( HWAVEOUT h_waveout, UINT uMsg,
- DWORD _p_aout,
- DWORD dwParam1, DWORD dwParam2 )
+ DWORD_PTR _p_aout,
+ DWORD_PTR dwParam1, DWORD_PTR dwParam2 )
{
(void)h_waveout; (void)dwParam1; (void)dwParam2;
audio_output_t *p_aout = (audio_output_t *)_p_aout;
/****************************************************************************
- * WaveOutClearDoneBuffers: Clear all done marked buffers, and free aout_bufer
+ * WaveOutClearDoneBuffers: Clear all done marked buffers, and free buffer
****************************************************************************
* return value is the number of still playing buffers in the queue
****************************************************************************/
if( (p_waveheader[i].dwFlags & WHDR_DONE) &&
p_waveheader[i].dwUser )
{
- aout_buffer_t *p_buffer =
- (aout_buffer_t *)(p_waveheader[i].dwUser);
+ block_t *p_buffer =
+ (block_t *)(p_waveheader[i].dwUser);
/* Unprepare and free the buffers which has just been played */
waveOutUnprepareHeader( p_sys->h_waveout, &p_waveheader[i],
sizeof(WAVEHDR) );
if( p_waveheader[i].dwUser != 1 )
- aout_BufferFree( p_buffer );
+ block_Release( p_buffer );
p_waveheader[i].dwUser = 0;
}
{
audio_output_t *p_aout = data;
aout_sys_t *p_sys = p_aout->sys;
- aout_buffer_t *p_buffer = NULL;
+ block_t *p_buffer = NULL;
WAVEHDR *p_waveheader = p_sys->waveheader;
int i, i_queued_frames;
bool b_sleek;
mtime_t next_date;
- uint32_t i_buffer_length = 64;
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) )
// than wait a short time... before grabbing first frames
mwait( p_sys->start_date - AOUT_MAX_PTS_ADVANCE/4 );
-#define waveout_warn(msg) msg_Warn( p_aout, "aout_OutputNextBuffer no buffer "\
+#define waveout_warn(msg) msg_Warn( p_aout, "aout_PacketNext no buffer "\
"got next_date=%d ms, "\
"%d frames to play, %s",\
(int)(next_date/(mtime_t)1000), \
/* Take into account the latency */
- p_buffer = aout_OutputNextBuffer( p_aout,
- next_date,
- b_sleek );
-
+ p_buffer = aout_PacketNext( p_aout, next_date );
if(!p_buffer)
{
#if 0
- msg_Dbg( p_aout, "aout_OutputNextBuffer no buffer "
- "got next_date=%d ms, "
- "%d frames to play",
- (int)(next_date/(mtime_t)1000),
- i_queued_frames);
+ msg_Dbg( p_aout, "aout_PacketNext no buffer got "
+ "next_date=%"PRId64" ms, %d frames to play",
+ next_date/1000, i_queued_frames);
#endif
// means we are too early to request a new buffer?
waveout_warn("waiting...")
- next_date = aout_FifoFirstDate( &p_aout->fifo );
mwait( next_date - AOUT_MAX_PTS_ADVANCE/4 );
next_date = mdate();
- p_buffer = aout_OutputNextBuffer( p_aout, next_date,
- b_sleek );
+ p_buffer = aout_PacketNext( p_aout, next_date );
}
if( !p_buffer && i_queued_frames )
{
mtime_t buffer_length = p_buffer->i_length;
next_date = next_date + buffer_length;
- i_buffer_length = buffer_length/1000;
}
/* 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;
}
-static int VolumeSet( audio_output_t * p_aout, float volume, bool mute )
+static int VolumeSet( audio_output_t *aout, float volume )
{
- if( mute )
- volume = 0.;
+ aout_sys_t *sys = aout->sys;
+ const HWAVEOUT hwo = sys->h_waveout;
+ const float full = 0xffff.fp0;
- unsigned long i_waveout_vol = volume
- * (0xFFFF * AOUT_VOLUME_DEFAULT / AOUT_VOLUME_MAX);
+ volume *= full;
+ if( volume >= full )
+ return -1;
- if( i_waveout_vol <= 0xFFFF )
- i_waveout_vol |= i_waveout_vol << 16;
- else
- i_waveout_vol = 0xFFFFFFFF;
+ sys->volume = volume;
+ if( sys->mute )
+ return 0;
-#ifdef UNDER_CE
- waveOutSetVolume( 0, i_waveout_vol );
-#else
- waveOutSetVolume( p_aout->sys->h_waveout, i_waveout_vol );
-#endif
+ uint16_t vol = lroundf(volume);
+ waveOutSetVolume( hwo, vol | (vol << 16) );
return 0;
}
+static int MuteSet( audio_output_t * p_aout, bool mute )
+{
+ aout_sys_t *sys = p_aout->sys;
+ const HWAVEOUT hwo = sys->h_waveout;
+ uint16_t vol = mute ? 0 : lroundf(sys->volume);
+
+ sys->mute = mute;
+ waveOutSetVolume( hwo, vol | (vol << 16) );
+ return 0;
+}
/*
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 );
-
- module_config_t *p_item = config_FindConfig( p_this, psz_name );
- if( !p_item ) return VLC_SUCCESS;
+ int n = 0, nb_devices = waveOutGetNumDevs();
- /* Clear-up the current list */
- if( p_item->i_list )
- {
- int i;
+ VLC_UNUSED( p_this); VLC_UNUSED( psz_name );
- /* 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;
+ *values = xmalloc( (nb_devices + 1) * sizeof(char *) );
+ *descs = xmalloc( (nb_devices + 1) * sizeof(char *) );
- int wave_devices = waveOutGetNumDevs();
+ (*values)[n] = strdup( "wavemapper" );
+ (*descs)[n] = strdup( _("Microsoft Soundmapper") );
+ n++;
- 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 *) );
-
- WAVEOUTCAPS caps;
- char sz_dev_name[MAXPNAMELEN+32];
- int j=1;
- for(int i=0; i<wave_devices; i++)
+ for(int i = 0; i < nb_devices; i++)
{
- if(waveOutGetDevCaps(i, &caps, sizeof(WAVEOUTCAPS))
- == MMSYSERR_NOERROR)
- {
- sprintf( sz_dev_name, psz_device_name_fmt, caps.szPname,
- caps.wMid,
- caps.wPid
- );
- p_item->ppsz_list[j] = FromLocaleDup( sz_dev_name );
- p_item->ppsz_list_text[j] = FromLocaleDup( sz_dev_name );
- p_item->i_list++;
- j++;
- }
+ WAVEOUTCAPS caps;
+ wchar_t dev_name[MAXPNAMELEN+32];
+ if(waveOutGetDevCaps(i, &caps, sizeof(WAVEOUTCAPS))
+ != MMSYSERR_NOERROR)
+ continue;
+
+ _snwprintf(dev_name, MAXPNAMELEN + 32, device_name_fmt,
+ 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;
-
- /* Signal change to the interface */
- p_item->b_dirty = true;
- return VLC_SUCCESS;
+ return n;
}
/*
return WAVE_MAPPER;
uint32_t wave_devices = waveOutGetNumDevs();
- WAVEOUTCAPS caps;
- char sz_dev_name[MAXPNAMELEN+32];
for( uint32_t i = 0; i < wave_devices; i++ )
{
+ WAVEOUTCAPS caps;
+ wchar_t dev_name[MAXPNAMELEN+32];
+
if( waveOutGetDevCaps( i, &caps, sizeof(WAVEOUTCAPS) )
- == MMSYSERR_NOERROR)
- {
- sprintf( sz_dev_name, psz_device_name_fmt, caps.szPname,
- caps.wMid,
- caps.wPid
- );
- char *psz_temp = FromLocaleDup(sz_dev_name);
+ != MMSYSERR_NOERROR )
+ continue;
- if( !stricmp(psz_temp, psz_device_name) )
- {
- LocaleFree( psz_temp );
- return i;
- }
- LocaleFree( psz_temp );
+ _snwprintf( dev_name, MAXPNAMELEN + 32, device_name_fmt,
+ caps.szPname, caps.wMid, caps.wPid );
+ char *u8 = FromWide(dev_name);
+ if( !stricmp(u8, psz_device_name) )
+ {
+ free( u8 );
+ return i;
}
+ free( u8 );
}
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);
+}