Ken Thomases : winecoreaudio: Allocate/deallocate audio buffers in widOpen/ widClose.

Alexandre Julliard julliard at wine.codeweavers.com
Fri Dec 29 06:47:20 CST 2006


Module: wine
Branch: master
Commit: 127523d7a2b7dbe3b04ca13c76dae0d4568b21af
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=127523d7a2b7dbe3b04ca13c76dae0d4568b21af

Author: Ken Thomases <ken at codeweavers.com>
Date:   Thu Dec 28 11:06:29 2006 -0600

winecoreaudio: Allocate/deallocate audio buffers in widOpen/widClose.

---

 dlls/winmm/winecoreaudio/audio.c |   67 ++++++++++++++++++++++++++++++++++++++
 1 files changed, 67 insertions(+), 0 deletions(-)

diff --git a/dlls/winmm/winecoreaudio/audio.c b/dlls/winmm/winecoreaudio/audio.c
index 6aac76d..4389bc1 100644
--- a/dlls/winmm/winecoreaudio/audio.c
+++ b/dlls/winmm/winecoreaudio/audio.c
@@ -176,6 +176,7 @@ typedef struct {
     PCMWAVEFORMAT   format;
 
     AudioUnit       audioUnit;
+    AudioBufferList*bufferList;
 
     /* Record state of debug channels at open.  Used to control fprintf's since
      * we can't use Wine debug channel calls in non-Wine AudioUnit threads. */
@@ -1519,12 +1520,61 @@ static DWORD widGetDevCaps(WORD wDevID,
 
 
 /**************************************************************************
+ *                    widHelper_DestroyAudioBufferList           [internal]
+ * Convenience function to dispose of our audio buffers
+ */
+static void widHelper_DestroyAudioBufferList(AudioBufferList* list)
+{
+    if (list)
+    {
+        UInt32 i;
+        for (i = 0; i < list->mNumberBuffers; i++)
+        {
+            if (list->mBuffers[i].mData)
+                HeapFree(GetProcessHeap(), 0, list->mBuffers[i].mData);
+        }
+        HeapFree(GetProcessHeap(), 0, list);
+    }
+}
+
+
+/**************************************************************************
+ *                    widHelper_AllocateAudioBufferList          [internal]
+ * Convenience function to allocate our audio buffers
+ */
+static AudioBufferList* widHelper_AllocateAudioBufferList(UInt32 numChannels, UInt32 size)
+{
+    AudioBufferList*            list;
+    UInt32                      i;
+
+    list = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(AudioBufferList) + numChannels * sizeof(AudioBuffer));
+    if (list == NULL)
+        return NULL;
+
+    list->mNumberBuffers = numChannels;
+    for (i = 0; i < numChannels; ++i)
+    {
+        list->mBuffers[i].mNumberChannels = 1;
+        list->mBuffers[i].mDataByteSize = size;
+        list->mBuffers[i].mData = HeapAlloc(GetProcessHeap(), 0, size);
+        if (list->mBuffers[i].mData == NULL)
+        {
+            widHelper_DestroyAudioBufferList(list);
+            return NULL;
+        }
+    }
+    return list;
+}
+
+
+/**************************************************************************
  *                              widOpen                         [internal]
  */
 static DWORD widOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
 {
     WINE_WAVEIN*    wwi;
     UInt32          frameCount;
+    UInt32          bytesPerFrame;
 
     TRACE("(%u, %p, %08X);\n", wDevID, lpDesc, dwFlags);
     if (lpDesc == NULL)
@@ -1601,6 +1651,19 @@ static DWORD widOpen(WORD wDevID, LPWAVE
         return MMSYSERR_ERROR;
     }
 
+    /* Allocate our audio buffers */
+    /* For interleaved audio, we allocate one buffer for all channels. */
+    bytesPerFrame = wwi->format.wBitsPerSample * wwi->format.wf.nChannels / 8;
+    wwi->bufferList = widHelper_AllocateAudioBufferList(1, wwi->format.wf.nChannels * frameCount * bytesPerFrame);
+    if (wwi->bufferList == NULL)
+    {
+        ERR("Failed to allocate buffer list\n");
+        AudioUnitUninitialize(wwi->audioUnit);
+        AudioUnit_CloseAudioUnit(wwi->audioUnit);
+        OSSpinLockUnlock(&wwi->lock);
+        return MMSYSERR_NOMEM;
+    }
+
     OSSpinLockUnlock(&wwi->lock);
 
     return widNotifyClient(wwi, WIM_OPEN, 0L, 0L);
@@ -1658,6 +1721,10 @@ static DWORD widClose(WORD wDevID)
             ERR("Can't close AudioUnit\n");
         }
 
+        /* Dellocate our audio buffers */
+        widHelper_DestroyAudioBufferList(wwi->bufferList);
+        wwi->bufferList = NULL;
+
         ret = widNotifyClient(wwi, WIM_CLOSE, 0L, 0L);
     }
 




More information about the wine-cvs mailing list