diff --git a/modules/audio_output/directx.c b/modules/audio_output/directx.c index 5f5d301f570a3d5ba7f395751621c01327c0012c..ed7c407e65d8b4b308d95b528b6ce93059d99100 100644 --- a/modules/audio_output/directx.c +++ b/modules/audio_output/directx.c @@ -2,7 +2,7 @@ * directx.c: Windows DirectX audio output method ***************************************************************************** * Copyright (C) 2001 VideoLAN - * $Id: directx.c,v 1.21 2003/06/11 18:20:38 gbazin Exp $ + * $Id: directx.c,v 1.22 2003/07/11 23:14:03 gbazin Exp $ * * Authors: Gildas Bazin * @@ -39,7 +39,7 @@ #include #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 @@ -711,7 +711,8 @@ static int CreateDSBuffer( aout_instance_t *p_aout, int i_format, dsbdesc.dwSize = sizeof(DSBUFFERDESC); dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2/* Better position accuracy */ | DSBCAPS_CTRLPOSITIONNOTIFY /* We need notification */ - | DSBCAPS_GLOBALFOCUS; /* Allows background playing */ + | DSBCAPS_GLOBALFOCUS /* Allows background playing */ + | DSBCAPS_LOCHARDWARE; /* Needed for 5.1 on emu101k */ dsbdesc.dwBufferBytes = FRAMES_NUM * i_bytes_per_frame; /* buffer size */ dsbdesc.lpwfxFormat = (WAVEFORMATEX *)&waveformat; @@ -719,7 +720,15 @@ static int CreateDSBuffer( aout_instance_t *p_aout, int i_format, p_aout->output.p_sys->p_dsobject, &dsbdesc, &p_aout->output.p_sys->p_dsbuffer, NULL) ) { - return VLC_EGENERIC; + /* 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" ); } /* Stop here if we were just probing */ @@ -782,7 +791,10 @@ static int CreateDSBufferPCM( aout_instance_t *p_aout, int *i_format, 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 ) diff --git a/modules/audio_output/waveout.c b/modules/audio_output/waveout.c index ef039e3c469bef128864e7146a7dab48730c02dd..41505c360700decb3d061105f7f0823e4f6a10ab 100644 --- a/modules/audio_output/waveout.c +++ b/modules/audio_output/waveout.c @@ -2,7 +2,7 @@ * waveout.c : Windows waveOut plugin for vlc ***************************************************************************** * Copyright (C) 2001 VideoLAN - * $Id: waveout.c,v 1.25 2003/05/21 15:54:08 gbazin Exp $ + * $Id: waveout.c,v 1.26 2003/07/11 23:14:03 gbazin Exp $ * * Authors: Gildas Bazin * @@ -35,7 +35,7 @@ #include #define FRAME_SIZE 1024 /* The size is in samples, not in bytes */ -#define FRAMES_NUM 4 +#define FRAMES_NUM 8 /***************************************************************************** * Useful macros @@ -104,6 +104,16 @@ static int Open ( vlc_object_t * ); static void Close ( vlc_object_t * ); static void Play ( aout_instance_t * ); +/***************************************************************************** + * notification_thread_t: waveOut event thread + *****************************************************************************/ +typedef struct notification_thread_t +{ + VLC_COMMON_MEMBERS + aout_instance_t *p_aout; + +} notification_thread_t; + /* local functions */ static void Probe ( aout_instance_t * ); static int OpenWaveOut ( aout_instance_t *, int, int, int, int, vlc_bool_t ); @@ -113,6 +123,7 @@ static int PlayWaveOut ( aout_instance_t *, HWAVEOUT, WAVEHDR *, aout_buffer_t * ); static void CALLBACK WaveOutCallback ( HWAVEOUT, UINT, DWORD, DWORD, DWORD ); +static void WaveOutThread( notification_thread_t * ); static void InterleaveFloat32( float *, int *, int ); static void InterleaveS16( int16_t *, int *, int ); @@ -140,6 +151,9 @@ struct aout_sys_t WAVEHDR waveheader[FRAMES_NUM]; + notification_thread_t *p_notif; /* WaveOutThread id */ + HANDLE event; + int i_buffer_size; byte_t *p_silence_buffer; /* buffer we use to play silence */ @@ -284,6 +298,20 @@ static int Open( vlc_object_t *p_this ) memset( p_aout->output.p_sys->p_silence_buffer, 0, p_aout->output.p_sys->i_buffer_size ); + /* Now we need to setup our waveOut 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; + p_aout->output.p_sys->event = CreateEvent( NULL, FALSE, FALSE, NULL ); + + /* Then launch the notification thread */ + if( vlc_thread_create( p_aout->output.p_sys->p_notif, + "waveOut Notification Thread", WaveOutThread, + VLC_THREAD_PRIORITY_HIGHEST, VLC_FALSE ) ) + { + msg_Err( p_aout, "cannot create WaveOutThread" ); + } + /* We need to kick off the playback in order to have the callback properly * working */ for( i = 0; i < FRAMES_NUM; i++ ) @@ -412,7 +440,7 @@ static void Probe( aout_instance_t * p_aout ) * This doesn't actually play the buffer. This just stores the buffer so it * can be played by the callback thread. *****************************************************************************/ -static void Play( aout_instance_t *p_aout ) +static void Play( aout_instance_t *_p_aout ) { } @@ -426,6 +454,11 @@ static void Close( vlc_object_t *p_this ) /* Before calling waveOutClose we must reset the device */ p_aout->b_die = VLC_TRUE; + /* wake up the audio thread */ + SetEvent( p_aout->output.p_sys->event ); + vlc_thread_join( p_aout->output.p_sys->p_notif ); + CloseHandle( p_aout->output.p_sys->event ); + /* Wait for the waveout buffers to be freed */ while( VLC_TRUE ) { @@ -690,8 +723,6 @@ static void CALLBACK WaveOutCallback( HWAVEOUT h_waveout, UINT uMsg, { aout_instance_t *p_aout = (aout_instance_t *)_p_aout; WAVEHDR *p_waveheader = (WAVEHDR *)dwParam1; - aout_buffer_t *p_buffer = NULL; - vlc_bool_t b_sleek; int i, i_queued_frames = 0; if( uMsg != WOM_DONE ) return; @@ -703,9 +734,6 @@ static void CALLBACK WaveOutCallback( HWAVEOUT h_waveout, UINT uMsg, if( p_aout->b_die ) return; - /* We don't want any resampling when using S/PDIF */ - b_sleek = p_aout->output.output.i_format == VLC_FOURCC('s','p','d','i'); - /* Find out the current latency */ for( i = 0; i < FRAMES_NUM; i++ ) { @@ -716,44 +744,9 @@ static void CALLBACK WaveOutCallback( HWAVEOUT h_waveout, UINT uMsg, } } - /* Try to fill in as many frame buffers as possible */ - for( i = 0; i < FRAMES_NUM; i++ ) - { - /* Check if frame buf is available */ - if( p_aout->output.p_sys->waveheader[i].dwFlags & WHDR_DONE ) - { - /* Take into account the latency */ - p_buffer = aout_OutputNextBuffer( p_aout, - mdate() + 1000000 * i_queued_frames / - p_aout->output.output.i_rate * p_aout->output.i_nb_samples, - b_sleek ); - - if( !p_buffer && i_queued_frames ) - { - /* We aren't late so no need to play a blank sample */ - return; - } - - /* Do the channel reordering here */ - if( p_buffer && p_aout->output.p_sys->b_chan_reorder ) - { - if( p_aout->output.output.i_format == - VLC_FOURCC('s','1','6','l') ) - InterleaveS16( (int16_t *)p_buffer->p_buffer, - p_aout->output.p_sys->pi_chan_table, - aout_FormatNbChannels( &p_aout->output.output ) ); - else - InterleaveFloat32( (float *)p_buffer->p_buffer, - p_aout->output.p_sys->pi_chan_table, - aout_FormatNbChannels( &p_aout->output.output ) ); - } - - PlayWaveOut( p_aout, h_waveout, - &p_aout->output.p_sys->waveheader[i] , p_buffer ); - - i_queued_frames++; - } - } + /* Don't wake up the thread too much */ + if( i_queued_frames < FRAMES_NUM / 2 ) + SetEvent( p_aout->output.p_sys->event ); } /***************************************************************************** @@ -794,3 +787,77 @@ static void InterleaveS16( int16_t *p_buf, int *pi_chan_table, i_nb_channels * sizeof(int16_t) ); } } + +/***************************************************************************** + * WaveOutThread: this thread will capture play notification events. + ***************************************************************************** + * We use this thread to feed new audio samples to the sound card because + * we are not authorized to use waveOutWrite() directly in the waveout + * callback. + *****************************************************************************/ +static void WaveOutThread( notification_thread_t *p_notif ) +{ + aout_instance_t *p_aout = p_notif->p_aout; + aout_buffer_t *p_buffer = NULL; + vlc_bool_t b_sleek; + int i, i_queued_frames; + + /* We don't want any resampling when using S/PDIF */ + b_sleek = p_aout->output.output.i_format == VLC_FOURCC('s','p','d','i'); + + while( 1 ) + { + WaitForSingleObject( p_aout->output.p_sys->event, INFINITE ); + if( p_aout->b_die ) return; + + /* Find out the current latency */ + i_queued_frames = 0; + for( i = 0; i < FRAMES_NUM; i++ ) + { + /* Check if frame buf is available */ + if( !(p_aout->output.p_sys->waveheader[i].dwFlags & WHDR_DONE) ) + { + i_queued_frames++; + } + } + + /* Try to fill in as many frame buffers as possible */ + for( i = 0; i < FRAMES_NUM; i++ ) + { + /* Check if frame buf is available */ + if( p_aout->output.p_sys->waveheader[i].dwFlags & WHDR_DONE ) + { + /* Take into account the latency */ + p_buffer = aout_OutputNextBuffer( p_aout, + mdate() + 1000000 * i_queued_frames / + p_aout->output.output.i_rate * p_aout->output.i_nb_samples, + b_sleek ); + + if( !p_buffer && i_queued_frames ) + { + /* We aren't late so no need to play a blank sample */ + break; + } + + /* Do the channel reordering here */ + if( p_buffer && p_aout->output.p_sys->b_chan_reorder ) + { + if( p_aout->output.output.i_format == + VLC_FOURCC('s','1','6','l') ) + InterleaveS16( (int16_t *)p_buffer->p_buffer, + p_aout->output.p_sys->pi_chan_table, + aout_FormatNbChannels( &p_aout->output.output ) ); + else + InterleaveFloat32( (float *)p_buffer->p_buffer, + p_aout->output.p_sys->pi_chan_table, + aout_FormatNbChannels( &p_aout->output.output ) ); + } + + PlayWaveOut( p_aout, p_aout->output.p_sys->h_waveout, + &p_aout->output.p_sys->waveheader[i] , p_buffer ); + + i_queued_frames++; + } + } + } +} diff --git a/modules/gui/wxwindows/messages.cpp b/modules/gui/wxwindows/messages.cpp index 7902b70ba7ca11a3a75f2ef5abd0f0c6313781f2..a513753218ccbbe2b8ac181793eebf996077a4d8 100644 --- a/modules/gui/wxwindows/messages.cpp +++ b/modules/gui/wxwindows/messages.cpp @@ -2,7 +2,7 @@ * playlist.cpp : wxWindows plugin for vlc ***************************************************************************** * Copyright (C) 2000-2001 VideoLAN - * $Id: messages.cpp,v 1.10 2003/07/10 11:15:18 adn Exp $ + * $Id: messages.cpp,v 1.11 2003/07/11 23:14:03 gbazin Exp $ * * Authors: Olivier Teulière * @@ -85,7 +85,6 @@ Messages::Messages( intf_thread_t *_p_intf, wxWindow *p_parent ): { /* Initializations */ p_intf = _p_intf; - b_verbose = VLC_FALSE; SetIcon( *p_intf->p_sys->p_icon ); save_log_dialog = NULL; @@ -117,6 +116,8 @@ Messages::Messages( intf_thread_t *_p_intf, wxWindow *p_parent ): /* Create the Verbose checkbox */ wxCheckBox *verbose_checkbox = new wxCheckBox( messages_panel, Verbose_Event, wxU(_("Verbose")) ); + b_verbose = p_intf->p_libvlc->i_verbose > 0; + verbose_checkbox->SetValue( b_verbose ); /* Place everything in sizers */ wxBoxSizer *buttons_sizer = new wxBoxSizer( wxHORIZONTAL );