X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Faudio_output%2Fdirectx.c;h=9a41a8bd5e15bf3c98d02fa66185d20e9872ea7f;hb=12ade3e3bc975d5426ba4af155b7372c31093b31;hp=bbf9412a495606d92355d8e57025fe9d46cce25b;hpb=61eaa3fd2d1fb30aae22f0888018de3693b215af;p=vlc diff --git a/modules/audio_output/directx.c b/modules/audio_output/directx.c index bbf9412a49..9a41a8bd5e 100644 --- a/modules/audio_output/directx.c +++ b/modules/audio_output/directx.c @@ -17,8 +17,8 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU 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. + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ /***************************************************************************** @@ -34,105 +34,11 @@ #include #include -#include -#include +#include "windows_audio_common.h" + #include #define FRAME_SIZE ((int)p_aout->output.output.i_rate/20) /* Size in samples */ -#define FRAMES_NUM 8 /* Needs to be > 3 */ - -/***************************************************************************** - * DirectSound GUIDs. - * Defining them here allows us to get rid of the dxguid library during - * the linking stage. - *****************************************************************************/ -#include - -/***************************************************************************** - * Useful macros - *****************************************************************************/ -#ifndef WAVE_FORMAT_IEEE_FLOAT -# define WAVE_FORMAT_IEEE_FLOAT 0x0003 -#endif - -#ifndef WAVE_FORMAT_DOLBY_AC3_SPDIF -# define WAVE_FORMAT_DOLBY_AC3_SPDIF 0x0092 -#endif - -#ifndef WAVE_FORMAT_EXTENSIBLE -#define WAVE_FORMAT_EXTENSIBLE 0xFFFE -#endif - -#ifndef SPEAKER_FRONT_LEFT -# define SPEAKER_FRONT_LEFT 0x1 -# define SPEAKER_FRONT_RIGHT 0x2 -# define SPEAKER_FRONT_CENTER 0x4 -# define SPEAKER_LOW_FREQUENCY 0x8 -# define SPEAKER_BACK_LEFT 0x10 -# define SPEAKER_BACK_RIGHT 0x20 -# define SPEAKER_FRONT_LEFT_OF_CENTER 0x40 -# define SPEAKER_FRONT_RIGHT_OF_CENTER 0x80 -# define SPEAKER_BACK_CENTER 0x100 -# define SPEAKER_SIDE_LEFT 0x200 -# define SPEAKER_SIDE_RIGHT 0x400 -# define SPEAKER_TOP_CENTER 0x800 -# define SPEAKER_TOP_FRONT_LEFT 0x1000 -# define SPEAKER_TOP_FRONT_CENTER 0x2000 -# define SPEAKER_TOP_FRONT_RIGHT 0x4000 -# define SPEAKER_TOP_BACK_LEFT 0x8000 -# define SPEAKER_TOP_BACK_CENTER 0x10000 -# define SPEAKER_TOP_BACK_RIGHT 0x20000 -# define SPEAKER_RESERVED 0x80000000 -#endif - -#ifndef DSSPEAKER_DSSPEAKER_DIRECTOUT -# define DSSPEAKER_DSSPEAKER_DIRECTOUT 0x00000000 -#endif -#ifndef DSSPEAKER_HEADPHONE -# define DSSPEAKER_HEADPHONE 0x00000001 -#endif -#ifndef DSSPEAKER_MONO -# define DSSPEAKER_MONO 0x00000002 -#endif -#ifndef DSSPEAKER_QUAD -# define DSSPEAKER_QUAD 0x00000003 -#endif -#ifndef DSSPEAKER_STEREO -# define DSSPEAKER_STEREO 0x00000004 -#endif -#ifndef DSSPEAKER_SURROUND -# define DSSPEAKER_SURROUND 0x00000005 -#endif -#ifndef DSSPEAKER_5POINT1 -# define DSSPEAKER_5POINT1 0x00000006 -#endif -#ifndef DSSPEAKER_7POINT1 -# define DSSPEAKER_7POINT1 0x00000007 -#endif -#ifndef DSSPEAKER_7POINT1_SURROUND -# define DSSPEAKER_7POINT1_SURROUND 0x00000008 -#endif -#ifndef DSSPEAKER_7POINT1_WIDE -# define DSSPEAKER_7POINT1_WIDE DSSPEAKER_7POINT1 -#endif - -#ifndef _WAVEFORMATEXTENSIBLE_ -typedef struct { - WAVEFORMATEX Format; - union { - WORD wValidBitsPerSample; /* bits of precision */ - WORD wSamplesPerBlock; /* valid if wBitsPerSample==0 */ - WORD wReserved; /* If neither applies, set to zero. */ - } Samples; - DWORD dwChannelMask; /* which channels are */ - /* present in stream */ - GUID SubFormat; -} WAVEFORMATEXTENSIBLE, *PWAVEFORMATEXTENSIBLE; -#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 @@ -160,7 +66,7 @@ struct aout_sys_t { HINSTANCE hdsound_dll; /* handle of the opened dsound dll */ - char * psz_device; /* user defined device name */ + char * psz_device; /* user defined device name */ LPGUID p_device_guid; LPDIRECTSOUND p_dsobject; /* main Direct Sound object */ @@ -170,36 +76,19 @@ struct aout_sys_t notification_thread_t *p_notif; /* DirectSoundThread id */ - int b_playing; /* playing status */ + int b_playing; /* playing status */ - int i_frame_size; /* Size in bytes of one frame */ + int i_frame_size; /* Size in bytes of one frame */ - int i_speaker_setup; /* Speaker setup override */ + int i_speaker_setup; /* Speaker setup override */ - bool b_chan_reorder; /* do we need channel reordering */ - int pi_chan_table[AOUT_CHAN_MAX]; + bool b_chan_reorder; /* do we need channel reordering */ + 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_src[] = - { AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT, - AOUT_CHAN_MIDDLELEFT, AOUT_CHAN_MIDDLERIGHT, - AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT, AOUT_CHAN_REARCENTER, - 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_BACK_CENTER, - 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_BACK_CENTER, - SPEAKER_SIDE_LEFT, SPEAKER_SIDE_RIGHT, 0 }; - /***************************************************************************** * Local prototypes. *****************************************************************************/ @@ -230,10 +119,7 @@ static const char *const ppsz_adev_text[] = {"default", }; *****************************************************************************/ #define DEVICE_TEXT N_("Output device") #define DEVICE_LONGTEXT N_("Select your audio output device") -#define FLOAT_TEXT N_("Use float32 output") -#define FLOAT_LONGTEXT N_( \ - "The option allows you to enable or disable the high-quality float32 " \ - "audio output mode (which is not well supported by some soundcards)." ) + #define SPEAKER_TEXT N_("Speaker configuration") #define SPEAKER_LONGTEXT N_("Select speaker configuration you want to use. " \ "This option doesn't upmix! So NO e.g. Stereo -> 5.1 conversion." ) @@ -244,11 +130,14 @@ vlc_module_begin () set_capability( "audio output", 100 ) set_category( CAT_AUDIO ) set_subcategory( SUBCAT_AUDIO_AOUT ) - add_shortcut( "directx" ) + add_shortcut( "directx", "directsound" ) + add_string( "directx-audio-device-name", "default", NULL, DEVICE_TEXT, DEVICE_LONGTEXT, false ) - change_string_list( ppsz_adev, ppsz_adev_text, ReloadDirectXDevices ) - change_action_add( ReloadDirectXDevices, N_("Refresh list") ) + add_deprecated_alias( "directx-audio-device" ) /* Since 1.1.0 */ + change_string_list( ppsz_adev, ppsz_adev_text, ReloadDirectXDevices ) + change_action_add( ReloadDirectXDevices, N_("Refresh list") ) + change_need_restart () add_bool( "directx-audio-float32", false, NULL, FLOAT_TEXT, FLOAT_LONGTEXT, true ) add_string( "directx-audio-speaker", "Windows default", NULL, @@ -273,7 +162,7 @@ static int OpenAudio( vlc_object_t *p_this ) const char * const * ppsz_compare = speaker_list; - msg_Dbg( p_aout, "OpenAudio" ); + msg_Dbg( p_aout, "Opening DirectSound Audio Output" ); /* Allocate structure */ p_aout->output.p_sys = malloc( sizeof( aout_sys_t ) ); @@ -305,8 +194,7 @@ static int OpenAudio( vlc_object_t *p_this ) if ( *ppsz_compare == NULL ) { - msg_Err( p_aout, "(%s) isn't valid speaker setup option", - psz_speaker ); + msg_Err( p_aout, "(%s) isn't valid speaker setup option", psz_speaker ); msg_Err( p_aout, "Defaulting to Windows default speaker config"); i = 0; } @@ -664,7 +552,7 @@ static void Probe( aout_instance_t * p_aout ) text.psz_string = _("A/52 over S/PDIF"); var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val, &text ); - if( config_GetInt( p_aout, "spdif" ) ) + if( var_InheritBool( p_aout, "spdif" ) ) var_Set( p_aout, "audio-device", val ); } } @@ -691,7 +579,6 @@ static void Play( aout_instance_t *p_aout ) if( !p_aout->output.p_sys->b_playing ) { aout_buffer_t *p_buffer; - int i; p_aout->output.p_sys->b_playing = 1; @@ -700,7 +587,7 @@ static void Play( aout_instance_t *p_aout ) aout_FifoFirstDate( p_aout, &p_aout->output.fifo ); /* fill in the first samples */ - for( i = 0; i < FRAMES_NUM; i++ ) + for( int i = 0; i < FRAMES_NUM; i++ ) { p_buffer = aout_FifoPop( p_aout, &p_aout->output.fifo ); if( !p_buffer ) break; @@ -725,7 +612,6 @@ static void CloseAudio( vlc_object_t *p_this ) /* kill the position notification thread, if any */ if( p_sys->p_notif ) { - vlc_object_detach( p_sys->p_notif ); vlc_object_kill( p_sys->p_notif ); /* wake up the audio thread if needed */ if( !p_sys->b_playing ) SetEvent( p_sys->p_notif->event ); @@ -750,34 +636,38 @@ static void CloseAudio( vlc_object_t *p_this ) /***************************************************************************** * CallBackDirectSoundEnum: callback to enumerate available devices *****************************************************************************/ -static int CALLBACK CallBackDirectSoundEnum( LPGUID p_guid, LPCSTR psz_desc, - LPCSTR psz_mod, LPVOID _p_aout ) +static int CALLBACK CallBackDirectSoundEnum( LPGUID p_guid, LPCWSTR psz_desc, + LPCWSTR psz_mod, LPVOID _p_aout ) { VLC_UNUSED( psz_mod ); aout_instance_t *p_aout = (aout_instance_t *)_p_aout; - msg_Dbg( p_aout, "found device: %s", psz_desc ); + char *psz_device = FromWide( psz_desc ); + msg_Dbg( p_aout, "found device: %s", psz_device ); - if( p_aout->output.p_sys->psz_device && !strcmp(p_aout->output.p_sys->psz_device, psz_desc) && p_guid ) + if( p_aout->output.p_sys->psz_device && + !strcmp(p_aout->output.p_sys->psz_device, psz_device) && p_guid ) { /* Use the device corresponding to psz_device */ p_aout->output.p_sys->p_device_guid = malloc( sizeof( GUID ) ); *p_aout->output.p_sys->p_device_guid = *p_guid; - msg_Dbg( p_aout, "using device: %s", psz_desc ); + msg_Dbg( p_aout, "using device: %s", psz_device ); } else { /* If no default device has been selected, chose the first one */ if( !p_aout->output.p_sys->psz_device && p_guid ) { - p_aout->output.p_sys->psz_device = strdup( psz_desc ); + p_aout->output.p_sys->psz_device = strdup( psz_device ); p_aout->output.p_sys->p_device_guid = malloc( sizeof( GUID ) ); *p_aout->output.p_sys->p_device_guid = *p_guid; - msg_Dbg( p_aout, "using device: %s", psz_desc ); + msg_Dbg( p_aout, "using device: %s", psz_device ); } } - return 1; + + free( psz_device ); + return true; } /***************************************************************************** @@ -786,7 +676,7 @@ static int CALLBACK CallBackDirectSoundEnum( LPGUID p_guid, LPCSTR psz_desc, static int InitDirectSound( aout_instance_t *p_aout ) { HRESULT (WINAPI *OurDirectSoundCreate)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN); - HRESULT (WINAPI *OurDirectSoundEnumerate)(LPDSENUMCALLBACK, LPVOID); + HRESULT (WINAPI *OurDirectSoundEnumerate)(LPDSENUMCALLBACKW, LPVOID); p_aout->output.p_sys->hdsound_dll = LoadLibrary("DSOUND.DLL"); if( p_aout->output.p_sys->hdsound_dll == NULL ) @@ -807,10 +697,10 @@ static int InitDirectSound( aout_instance_t *p_aout ) /* Get DirectSoundEnumerate */ OurDirectSoundEnumerate = (void *) GetProcAddress( p_aout->output.p_sys->hdsound_dll, - "DirectSoundEnumerateA" ); + "DirectSoundEnumerateW" ); if( OurDirectSoundEnumerate ) { - p_aout->output.p_sys->psz_device = config_GetPsz(p_aout, "directx-audio-device-name"); + p_aout->output.p_sys->psz_device = var_InheritString(p_aout, "directx-audio-device-name"); /* Attempt enumeration */ if( FAILED( OurDirectSoundEnumerate( CallBackDirectSoundEnum, p_aout ) ) ) @@ -1069,7 +959,7 @@ static int FillBuffer( aout_instance_t *p_aout, int i_frame, p_notif->i_frame_size, /* Number of bytes */ &p_write_position, /* Address of lock start */ &l_bytes1, /* Count of bytes locked before wrap around */ - &p_wrap_around, /* Buffer adress (if wrap around) */ + &p_wrap_around, /* Buffer address (if wrap around) */ &l_bytes2, /* Count of bytes after wrap around */ 0 ); /* Flags */ if( dsresult == DSERR_BUFFERLOST ) @@ -1128,14 +1018,11 @@ static void* DirectSoundThread( vlc_object_t *p_this ) { notification_thread_t *p_notif = (notification_thread_t*)p_this; aout_instance_t *p_aout = p_notif->p_aout; - bool b_sleek; mtime_t last_time; - HRESULT dsresult; - long l_queued = 0; int canc = vlc_savecancel (); /* We don't want any resampling when using S/PDIF output */ - b_sleek = p_aout->output.output.i_format == VLC_CODEC_SPDIFL; + bool b_sleek = (p_aout->output.output.i_format == VLC_CODEC_SPDIFL); msg_Dbg( p_notif, "DirectSoundThread ready" ); @@ -1144,6 +1031,7 @@ static void* DirectSoundThread( vlc_object_t *p_this ) if( vlc_object_alive (p_notif) ) { + HRESULT dsresult; mwait( p_notif->start_date - AOUT_PTS_TOLERANCE / 2 ); /* start playing the buffer */ @@ -1169,7 +1057,8 @@ static void* DirectSoundThread( vlc_object_t *p_this ) while( vlc_object_alive (p_notif) ) { - long l_read, l_free_slots; + DWORD l_read; + int l_queued = 0, l_free_slots; unsigned i_frame_siz = p_aout->output.i_nb_samples; mtime_t mtime = mdate(); int i; @@ -1234,32 +1123,30 @@ static void* DirectSoundThread( vlc_object_t *p_this ) /***************************************************************************** * CallBackConfigNBEnum: callback to get the number of available devices *****************************************************************************/ -static int CALLBACK CallBackConfigNBEnum( LPGUID p_guid, LPCSTR psz_desc, - LPCSTR psz_mod, LPVOID p_nb ) +static int CALLBACK CallBackConfigNBEnum( LPGUID p_guid, LPCWSTR psz_desc, + LPCWSTR psz_mod, LPVOID p_nb ) { - VLC_UNUSED( psz_mod ); - VLC_UNUSED( psz_desc ); - VLC_UNUSED( p_guid ); + VLC_UNUSED( psz_mod ); VLC_UNUSED( psz_desc ); VLC_UNUSED( p_guid ); + int * a = (int *)p_nb; - *a = *a +1; - return 1; + (*a)++; + return true; } /***************************************************************************** * CallBackConfigEnum: callback to add available devices to the preferences list *****************************************************************************/ -static int CALLBACK CallBackConfigEnum( LPGUID p_guid, LPCSTR psz_desc, - LPCSTR psz_mod, LPVOID _p_item ) +static int CALLBACK CallBackConfigEnum( LPGUID p_guid, LPCWSTR psz_desc, + LPCWSTR psz_mod, LPVOID _p_item ) { - VLC_UNUSED( psz_mod ); - VLC_UNUSED( p_guid ); + VLC_UNUSED( psz_mod ); VLC_UNUSED( p_guid ); module_config_t *p_item = (module_config_t *) _p_item; - p_item->ppsz_list[p_item->i_list] = FromLocaleDup(psz_desc); - p_item->ppsz_list_text[p_item->i_list] = FromLocaleDup(psz_desc); - p_item->i_list = p_item->i_list +1; - return 1; + p_item->ppsz_list[p_item->i_list] = FromWide( psz_desc ); + p_item->ppsz_list_text[p_item->i_list] = FromWide( psz_desc ); + p_item->i_list++; + return true; } /***************************************************************************** @@ -1269,49 +1156,54 @@ static int ReloadDirectXDevices( vlc_object_t *p_this, char const *psz_name, vlc_value_t newval, vlc_value_t oldval, void *data ) { 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; /* Clear-up the current list */ if( p_item->i_list ) { - int i; - for( i = 0; i < p_item->i_list; i++ ) + for( int i = 0; i < p_item->i_list; i++ ) { free((char *)(p_item->ppsz_list[i]) ); free((char *)(p_item->ppsz_list_text[i]) ); } } - HRESULT (WINAPI *OurDirectSoundEnumerate)(LPDSENUMCALLBACK, LPVOID); + HRESULT (WINAPI *OurDirectSoundEnumerate)(LPDSENUMCALLBACKW, LPVOID); HANDLE hdsound_dll = LoadLibrary("DSOUND.DLL"); if( hdsound_dll == NULL ) { msg_Warn( p_this, "cannot open DSOUND.DLL" ); + return VLC_SUCCESS; } /* Get DirectSoundEnumerate */ OurDirectSoundEnumerate = (void *) - GetProcAddress( hdsound_dll, - "DirectSoundEnumerateA" ); + GetProcAddress( hdsound_dll, "DirectSoundEnumerateW" ); + + if( OurDirectSoundEnumerate == NULL ) + goto error; + int nb_devices = 0; OurDirectSoundEnumerate(CallBackConfigNBEnum, &nb_devices); msg_Dbg(p_this,"found %d devices", nb_devices); p_item->ppsz_list = xrealloc( p_item->ppsz_list, - nb_devices * sizeof(char *) ); + nb_devices * sizeof(char *) ); p_item->ppsz_list_text = xrealloc( p_item->ppsz_list_text, - nb_devices * sizeof(char *) ); + nb_devices * sizeof(char *) ); p_item->i_list = 0; OurDirectSoundEnumerate(CallBackConfigEnum, p_item); - FreeLibrary(hdsound_dll); - /* Signal change to the interface */ p_item->b_dirty = true; +error: + FreeLibrary(hdsound_dll); + return VLC_SUCCESS; }