[xiph-cvs] cvs commit: ao/src/plugins/mmsound mmsound.c
Chris Wolf
cwolf at xiph.org
Sun Sep 9 08:20:48 PDT 2001
cwolf 01/09/09 08:20:48
Modified: src/plugins/mmsound mmsound.c
Log:
Alternative buffer filling scheme
Revision Changes Path
1.4 +78 -87 ao/src/plugins/mmsound/mmsound.c
Index: mmsound.c
===================================================================
RCS file: /usr/local/cvsroot/ao/src/plugins/mmsound/mmsound.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- mmsound.c 2001/09/08 21:10:35 1.3
+++ mmsound.c 2001/09/09 15:20:47 1.4
@@ -29,21 +29,19 @@
#include <ao/ao.h>
#include <ao/plugin.h>
-
-#define MAXBUF 5 // Max buffers in circular buffer queue
-#define DEFAULTBUFTIME 3 // default to three seconds total buffer time
-
-typedef struct ao_mmsound_internal
-{
- HWAVEOUT m_hWaveOut;
- WAVEHDR m_waveHeader[MAXBUF];
- uint_32 buf_size;
- void *buffer[MAXBUF];
- int next_in;
- int next_out;
- int timeout_msec;
- HANDLE hSema; // semaphore for foreground/background coordination
- CRITICAL_SECTION lock; // concurrency control for atomic state updates
+typedef struct ao_mmsound_internal {
+ HWAVEOUT m_hWaveOut;
+ WAVEHDR m_waveHeader[2];
+ uint_32 num_bytes[2];
+ void *buffer[2];
+ void *tempbuf;
+ uint_32 tb_num_bytes;
+ int currentb;
+ uint_32 buf_size;
+ int running;
+ HANDLE notdone;
+ HANDLE datanotdone;
+ CRITICAL_SECTION lock;
} ao_mmsound_internal;
static char *ao_mmsound_options[] = {"buf_size"};
@@ -61,25 +59,49 @@
1
};
-static void CALLBACK waveOutProc(HWAVEOUT hwo,UINT uMsg,DWORD dwInstance,DWORD dwParam1,DWORD dwParam2)
+void fillnextbuffer(DWORD dwInstance)
{
- ao_mmsound_internal *internal = (ao_mmsound_internal *)dwInstance;
+ ao_mmsound_internal *internal = (ao_mmsound_internal *)dwInstance;
-// printf("********* %x Next in: %d Next out: %d\n",
-// uMsg, internal->next_in, internal->next_out);
+ EnterCriticalSection(&internal->lock);
- if (uMsg == WOM_DONE)
- {
- EnterCriticalSection(&internal->lock);
- internal->next_out++;
+ if (internal->m_waveHeader[internal->currentb].dwFlags&WHDR_PREPARED)
+ waveOutUnprepareHeader(internal->m_hWaveOut,&internal->m_waveHeader[internal->currentb],sizeof(WAVEHDR));
+
+ ReleaseSemaphore(internal->notdone, 1, NULL);
+ WaitForSingleObject(internal->datanotdone,INFINITE);
+ memcpy(internal->buffer[internal->currentb], internal->tempbuf, internal->tb_num_bytes);
+ internal->num_bytes[internal->currentb] = internal->tb_num_bytes;
+
+ internal->m_waveHeader[internal->currentb].lpData = (char*)internal->buffer[internal->currentb];
+ internal->m_waveHeader[internal->currentb].dwBufferLength = (unsigned long)internal->num_bytes[internal->currentb];
+ waveOutPrepareHeader(internal->m_hWaveOut,&internal->m_waveHeader[internal->currentb],sizeof(WAVEHDR));
+
+ waveOutWrite(internal->m_hWaveOut,&internal->m_waveHeader[internal->currentb],sizeof(WAVEHDR));
+ internal->currentb++;
+ if(internal->currentb == 2)
+ internal->currentb = 0;
+ LeaveCriticalSection(&internal->lock);
+
+}
+
+void startbuffer(DWORD dwInstance)
+{
+ ao_mmsound_internal *internal = (ao_mmsound_internal *)dwInstance;
+
+ fillnextbuffer(internal);
+ fillnextbuffer(internal);
+ _endthread();
+}
- if (internal->next_out == internal->next_in)
- {
- internal->next_in = internal->next_out = 0;
- ReleaseSemaphore(internal->hSema, 1, NULL);
- }
+static void CALLBACK waveOutProc(HWAVEOUT hwo,UINT uMsg,DWORD dwInstance,DWORD dwParam1,DWORD dwParam2)
+{
+ ao_mmsound_internal *internal = (ao_mmsound_internal *)dwInstance;
- LeaveCriticalSection(&internal->lock);
+ if (uMsg == WOM_DONE)
+ {
+ if(internal->running)
+ fillnextbuffer(dwInstance);
}
}
@@ -123,7 +145,6 @@
*/
int ao_plugin_open(ao_device *device, ao_sample_format *format)
{
- int i;
ao_mmsound_internal *internal = (ao_mmsound_internal *) device->internal;
MMRESULT errCode;
@@ -148,23 +169,25 @@
if(internal->buf_size == 0)
{
- internal->buf_size = wfx.nAvgBytesPerSec * DEFAULTBUFTIME;
+ internal->buf_size = 352800;
}
- internal->timeout_msec = (internal->buf_size / wfx.nAvgBytesPerSec) * 1000;
-
- for (i=0; i<MAXBUF; i++)
- {
- internal->buffer[i] = malloc(internal->buf_size);
- memset(&internal->m_waveHeader[i],0,sizeof(WAVEHDR));
- }
+ memset(&internal->m_waveHeader[0],0,sizeof(WAVEHDR));
+ memset(&internal->m_waveHeader[1],0,sizeof(WAVEHDR));
+ internal->buffer[0] = malloc(internal->buf_size);
+ internal->buffer[1] = malloc(internal->buf_size);
+ internal->tempbuf = malloc(internal->buf_size);
+ internal->currentb = 0;
+ internal->running = 1;
+
+ internal->notdone = CreateSemaphore(NULL, 0, 1, NULL);
+ internal->datanotdone = CreateSemaphore(NULL, 0, 1, NULL);
- internal->next_in = internal->next_out = 0;
+ device->driver_byte_format = AO_FMT_NATIVE;
- internal->hSema = CreateSemaphore(NULL, MAXBUF-1, MAXBUF, NULL);
- InitializeCriticalSection(&internal->lock);
+ InitializeCriticalSection(&internal->lock);
- device->driver_byte_format = AO_FMT_NATIVE;
+ _beginthread(startbuffer, 0, internal);
return 1;
}
@@ -176,65 +199,33 @@
uint_32 num_bytes)
{
ao_mmsound_internal *internal = (ao_mmsound_internal *) device->internal;
-
- EnterCriticalSection(&internal->lock);
if(num_bytes > internal->buf_size)
- {
- LeaveCriticalSection(&internal->lock);
return 0;
- }
-// printf("*** Next in: %d Next out: %d\n",
-// internal->next_in, internal->next_out);
- if (internal->m_waveHeader[internal->next_in].dwFlags&WHDR_PREPARED)
- waveOutUnprepareHeader(internal->m_hWaveOut,
- &internal->m_waveHeader[internal->next_in],
- sizeof(WAVEHDR));
-
- // Prepare internal->buffer[n] to be inserted into WaveOut buffer.
- memcpy(internal->buffer[internal->next_in], output_samples, num_bytes);
-
- internal->m_waveHeader[internal->next_in].lpData =
- (char*)internal->buffer[internal->next_in];
-
- internal->m_waveHeader[internal->next_in].dwBufferLength =
- (unsigned long)num_bytes;
-
- waveOutPrepareHeader(internal->m_hWaveOut,
- &internal->m_waveHeader[internal->next_in], sizeof(WAVEHDR));
-
- // Send internal->buffer[n] to the WaveOut device buffer.
- waveOutWrite(internal->m_hWaveOut,
- &internal->m_waveHeader[internal->next_in], sizeof(WAVEHDR));
-
- internal->next_in++;
- LeaveCriticalSection(&internal->lock);
- WaitForSingleObject(internal->hSema, internal->timeout_msec);
+ WaitForSingleObject(internal->notdone, INFINITE);
+
+ memcpy(internal->tempbuf, output_samples, num_bytes);
+ internal->tb_num_bytes = num_bytes;
+
+ ReleaseSemaphore(internal->datanotdone, 1, NULL);
return 1;
}
int ao_plugin_close(ao_device *device)
{
- int i;
ao_mmsound_internal *internal = (ao_mmsound_internal *) device->internal;
-
- // Wait for last block to finish playing
- while ( internal->next_in != internal->next_out )
- {
- WaitForSingleObject(internal->hSema, internal->timeout_msec);
- }
-
- CloseHandle(internal->hSema);
- DeleteCriticalSection(&internal->lock);
-
- for (i=0; i<MAXBUF; i++)
- free(internal->buffer[i]);
+ internal->running = 0;
+ while((!internal->m_waveHeader[0].dwFlags&WHDR_DONE) || (!internal->m_waveHeader[1].dwFlags&WHDR_DONE))
+ {}
waveOutReset(internal->m_hWaveOut);
waveOutClose(internal->m_hWaveOut);
+ CloseHandle(internal->notdone);
+ free(internal->buffer[0]);
+ free(internal->buffer[1]);
return 1;
}
@@ -244,4 +235,4 @@
ao_mmsound_internal *internal = (ao_mmsound_internal *) device->internal;
free(internal);
-}
+}
\ No newline at end of file
--- >8 ----
List archives: http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body. No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.
More information about the commits
mailing list