* modules/audio_output/directx.c: 5.1 audio output now works on sblive/audigy as...
authorGildas Bazin <gbazin@videolan.org>
Fri, 11 Jul 2003 23:14:03 +0000 (23:14 +0000)
committerGildas Bazin <gbazin@videolan.org>
Fri, 11 Jul 2003 23:14:03 +0000 (23:14 +0000)
* modules/audio_output/waveout.c: fixed the waveOut plugin so works on NT4 as well... that complicates the plugin a bit more than I would have wanted, but hey.
* modules/gui/wxwindows/messages.cpp: the verbose checkbox is set to the value of the --verbose config option.

modules/audio_output/directx.c
modules/audio_output/waveout.c
modules/gui/wxwindows/messages.cpp

index 5f5d301..ed7c407 100644 (file)
@@ -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 <gbazin@netcourrier.com>
  *
@@ -39,7 +39,7 @@
 #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
@@ -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 )
index ef039e3..41505c3 100644 (file)
@@ -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 <gbazin@netcourrier.com>
  *      
@@ -35,7 +35,7 @@
 #include <mmsystem.h>
 
 #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++;
+            }
+        }
+    }
+}
index 7902b70..a513753 100644 (file)
@@ -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 <ipkiss@via.ecp.fr>
  *
@@ -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 );