audio ring buffer

Rob Crittenden <[email protected]>
Newsgroups gmane.comp.emulators.winex.devel
Message-ID <[email protected]>
Attached is a simple patch to convert from a fixed audio ring buffer to
one that grows dynamically.  I picked a startup/increment size of 128 out of
thin air, there may be a better value.

rob
audio.diff (text/plain, 6.2 KB)
Index: wineoss/audio.c
===================================================================
RCS file: /cvsroot/winex/wine/dlls/winmm/wineoss/audio.c,v
retrieving revision 1.50
diff -u -r1.50 audio.c
--- wineoss/audio.c	25 Jul 2003 21:45:27 -0000	1.50
+++ wineoss/audio.c	7 Nov 2003 15:44:42 -0000
@@ -130,10 +130,9 @@
  * this ring will be used by the input (resp output) record (resp playback) routine
  */
 typedef struct {
-    /* FIXME: this could be made a dynamically growing array (if needed) */
-    /* maybe it's needed, a Humongous game manages to transmit 128 messages at once at startup */
-#define OSS_RING_BUFFER_SIZE	192
-    OSS_MSG			messages[OSS_RING_BUFFER_SIZE];
+#define OSS_RING_BUFFER_SIZE	128
+    int                         entries; /* # of entries in the ring */
+    OSS_MSG			* messages;
     int				msg_tosave;
     int				msg_toget;
 #ifdef USE_PIPE_SYNC
@@ -919,7 +918,8 @@
 #else
     omr->msg_event = CreateEventA(NULL, FALSE, FALSE, NULL);
 #endif
-    memset(omr->messages, 0, sizeof(OSS_MSG) * OSS_RING_BUFFER_SIZE);
+    omr->entries = OSS_RING_BUFFER_SIZE;
+    omr->messages = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, omr->entries * sizeof(OSS_MSG));
     InitializeCriticalSection(&omr->msg_crst);
     return 0;
 }
@@ -950,11 +950,11 @@
     HANDLE	hEvent = INVALID_HANDLE_VALUE;
 
     EnterCriticalSection(&omr->msg_crst);
-    if ((omr->msg_toget == ((omr->msg_tosave + 1) % OSS_RING_BUFFER_SIZE))) /* buffer overflow ? */
+    if ((omr->msg_toget == ((omr->msg_tosave + 1) % omr->entries))) /* buffer overflow */
     {
-	ERR("buffer overflow !?\n");
-        LeaveCriticalSection(&omr->msg_crst);
-	return 0;
+        omr->entries += OSS_RING_BUFFER_SIZE;
+        omr->messages = HeapReAlloc(GetProcessHeap(), 0, omr->messages, omr->entries * sizeof(OSS_MSG));
+        TRACE("Growing ring buffer to %d\n", omr->entries);
     }
     if (wait)
     {
@@ -969,7 +969,7 @@
             FIXME("two fast messages in the queue!!!!\n");
 
         /* fast messages have to be added at the start of the queue */
-        omr->msg_toget = (omr->msg_toget + OSS_RING_BUFFER_SIZE - 1) % OSS_RING_BUFFER_SIZE;
+        omr->msg_toget = (omr->msg_toget + omr->entries - 1) % omr->entries;
 
         omr->messages[omr->msg_toget].msg = msg;
         omr->messages[omr->msg_toget].param = param;
@@ -980,7 +980,7 @@
         omr->messages[omr->msg_tosave].msg = msg;
         omr->messages[omr->msg_tosave].param = param;
         omr->messages[omr->msg_tosave].hEvent = INVALID_HANDLE_VALUE;
-        omr->msg_tosave = (omr->msg_tosave + 1) % OSS_RING_BUFFER_SIZE;
+        omr->msg_tosave = (omr->msg_tosave + 1) % omr->entries;
     }
     LeaveCriticalSection(&omr->msg_crst);
     /* signal a new message */
@@ -1014,7 +1014,7 @@
     omr->messages[omr->msg_toget].msg = 0;
     *param = omr->messages[omr->msg_toget].param;
     *hEvent = omr->messages[omr->msg_toget].hEvent;
-    omr->msg_toget = (omr->msg_toget + 1) % OSS_RING_BUFFER_SIZE;
+    omr->msg_toget = (omr->msg_toget + 1) % omr->entries;
     CLEAR_OMR(omr);
     LeaveCriticalSection(&omr->msg_crst);
     return 1;
Index: winealsa/audio.c
===================================================================
RCS file: /cvsroot/winex/wine/dlls/winmm/winealsa/audio.c,v
retrieving revision 1.2
diff -u -r1.2 audio.c
--- winealsa/audio.c	15 Oct 2003 02:53:13 -0000	1.2
+++ winealsa/audio.c	7 Nov 2003 15:44:47 -0000
@@ -89,9 +89,9 @@
  * this ring will be used by the input (resp output) record (resp playback) routine
  */
 typedef struct {
-    /* FIXME: this could be made a dynamically growing array (if needed) */
-#define ALSA_RING_BUFFER_SIZE	30
-    ALSA_MSG			messages[ALSA_RING_BUFFER_SIZE];
+#define ALSA_RING_BUFFER_SIZE	128
+    int				entries; /* # of entries in the ring */
+    ALSA_MSG			* messages;
     int				msg_tosave;
     int				msg_toget;
     HANDLE			msg_event;
@@ -504,7 +504,8 @@
     omr->msg_toget = 0;
     omr->msg_tosave = 0;
     omr->msg_event = CreateEventA(NULL, FALSE, FALSE, NULL);
-    memset(omr->messages, 0, sizeof(ALSA_MSG) * ALSA_RING_BUFFER_SIZE);
+    omr->entries = ALSA_RING_BUFFER_SIZE;
+    omr->messages = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, omr->entries * sizeof(ALSA_MSG));
     InitializeCriticalSection(&omr->msg_crst);
     return 0;
 }
@@ -530,11 +531,11 @@
     HANDLE	hEvent = INVALID_HANDLE_VALUE;
 
     EnterCriticalSection(&omr->msg_crst);
-    if ((omr->msg_toget == ((omr->msg_tosave + 1) % ALSA_RING_BUFFER_SIZE))) /* buffer overflow ? */
+    if ((omr->msg_toget == ((omr->msg_tosave + 1) % omr->entries))) /* buffer overflow ? */
     {
-	ERR("buffer overflow !?\n");
-        LeaveCriticalSection(&omr->msg_crst);
-	return 0;
+        omr->entries += ALSA_RING_BUFFER_SIZE;
+        omr->messages = HeapReAlloc(GetProcessHeap(), 0, omr->messages, omr->entries * sizeof(ALSA_MSG));
+        TRACE("Growing audio ring buffer to %d\n", omr->entries);
     }
     if (wait)
     {
@@ -549,7 +550,7 @@
             FIXME("two fast messages in the queue!!!!\n");
 
         /* fast messages have to be added at the start of the queue */
-        omr->msg_toget = (omr->msg_toget + ALSA_RING_BUFFER_SIZE - 1) % ALSA_RING_BUFFER_SIZE;
+        omr->msg_toget = (omr->msg_toget + omr->entries - 1) % omr->entries;
 
         omr->messages[omr->msg_toget].msg = msg;
         omr->messages[omr->msg_toget].param = param;
@@ -560,7 +561,7 @@
         omr->messages[omr->msg_tosave].msg = msg;
         omr->messages[omr->msg_tosave].param = param;
         omr->messages[omr->msg_tosave].hEvent = INVALID_HANDLE_VALUE;
-        omr->msg_tosave = (omr->msg_tosave + 1) % ALSA_RING_BUFFER_SIZE;
+        omr->msg_tosave = (omr->msg_tosave + 1) % omr->entries;
     }
     LeaveCriticalSection(&omr->msg_crst);
     /* signal a new message */
@@ -594,7 +595,7 @@
     omr->messages[omr->msg_toget].msg = 0;
     *param = omr->messages[omr->msg_toget].param;
     *hEvent = omr->messages[omr->msg_toget].hEvent;
-    omr->msg_toget = (omr->msg_toget + 1) % ALSA_RING_BUFFER_SIZE;
+    omr->msg_toget = (omr->msg_toget + 1) % omr->entries;
     LeaveCriticalSection(&omr->msg_crst);
     return 1;
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.