changeset 28822:2c00a46b99c8

Use code that is actually thread-safe to calculate delay, free space etc. in ao_win32
author reimar
date Fri, 06 Mar 2009 19:23:24 +0000
parents e722ebb83ffe
children 9a5b8c2ed6de
files libao2/ao_win32.c
diffstat 1 files changed, 13 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/libao2/ao_win32.c	Fri Mar 06 19:10:54 2009 +0000
+++ b/libao2/ao_win32.c	Fri Mar 06 19:23:24 2009 +0000
@@ -87,7 +87,7 @@
 static WAVEHDR*     waveBlocks;         //pointer to our ringbuffer memory
 static HWAVEOUT     hWaveOut;           //handle to the waveout device
 static unsigned int buf_write=0;
-static volatile int buffered_bytes=0;
+static volatile int buf_read=0;
 
 
 static ao_info_t info =
@@ -105,7 +105,7 @@
 {
 	if(uMsg != WOM_DONE)
         return;
-		buffered_bytes-=BUFFER_SIZE;
+	buf_read = (buf_read + 1) % BUFFER_COUNT;
 }
 
 // to set/get/query special features/parameters
@@ -233,7 +233,7 @@
         buffer += BUFFER_SIZE;
     }
     buf_write=0;
-    buffered_bytes=0;
+    buf_read=0;
 
     return 1;
 }
@@ -243,7 +243,6 @@
 {
     if(!immed)
 	usec_sleep(get_delay() * 1000 * 1000);
-    else buffered_bytes=0;
 	waveOutReset(hWaveOut);
 	waveOutClose(hWaveOut);
 	mp_msg(MSGT_AO, MSGL_V,"waveOut device closed\n");
@@ -256,7 +255,7 @@
 {
    	waveOutReset(hWaveOut);
 	buf_write=0;
-	buffered_bytes=0;
+	buf_read=0;
 }
 
 // stop playing, keep buffers (for pause)
@@ -274,7 +273,9 @@
 // return: how many bytes can be played without blocking
 static int get_space(void)
 {
-    return BUFFER_COUNT*BUFFER_SIZE - buffered_bytes;
+    int free = buf_read - buf_write - 1;
+    if (free < 0) free += BUFFER_COUNT;
+    return free * BUFFER_SIZE;
 }
 
 //writes data into buffer, based on ringbuffer code in ao_sdl.c
@@ -283,8 +284,9 @@
   int len2=0;
   int x;
   while(len>0){
+    int buf_next = (buf_write + 1) % BUFFER_COUNT;
     current = &waveBlocks[buf_write];
-    if(buffered_bytes==BUFFER_COUNT*BUFFER_SIZE) break;
+    if(buf_next == buf_read) break;
     //unprepare the header if it is prepared
 	if(current->dwFlags & WHDR_PREPARED)
            waveOutUnprepareHeader(hWaveOut, current, sizeof(WAVEHDR));
@@ -292,13 +294,12 @@
     if(x>len) x=len;
     fast_memcpy(current->lpData,data+len2,x);
     len2+=x; len-=x;
-	buffered_bytes+=x;
 	//prepare header and write data to device
 	current->dwBufferLength = x;
 	waveOutPrepareHeader(hWaveOut, current, sizeof(WAVEHDR));
 	waveOutWrite(hWaveOut, current, sizeof(WAVEHDR));
 
-       buf_write=(buf_write+1)%BUFFER_COUNT;
+       buf_write = buf_next;
   }
   return len2;
 }
@@ -316,5 +317,7 @@
 // return: delay in seconds between first and last sample in buffer
 static float get_delay(void)
 {
-	return (float)(buffered_bytes + ao_data.buffersize)/(float)ao_data.bps;
+	int used = buf_write - buf_read;
+	if (used < 0) used += BUFFER_COUNT;
+	return (float)(used * BUFFER_SIZE + ao_data.buffersize)/(float)ao_data.bps;
 }