* directx.c: Windows DirectX audio output method
*****************************************************************************
* Copyright (C) 2001 VideoLAN
- * $Id: directx.c,v 1.15 2003/03/03 14:21:08 gbazin Exp $
+ * $Id$
*
- * Authors: Gildas Bazin <gbazin@netcourrier.com>
+ * Authors: Gildas Bazin <gbazin@videolan.org>
*
* 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
#include <dsound.h>
#define FRAME_SIZE 2048 /* The size is in samples, not in bytes */
-#define FRAMES_NUM 4
+#define FRAMES_NUM 8
/* frame buffer status */
#define FRAME_QUEUED 0
} WAVEFORMATEXTENSIBLE, *PWAVEFORMATEXTENSIBLE;
#endif
-#ifndef KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
-DEFINE_GUID( KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, WAVE_FORMAT_IEEE_FLOAT, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 );
-#endif
-#ifndef KSDATAFORMAT_SUBTYPE_PCM
-DEFINE_GUID( KSDATAFORMAT_SUBTYPE_PCM, WAVE_FORMAT_PCM, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 );
-#endif
-#ifndef KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF
-DEFINE_GUID( KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF, WAVE_FORMAT_DOLBY_AC3_SPDIF, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 );
-#endif
+DEFINE_GUID( _KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, WAVE_FORMAT_IEEE_FLOAT, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 );
+DEFINE_GUID( _KSDATAFORMAT_SUBTYPE_PCM, WAVE_FORMAT_PCM, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 );
+DEFINE_GUID( _KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF, WAVE_FORMAT_DOLBY_AC3_SPDIF, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 );
/*****************************************************************************
* notification_thread_t: DirectX event thread
int i_frame_size; /* Size in bytes of one frame */
vlc_bool_t b_chan_reorder; /* do we need channel reordering */
- int *pi_chan_table;
+ int pi_chan_table[AOUT_CHAN_MAX];
uint32_t i_channel_mask;
+ uint32_t i_bits_per_sample;
+ uint32_t i_channels;
};
-static const uint32_t pi_channels_in[] =
+static const uint32_t pi_channels_src[] =
{ AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT,
+ AOUT_CHAN_MIDDLELEFT, AOUT_CHAN_MIDDLERIGHT,
AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT,
- AOUT_CHAN_CENTER, AOUT_CHAN_LFE };
+ AOUT_CHAN_CENTER, AOUT_CHAN_LFE, 0 };
+static const uint32_t pi_channels_in[] =
+ { SPEAKER_FRONT_LEFT, SPEAKER_FRONT_RIGHT,
+ SPEAKER_SIDE_LEFT, SPEAKER_SIDE_RIGHT,
+ SPEAKER_BACK_LEFT, SPEAKER_BACK_RIGHT,
+ SPEAKER_FRONT_CENTER, SPEAKER_LOW_FREQUENCY, 0 };
static const uint32_t pi_channels_out[] =
{ SPEAKER_FRONT_LEFT, SPEAKER_FRONT_RIGHT,
+ SPEAKER_FRONT_CENTER, SPEAKER_LOW_FREQUENCY,
SPEAKER_BACK_LEFT, SPEAKER_BACK_RIGHT,
- SPEAKER_FRONT_CENTER, SPEAKER_LOW_FREQUENCY };
-static const uint32_t pi_channels_ordered[] =
- { SPEAKER_FRONT_LEFT, SPEAKER_FRONT_RIGHT, SPEAKER_FRONT_CENTER,
- SPEAKER_LOW_FREQUENCY,
- SPEAKER_BACK_LEFT, SPEAKER_BACK_RIGHT };
+ SPEAKER_SIDE_LEFT, SPEAKER_SIDE_RIGHT, 0 };
/*****************************************************************************
* Local prototypes.
static void DirectSoundThread ( notification_thread_t * );
static int FillBuffer ( aout_instance_t *, int, aout_buffer_t * );
-static void CheckReordering ( aout_instance_t *, int );
-static void InterleaveFloat32 ( float *, float *, int *, int );
-static void InterleaveS16 ( int16_t *, int16_t *, int *, int );
-
/*****************************************************************************
* Module descriptor
*****************************************************************************/
vlc_module_begin();
- set_description( _("DirectX audio module") );
+ set_description( _("DirectX audio output") );
+ set_shortname( "DirectX" );
set_capability( "audio output", 100 );
+ set_category( CAT_AUDIO );
+ set_subcategory( SUBCAT_AUDIO_AOUT );
add_shortcut( "directx" );
set_callbacks( OpenAudio, CloseAudio );
vlc_module_end();
p_aout->output.p_sys->p_dsnotify = NULL;
p_aout->output.p_sys->p_notif = NULL;
p_aout->output.p_sys->b_playing = 0;
- p_aout->output.p_sys->pi_chan_table = NULL;
p_aout->output.pf_play = Play;
aout_VolumeSoftInit( p_aout );
goto error;
}
- /* Now we need to setup our DirectSound play notification structure */
- p_aout->output.p_sys->p_notif =
- vlc_object_create( p_aout, sizeof(notification_thread_t) );
- p_aout->output.p_sys->p_notif->p_aout = p_aout;
-
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_aout->output.p_sys );
- return VLC_EGENERIC;
+ goto error;
}
+ /* Now we need to setup our DirectSound play notification structure */
+ p_aout->output.p_sys->p_notif =
+ vlc_object_create( p_aout, sizeof(notification_thread_t) );
+ p_aout->output.p_sys->p_notif->p_aout = p_aout;
+
/* Then create the notification events */
for( i = 0; i < FRAMES_NUM; i++ )
p_aout->output.p_sys->p_notif->p_events[i].hEventNotify =
CreateEvent( NULL, FALSE, FALSE, NULL );
/* Open the device */
- if( !strcmp( val.psz_string, N_("A/52 over S/PDIF") ) )
+ if( val.i_int == AOUT_VAR_SPDIF )
{
- free( val.psz_string );
p_aout->output.output.i_format = VLC_FOURCC('s','p','d','i');
/* Calculate the frame size in bytes */
p_aout->output.p_sys->i_frame_size, VLC_FALSE )
!= VLC_SUCCESS )
{
- msg_Err( p_aout, "cannot open waveout audio device" );
+ msg_Err( p_aout, "cannot open directx audio device" );
free( p_aout->output.p_sys );
return VLC_EGENERIC;
}
}
else
{
- if( !strcmp( val.psz_string, N_("5.1") ) )
+ if( val.i_int == AOUT_VAR_5_1 )
{
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;
}
- else if( !strcmp( val.psz_string, N_("2 Front 2 Rear") ) )
+ else if( val.i_int == AOUT_VAR_3F2R )
+ {
+ p_aout->output.output.i_physical_channels
+ = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
+ | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
+ }
+ else if( val.i_int == AOUT_VAR_2F2R )
{
p_aout->output.output.i_physical_channels
= AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
| AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
}
- else if( !strcmp( val.psz_string, "Mono" ) )
+ else if( val.i_int == AOUT_VAR_MONO )
{
p_aout->output.output.i_physical_channels = AOUT_CHAN_CENTER;
}
p_aout->output.output.i_physical_channels
= AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
}
- free( val.psz_string );
if( CreateDSBufferPCM( p_aout, &p_aout->output.output.i_format,
p_aout->output.output.i_physical_channels,
p_aout->output.output.i_rate, VLC_FALSE )
!= VLC_SUCCESS )
{
- msg_Err( p_aout, "cannot open waveout audio device" );
+ msg_Err( p_aout, "cannot open directx audio device" );
free( p_aout->output.p_sys );
return VLC_EGENERIC;
}
*****************************************************************************/
static void Probe( aout_instance_t * p_aout )
{
- vlc_value_t val;
+ vlc_value_t val, text;
int i_format;
unsigned int i_physical_channels;
DWORD ui_speaker_config;
- var_Create( p_aout, "audio-device", VLC_VAR_STRING | VLC_VAR_HASCHOICE );
+ var_Create( p_aout, "audio-device", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE );
+ text.psz_string = _("Audio Device");
+ var_Change( p_aout, "audio-device", VLC_VAR_SETTEXT, &text, NULL );
/* Test for 5.1 support */
i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
p_aout->output.output.i_rate, VLC_TRUE )
== VLC_SUCCESS )
{
- val.psz_string = N_("5.1");
- var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val );
+ val.i_int = AOUT_VAR_5_1;
+ text.psz_string = N_("5.1");
+ var_Change( p_aout, "audio-device",
+ VLC_VAR_ADDCHOICE, &val, &text );
msg_Dbg( p_aout, "device supports 5.1 channels" );
}
}
+ /* Test for 3 Front 2 Rear support */
+ i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
+ AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT |
+ AOUT_CHAN_REARRIGHT;
+ if( p_aout->output.output.i_physical_channels == i_physical_channels )
+ {
+ if( CreateDSBufferPCM( p_aout, &i_format, i_physical_channels, 5,
+ p_aout->output.output.i_rate, VLC_TRUE )
+ == VLC_SUCCESS )
+ {
+ val.i_int = AOUT_VAR_3F2R;
+ text.psz_string = N_("3 Front 2 Rear");
+ var_Change( p_aout, "audio-device",
+ VLC_VAR_ADDCHOICE, &val, &text );
+ msg_Dbg( p_aout, "device supports 5 channels" );
+ }
+ }
+
/* Test for 2 Front 2 Rear support */
i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
p_aout->output.output.i_rate, VLC_TRUE )
== VLC_SUCCESS )
{
- val.psz_string = N_("2 Front 2 Rear");
- var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val );
+ val.i_int = AOUT_VAR_2F2R;
+ text.psz_string = N_("2 Front 2 Rear");
+ var_Change( p_aout, "audio-device",
+ VLC_VAR_ADDCHOICE, &val, &text );
msg_Dbg( p_aout, "device supports 4 channels" );
}
}
p_aout->output.output.i_rate, VLC_TRUE )
== VLC_SUCCESS )
{
- val.psz_string = N_("Stereo");
- var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val );
+ val.i_int = AOUT_VAR_STEREO;
+ text.psz_string = N_("Stereo");
+ var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val, &text );
+ var_Change( p_aout, "audio-device", VLC_VAR_SETDEFAULT, &val, NULL );
msg_Dbg( p_aout, "device supports 2 channels" );
}
p_aout->output.output.i_rate, VLC_TRUE )
== VLC_SUCCESS )
{
- val.psz_string = N_("Mono");
- var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val );
+ val.i_int = AOUT_VAR_MONO;
+ text.psz_string = N_("Mono");
+ var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val, &text );
msg_Dbg( p_aout, "device supports 1 channel" );
}
switch( DSSPEAKER_CONFIG(ui_speaker_config) )
{
case DSSPEAKER_5POINT1:
- val.psz_string = N_("5.1");
+ val.i_int = AOUT_VAR_5_1;
break;
case DSSPEAKER_QUAD:
- val.psz_string = N_("2 Front 2 Rear");
+ val.i_int = AOUT_VAR_2F2R;
break;
+#if 0 /* Lots of people just get their settings wrong and complain that
+ * this is a problem with VLC so just don't ever set mono by default. */
case DSSPEAKER_MONO:
- val.psz_string = N_("Mono");
+ val.i_int = AOUT_VAR_MONO;
break;
+#endif
case DSSPEAKER_SURROUND:
case DSSPEAKER_STEREO:
default:
- val.psz_string = N_("Stereo");
+ val.i_int = AOUT_VAR_STEREO;
break;
}
var_Set( p_aout, "audio-device", val );
== VLC_SUCCESS )
{
msg_Dbg( p_aout, "device supports A/52 over S/PDIF" );
- val.psz_string = N_("A/52 over S/PDIF");
- var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val );
+ val.i_int = AOUT_VAR_SPDIF;
+ text.psz_string = N_("A/52 over S/PDIF");
+ var_Change( p_aout, "audio-device",
+ VLC_VAR_ADDCHOICE, &val, &text );
if( config_GetInt( p_aout, "spdif" ) )
var_Set( p_aout, "audio-device", val );
}
}
+ var_Change( p_aout, "audio-device", VLC_VAR_CHOICESCOUNT, &val, NULL );
+ if( val.i_int <= 0 )
+ {
+ /* Probe() has failed. */
+ var_Destroy( p_aout, "audio-device" );
+ return;
+ }
+
var_AddCallback( p_aout, "audio-device", aout_ChannelsRestart, NULL );
val.b_bool = VLC_TRUE;
static void CloseAudio( vlc_object_t *p_this )
{
aout_instance_t * p_aout = (aout_instance_t *)p_this;
+ aout_sys_t *p_sys = p_aout->output.p_sys;
msg_Dbg( p_aout, "CloseAudio" );
/* kill the position notification thread, if any */
- if( p_aout->output.p_sys->p_notif )
+ if( p_sys->p_notif )
{
- vlc_object_detach( p_aout->output.p_sys->p_notif );
- if( p_aout->output.p_sys->p_notif->b_thread )
+ vlc_object_detach( p_sys->p_notif );
+ if( p_sys->p_notif->b_thread )
{
- p_aout->output.p_sys->p_notif->b_die = 1;
+ p_sys->p_notif->b_die = 1;
- if( !p_aout->output.p_sys->b_playing )
+ if( !p_sys->b_playing )
/* wake up the audio thread */
- SetEvent(
- p_aout->output.p_sys->p_notif->p_events[0].hEventNotify );
+ SetEvent( p_sys->p_notif->p_events[0].hEventNotify );
- vlc_thread_join( p_aout->output.p_sys->p_notif );
+ vlc_thread_join( p_sys->p_notif );
}
- vlc_object_destroy( p_aout->output.p_sys->p_notif );
+ vlc_object_destroy( p_sys->p_notif );
}
/* release the secondary buffer */
DestroyDSBuffer( p_aout );
/* finally release the DirectSound object */
- if( p_aout->output.p_sys->p_dsobject )
- IDirectSound_Release( p_aout->output.p_sys->p_dsobject );
+ if( p_sys->p_dsobject ) IDirectSound_Release( p_sys->p_dsobject );
/* free DSOUND.DLL */
- if( p_aout->output.p_sys->hdsound_dll )
- FreeLibrary( p_aout->output.p_sys->hdsound_dll );
-
- if( p_aout->output.p_sys->pi_chan_table )
- free( p_aout->output.p_sys->pi_chan_table );
+ if( p_sys->hdsound_dll ) FreeLibrary( p_sys->hdsound_dll );
- free( p_aout->output.p_sys );
+ free( p_sys );
}
/*****************************************************************************
/* First set the sound buffer format */
waveformat.dwChannelMask = 0;
- for( i = 0; i < sizeof(pi_channels_in)/sizeof(uint32_t); i++ )
+ for( i = 0; i < sizeof(pi_channels_src)/sizeof(uint32_t); i++ )
{
- if( i_channels & pi_channels_in[i] )
- waveformat.dwChannelMask |= pi_channels_out[i];
+ if( i_channels & pi_channels_src[i] )
+ waveformat.dwChannelMask |= pi_channels_in[i];
}
switch( i_format )
waveformat.Samples.wValidBitsPerSample =
waveformat.Format.wBitsPerSample;
waveformat.Format.wFormatTag = WAVE_FORMAT_DOLBY_AC3_SPDIF;
- waveformat.SubFormat = KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF;
+ waveformat.SubFormat = _KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF;
break;
case VLC_FOURCC('f','l','3','2'):
waveformat.Samples.wValidBitsPerSample =
waveformat.Format.wBitsPerSample;
waveformat.Format.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
- waveformat.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
+ waveformat.SubFormat = _KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
break;
case VLC_FOURCC('s','1','6','l'):
waveformat.Samples.wValidBitsPerSample =
waveformat.Format.wBitsPerSample;
waveformat.Format.wFormatTag = WAVE_FORMAT_PCM;
- waveformat.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
+ waveformat.SubFormat = _KSDATAFORMAT_SUBTYPE_PCM;
break;
}
waveformat.Format.nAvgBytesPerSec =
waveformat.Format.nSamplesPerSec * waveformat.Format.nBlockAlign;
+ p_aout->output.p_sys->i_bits_per_sample = waveformat.Format.wBitsPerSample;
+ p_aout->output.p_sys->i_channels = i_nb_channels;
+
+ /* Then fill in the direct sound descriptor */
+ memset(&dsbdesc, 0, sizeof(DSBUFFERDESC));
+ dsbdesc.dwSize = sizeof(DSBUFFERDESC);
+ dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2/* Better position accuracy */
+ | DSBCAPS_CTRLPOSITIONNOTIFY /* We need notification */
+ | DSBCAPS_GLOBALFOCUS; /* Allows background playing */
+
/* Only use the new WAVE_FORMAT_EXTENSIBLE format for multichannel audio */
if( i_nb_channels <= 2 )
{
waveformat.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
waveformat.Format.cbSize =
sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
- }
+ /* Needed for 5.1 on emu101k */
+ dsbdesc.dwFlags |= DSBCAPS_LOCHARDWARE;
+ }
- /* Then fill in the direct sound descriptor */
- memset(&dsbdesc, 0, sizeof(DSBUFFERDESC));
- dsbdesc.dwSize = sizeof(DSBUFFERDESC);
- dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2/* Better position accuracy */
- | DSBCAPS_CTRLPOSITIONNOTIFY /* We need notification */
- | DSBCAPS_GLOBALFOCUS; /* Allows background playing */
dsbdesc.dwBufferBytes = FRAMES_NUM * i_bytes_per_frame; /* buffer size */
dsbdesc.lpwfxFormat = (WAVEFORMATEX *)&waveformat;
p_aout->output.p_sys->p_dsobject, &dsbdesc,
&p_aout->output.p_sys->p_dsbuffer, NULL) )
{
- goto error;
+ if( dsbdesc.dwFlags & DSBCAPS_LOCHARDWARE )
+ {
+ /* Try without DSBCAPS_LOCHARDWARE */
+ dsbdesc.dwFlags &= ~DSBCAPS_LOCHARDWARE;
+ if FAILED( IDirectSound_CreateSoundBuffer(
+ p_aout->output.p_sys->p_dsobject, &dsbdesc,
+ &p_aout->output.p_sys->p_dsbuffer, NULL) )
+ {
+ return VLC_EGENERIC;
+ }
+ if( !b_probe )
+ msg_Dbg( p_aout, "couldn't use hardware sound buffer" );
+ }
+ else
+ {
+ return VLC_EGENERIC;
+ }
}
/* Stop here if we were just probing */
}
p_aout->output.p_sys->i_channel_mask = waveformat.dwChannelMask;
- CheckReordering( p_aout, i_nb_channels );
- return VLC_SUCCESS;
+ p_aout->output.p_sys->b_chan_reorder =
+ aout_CheckChannelReorder( pi_channels_in, pi_channels_out,
+ waveformat.dwChannelMask, i_nb_channels,
+ p_aout->output.p_sys->pi_chan_table );
- error:
- if( p_aout->output.p_sys->p_dsbuffer )
- {
- IDirectSoundBuffer_Release( p_aout->output.p_sys->p_dsbuffer );
- p_aout->output.p_sys->p_dsbuffer = NULL;
- }
- if( p_aout->output.p_sys->p_dsnotify )
+ if( p_aout->output.p_sys->b_chan_reorder )
{
- IDirectSoundBuffer_Release( p_aout->output.p_sys->p_dsbuffer );
- p_aout->output.p_sys->p_dsnotify = NULL;
+ msg_Dbg( p_aout, "channel reordering needed" );
}
+
+ return VLC_SUCCESS;
+
+ error:
+ DestroyDSBuffer( p_aout );
return VLC_EGENERIC;
}
int i_channels, int i_nb_channels, int i_rate,
vlc_bool_t b_probe )
{
- if( CreateDSBuffer( p_aout, VLC_FOURCC('f','l','3','2'),
+ /* Float32 audio samples are not supported for 5.1 output on the emu101k */
+
+ if( i_nb_channels > 2 ||
+ CreateDSBuffer( p_aout, VLC_FOURCC('f','l','3','2'),
i_channels, i_nb_channels, i_rate,
FRAME_SIZE * 4 * i_nb_channels, b_probe )
!= VLC_SUCCESS )
aout_buffer_t *p_buffer )
{
notification_thread_t *p_notif = p_aout->output.p_sys->p_notif;
+ aout_sys_t *p_sys = p_aout->output.p_sys;
void *p_write_position, *p_wrap_around;
long l_bytes1, l_bytes2;
HRESULT dsresult;
/* Before copying anything, we have to lock the buffer */
dsresult = IDirectSoundBuffer_Lock(
- p_aout->output.p_sys->p_dsbuffer, /* DS buffer */
+ p_sys->p_dsbuffer, /* DS buffer */
i_frame * p_notif->i_frame_size, /* Start offset */
p_notif->i_frame_size, /* Number of bytes */
&p_write_position, /* Address of lock start */
0 ); /* Flags */
if( dsresult == DSERR_BUFFERLOST )
{
- IDirectSoundBuffer_Restore( p_aout->output.p_sys->p_dsbuffer );
+ IDirectSoundBuffer_Restore( p_sys->p_dsbuffer );
dsresult = IDirectSoundBuffer_Lock(
- p_aout->output.p_sys->p_dsbuffer,
+ p_sys->p_dsbuffer,
i_frame * p_notif->i_frame_size,
p_notif->i_frame_size,
&p_write_position,
{
memset( p_write_position, 0, l_bytes1 );
}
- else if( p_aout->output.p_sys->b_chan_reorder )
- {
- /* Do the channel reordering here */
-
- if( p_aout->output.output.i_format == VLC_FOURCC('s','1','6','l') )
- InterleaveS16( (int16_t *)p_buffer->p_buffer,
- (int16_t *)p_write_position,
- p_aout->output.p_sys->pi_chan_table,
- aout_FormatNbChannels( &p_aout->output.output ) );
- else
- InterleaveFloat32( (float *)p_buffer->p_buffer,
- (float *)p_write_position,
- p_aout->output.p_sys->pi_chan_table,
- aout_FormatNbChannels( &p_aout->output.output ) );
- }
else
{
+ if( p_sys->b_chan_reorder )
+ {
+ /* Do the channel reordering here */
+ aout_ChannelReorder( p_buffer->p_buffer, p_buffer->i_nb_bytes,
+ p_sys->i_channels, p_sys->pi_chan_table,
+ p_sys->i_bits_per_sample );
+ }
+
p_aout->p_vlc->pf_memcpy( p_write_position, p_buffer->p_buffer,
l_bytes1 );
aout_BufferFree( p_buffer );
}
/* Now the data has been copied, unlock the buffer */
- IDirectSoundBuffer_Unlock( p_aout->output.p_sys->p_dsbuffer,
- p_write_position, l_bytes1,
+ IDirectSoundBuffer_Unlock( p_sys->p_dsbuffer, p_write_position, l_bytes1,
p_wrap_around, l_bytes2 );
return VLC_SUCCESS;
msg_Dbg( p_notif, "DirectSoundThread exiting" );
}
-
-/*****************************************************************************
- * CheckReordering: Check if we need to do some channel re-ordering (the ac3
- * channel order is different from the one chosen by
- * Microsoft).
- *****************************************************************************/
-static void CheckReordering( aout_instance_t *p_aout, int i_nb_channels )
-{
- int i, j, k, l;
-
-#define i_channel_mask p_aout->output.p_sys->i_channel_mask
-#define pi_chan_table p_aout->output.p_sys->pi_chan_table
-
- p_aout->output.p_sys->b_chan_reorder = VLC_FALSE;
-
- pi_chan_table = malloc( i_nb_channels * sizeof(int) );
- if( !pi_chan_table )
- {
- return;
- }
-
- for( i = 0, j = 0;
- i < (int)(sizeof(pi_channels_out)/sizeof(uint32_t)); i++ )
- {
- if( i_channel_mask & pi_channels_out[i] )
- {
- for( k = 0, l = 0;
- pi_channels_out[i] != pi_channels_ordered[k]; k++ )
- {
- if( i_channel_mask & pi_channels_ordered[k] )
- {
- l++;
- }
- }
-
- pi_chan_table[j] = l;
-
- j++;
- }
- }
-
- for( i = 0; i < i_nb_channels; i++ )
- {
- if( pi_chan_table[i] != i )
- {
- p_aout->output.p_sys->b_chan_reorder = VLC_TRUE;
- }
- }
-
- if( p_aout->output.p_sys->b_chan_reorder )
- {
- msg_Dbg( p_aout, "channel reordering needed" );
- }
-
-#undef pi_chan_table
-#undef waveformat
-}
-
-/*****************************************************************************
- * InterleaveFloat32/S16: change the channel order to the Microsoft one.
- *****************************************************************************/
-static void InterleaveFloat32( float *p_buf, float *p_buf_out,
- int *pi_chan_table, int i_nb_channels )
-{
- int i, j;
-
- for( i = 0; i < FRAME_SIZE; i++ )
- {
- for( j = 0; j < i_nb_channels; j++ )
- {
- p_buf_out[i*i_nb_channels + pi_chan_table[j]] =
- p_buf[i*i_nb_channels + j];
- }
- }
-}
-
-static void InterleaveS16( int16_t *p_buf, int16_t *p_buf_out,
- int *pi_chan_table, int i_nb_channels )
-{
- int i, j;
-
- for( i = 0; i < FRAME_SIZE; i++ )
- {
- for( j = 0; j < i_nb_channels; j++ )
- {
- p_buf_out[ i*i_nb_channels + pi_chan_table[j]] =
- p_buf[i*i_nb_channels + j];
- }
- }
-}