From 23bc426e147341152d2343edd5f9a7e5bbda1cd8 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Wed, 15 Aug 2007 16:11:38 +0200 Subject: [PATCH] winealsa: Add IDsCaptureDriverBuffer stub. --- dlls/winealsa.drv/dscapture.c | 211 +++++++++++++++++++++++++++++++++- 1 file changed, 209 insertions(+), 2 deletions(-) diff --git a/dlls/winealsa.drv/dscapture.c b/dlls/winealsa.drv/dscapture.c index 24871c71fd7..233f6eea9e6 100644 --- a/dlls/winealsa.drv/dscapture.c +++ b/dlls/winealsa.drv/dscapture.c @@ -59,6 +59,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(dsalsa); typedef struct IDsCaptureDriverImpl IDsCaptureDriverImpl; +typedef struct IDsCaptureDriverBufferImpl IDsCaptureDriverBufferImpl; struct IDsCaptureDriverImpl { @@ -67,9 +68,171 @@ struct IDsCaptureDriverImpl LONG ref; /* IDsCaptureDriverImpl fields */ + IDsCaptureDriverBufferImpl* capture_buffer; UINT wDevID; }; +struct IDsCaptureDriverBufferImpl +{ + const IDsCaptureDriverBufferVtbl *lpVtbl; + LONG ref; + IDsCaptureDriverImpl* drv; + + CRITICAL_SECTION pcm_crst; + LPBYTE mmap_buffer, presented_buffer; + DWORD mmap_buflen_bytes, play_looping, mmap_ofs_bytes; +}; + +static HRESULT WINAPI IDsCaptureDriverBufferImpl_QueryInterface(PIDSCDRIVERBUFFER iface, REFIID riid, LPVOID *ppobj) +{ + /* IDsCaptureDriverBufferImpl *This = (IDsCaptureDriverBufferImpl *)iface; */ + FIXME("(): stub!\n"); + return DSERR_UNSUPPORTED; +} + +static ULONG WINAPI IDsCaptureDriverBufferImpl_AddRef(PIDSCDRIVERBUFFER iface) +{ + IDsCaptureDriverBufferImpl *This = (IDsCaptureDriverBufferImpl *)iface; + ULONG refCount = InterlockedIncrement(&This->ref); + + TRACE("(%p)->(ref before=%u)\n",This, refCount - 1); + + return refCount; +} + +static ULONG WINAPI IDsCaptureDriverBufferImpl_Release(PIDSCDRIVERBUFFER iface) +{ + IDsCaptureDriverBufferImpl *This = (IDsCaptureDriverBufferImpl *)iface; + ULONG refCount = InterlockedDecrement(&This->ref); + + TRACE("(%p)->(ref before=%u)\n",This, refCount + 1); + + if (refCount) + return refCount; + + TRACE("mmap buffer %p destroyed\n", This->mmap_buffer); + + This->drv->capture_buffer = NULL; + This->pcm_crst.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&This->pcm_crst); + + HeapFree(GetProcessHeap(), 0, This->presented_buffer); + HeapFree(GetProcessHeap(), 0, This); + return 0; +} + +static HRESULT WINAPI IDsCaptureDriverBufferImpl_Lock(PIDSCDRIVERBUFFER iface, LPVOID*ppvAudio1,LPDWORD pdwLen1,LPVOID*ppvAudio2,LPDWORD pdwLen2, DWORD dwWritePosition,DWORD dwWriteLen, DWORD dwFlags) +{ + IDsCaptureDriverBufferImpl *This = (IDsCaptureDriverBufferImpl *)iface; + TRACE("(%p,%p,%p,%p,%p,%d,%d,0x%08x)\n", This, ppvAudio1, pdwLen1, ppvAudio2, pdwLen2, dwWritePosition, dwWriteLen, dwFlags); + + if (ppvAudio1) + *ppvAudio1 = (LPBYTE)This->presented_buffer + dwWritePosition; + + if (dwWritePosition + dwWriteLen < This->mmap_buflen_bytes) { + if (pdwLen1) + *pdwLen1 = dwWriteLen; + if (ppvAudio2) + *ppvAudio2 = 0; + if (pdwLen2) + *pdwLen2 = 0; + } else { + if (pdwLen1) + *pdwLen1 = This->mmap_buflen_bytes - dwWritePosition; + if (ppvAudio2) + *ppvAudio2 = This->presented_buffer; + if (pdwLen2) + *pdwLen2 = dwWriteLen - (This->mmap_buflen_bytes - dwWritePosition); + } + return DS_OK; +} + +static HRESULT WINAPI IDsCaptureDriverBufferImpl_Unlock(PIDSCDRIVERBUFFER iface, LPVOID pvAudio1,DWORD dwLen1, LPVOID pvAudio2,DWORD dwLen2) +{ + IDsCaptureDriverBufferImpl *This = (IDsCaptureDriverBufferImpl *)iface; + TRACE("(%p,%p,%d,%p,%d)\n",This,pvAudio1,dwLen1,pvAudio2,dwLen2); + return DS_OK; +} + +static HRESULT WINAPI IDsCaptureDriverBufferImpl_SetFormat(PIDSCDRIVERBUFFER iface, LPWAVEFORMATEX pwfx) +{ + FIXME("stub!\n"); + return DSERR_BADFORMAT; +} + +static HRESULT WINAPI IDsCaptureDriverBufferImpl_GetPosition(PIDSCDRIVERBUFFER iface, LPDWORD lpdwCappos, LPDWORD lpdwReadpos) +{ + FIXME("stub!\n"); + return DSERR_GENERIC; +} + +static HRESULT WINAPI IDsCaptureDriverBufferImpl_GetStatus(PIDSCDRIVERBUFFER iface, LPDWORD lpdwStatus) +{ + IDsCaptureDriverBufferImpl *This = (IDsCaptureDriverBufferImpl *)iface; + snd_pcm_state_t state; + TRACE("(%p,%p)\n",iface,lpdwStatus); + + state = 0; + switch (state) + { + case SND_PCM_STATE_XRUN: + case SND_PCM_STATE_SUSPENDED: + case SND_PCM_STATE_RUNNING: + *lpdwStatus = DSCBSTATUS_CAPTURING | (This->play_looping ? DSCBSTATUS_LOOPING : 0); + break; + default: + *lpdwStatus = 0; + break; + } + + TRACE("State: %d, flags: 0x%08x\n", state, *lpdwStatus); + return DS_OK; +} + +static HRESULT WINAPI IDsCaptureDriverBufferImpl_Start(PIDSCDRIVERBUFFER iface, DWORD dwFlags) +{ + IDsCaptureDriverBufferImpl *This = (IDsCaptureDriverBufferImpl *)iface; + TRACE("(%p,%x)\n",iface,dwFlags); + + /* **** */ + EnterCriticalSection(&This->pcm_crst); + This->play_looping = !!(dwFlags & DSCBSTART_LOOPING); + if (!This->play_looping) + /* Not well supported because of the difference in ALSA size and DSOUND's notion of size + * what it does right now is fill the buffer once.. ALSA size */ + FIXME("Non-looping buffers are not properly supported!\n"); + /* **** */ + LeaveCriticalSection(&This->pcm_crst); + return DS_OK; +} + +static HRESULT WINAPI IDsCaptureDriverBufferImpl_Stop(PIDSCDRIVERBUFFER iface) +{ + IDsCaptureDriverBufferImpl *This = (IDsCaptureDriverBufferImpl *)iface; + TRACE("(%p)\n",iface); + + /* **** */ + EnterCriticalSection(&This->pcm_crst); + This->play_looping = FALSE; + /* **** */ + LeaveCriticalSection(&This->pcm_crst); + return DS_OK; +} + +static const IDsCaptureDriverBufferVtbl dsdbvt = +{ + IDsCaptureDriverBufferImpl_QueryInterface, + IDsCaptureDriverBufferImpl_AddRef, + IDsCaptureDriverBufferImpl_Release, + IDsCaptureDriverBufferImpl_Lock, + IDsCaptureDriverBufferImpl_Unlock, + IDsCaptureDriverBufferImpl_SetFormat, + IDsCaptureDriverBufferImpl_GetPosition, + IDsCaptureDriverBufferImpl_GetStatus, + IDsCaptureDriverBufferImpl_Start, + IDsCaptureDriverBufferImpl_Stop +}; + static HRESULT WINAPI IDsCaptureDriverImpl_QueryInterface(PIDSCDRIVER iface, REFIID riid, LPVOID *ppobj) { /* IDsCaptureDriverImpl *This = (IDsCaptureDriverImpl *)iface; */ @@ -188,8 +351,52 @@ static HRESULT WINAPI IDsCaptureDriverImpl_CreateCaptureBuffer(PIDSCDRIVER iface LPBYTE *ppbBuffer, LPVOID *ppvObj) { - FIXME("stub!\n"); - return DSERR_GENERIC; +{ + IDsCaptureDriverImpl *This = (IDsCaptureDriverImpl *)iface; + IDsCaptureDriverBufferImpl** ippdsdb = (IDsCaptureDriverBufferImpl**)ppvObj; + HRESULT err; + + TRACE("(%p,%p,%x,%x)\n",iface,pwfx,dwFlags,dwCardAddress); + + if (This->capture_buffer) + return DSERR_ALLOCATED; + + This->capture_buffer = *ippdsdb = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDsCaptureDriverBufferImpl)); + if (*ippdsdb == NULL) + return DSERR_OUTOFMEMORY; + + (*ippdsdb)->presented_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *pdwcbBufferSize); + if (!(*ippdsdb)->presented_buffer) + { + HeapFree(GetProcessHeap(), 0, (*ippdsdb)->presented_buffer); + return DSERR_OUTOFMEMORY; + } + (*ippdsdb)->lpVtbl = &dsdbvt; + (*ippdsdb)->ref = 1; + (*ippdsdb)->drv = This; + (*ippdsdb)->mmap_buflen_bytes = *pdwcbBufferSize; + InitializeCriticalSection(&(*ippdsdb)->pcm_crst); + (*ippdsdb)->pcm_crst.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ALSA_DSCAPTURE.pcm_crst"); + + /* SetFormat initialises pcm */ + err = IDsDriverBuffer_SetFormat((IDsDriverBuffer*)*ppvObj, pwfx); + if (FAILED(err)) + { + WARN("Error occurred: %08x\n", err); + goto err; + } + *ppbBuffer = (*ippdsdb)->presented_buffer; + + /* buffer is ready to go */ + TRACE("buffer created at %p\n", *ippdsdb); + return err; + + err: + HeapFree(GetProcessHeap(), 0, (*ippdsdb)->presented_buffer); + HeapFree(GetProcessHeap(), 0, *ippdsdb); + *ippdsdb = NULL; + return err; +} } static const IDsCaptureDriverVtbl dscdvt =