capture.c
来自「一个类似windows」· C语言 代码 · 共 1,798 行 · 第 1/4 页
C
1,798 行
WARN("waveInOpen failed\n"); This->dsound->device->capture_buffer = 0; HeapFree( GetProcessHeap(), 0, This ); *ppobj = NULL; return err; } buflen = lpcDSCBufferDesc->dwBufferBytes; TRACE("desired buflen=%ld, old buffer=%p\n", buflen, ipDSC->device->buffer); if (ipDSC->device->buffer) newbuf = HeapReAlloc(GetProcessHeap(),0,ipDSC->device->buffer,buflen); else newbuf = HeapAlloc(GetProcessHeap(),0,buflen); if (newbuf == NULL) { WARN("failed to allocate capture buffer\n"); err = DSERR_OUTOFMEMORY; /* but the old buffer might still exist and must be re-prepared */ } else { ipDSC->device->buffer = newbuf; ipDSC->device->buflen = buflen; } } } TRACE("returning DS_OK\n"); return DS_OK;}/******************************************************************************* * IDirectSoundCaptureNotify */static HRESULT WINAPI IDirectSoundCaptureNotifyImpl_QueryInterface( LPDIRECTSOUNDNOTIFY iface, REFIID riid, LPVOID *ppobj){ IDirectSoundCaptureNotifyImpl *This = (IDirectSoundCaptureNotifyImpl *)iface; TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj); if (This->dscb == NULL) { WARN("invalid parameter\n"); return E_INVALIDARG; } return IDirectSoundCaptureBuffer_QueryInterface((LPDIRECTSOUNDCAPTUREBUFFER)This->dscb, riid, ppobj);}static ULONG WINAPI IDirectSoundCaptureNotifyImpl_AddRef(LPDIRECTSOUNDNOTIFY iface){ IDirectSoundCaptureNotifyImpl *This = (IDirectSoundCaptureNotifyImpl *)iface; ULONG ref = InterlockedIncrement(&(This->ref)); TRACE("(%p) ref was %ld\n", This, ref - 1); return ref;}static ULONG WINAPI IDirectSoundCaptureNotifyImpl_Release(LPDIRECTSOUNDNOTIFY iface){ IDirectSoundCaptureNotifyImpl *This = (IDirectSoundCaptureNotifyImpl *)iface; ULONG ref = InterlockedDecrement(&(This->ref)); TRACE("(%p) ref was %ld\n", This, ref + 1); if (!ref) { if (This->dscb->hwnotify) IDsDriverNotify_Release(This->dscb->hwnotify); This->dscb->notify=NULL; IDirectSoundCaptureBuffer_Release((LPDIRECTSOUNDCAPTUREBUFFER)This->dscb); HeapFree(GetProcessHeap(),0,This); TRACE("(%p) released\n", This); } return ref;}static HRESULT WINAPI IDirectSoundCaptureNotifyImpl_SetNotificationPositions( LPDIRECTSOUNDNOTIFY iface, DWORD howmuch, LPCDSBPOSITIONNOTIFY notify){ IDirectSoundCaptureNotifyImpl *This = (IDirectSoundCaptureNotifyImpl *)iface; TRACE("(%p,0x%08lx,%p)\n",This,howmuch,notify); if (howmuch > 0 && notify == NULL) { WARN("invalid parameter: notify == NULL\n"); return DSERR_INVALIDPARAM; } if (TRACE_ON(dsound)) { unsigned int i; for (i=0;i<howmuch;i++) TRACE("notify at %ld to %p\n", notify[i].dwOffset,notify[i].hEventNotify); } if (This->dscb->hwnotify) { HRESULT hres; hres = IDsDriverNotify_SetNotificationPositions(This->dscb->hwnotify, howmuch, notify); if (hres != DS_OK) WARN("IDsDriverNotify_SetNotificationPositions failed\n"); return hres; } else if (howmuch > 0) { /* Make an internal copy of the caller-supplied array. * Replace the existing copy if one is already present. */ if (This->dscb->notifies) This->dscb->notifies = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->dscb->notifies, howmuch * sizeof(DSBPOSITIONNOTIFY)); else This->dscb->notifies = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, howmuch * sizeof(DSBPOSITIONNOTIFY)); if (This->dscb->notifies == NULL) { WARN("out of memory\n"); return DSERR_OUTOFMEMORY; } CopyMemory(This->dscb->notifies, notify, howmuch * sizeof(DSBPOSITIONNOTIFY)); This->dscb->nrofnotifies = howmuch; } else { HeapFree(GetProcessHeap(), 0, This->dscb->notifies); This->dscb->notifies = NULL; This->dscb->nrofnotifies = 0; } return S_OK;}static const IDirectSoundNotifyVtbl dscnvt ={ IDirectSoundCaptureNotifyImpl_QueryInterface, IDirectSoundCaptureNotifyImpl_AddRef, IDirectSoundCaptureNotifyImpl_Release, IDirectSoundCaptureNotifyImpl_SetNotificationPositions,};HRESULT WINAPI IDirectSoundCaptureNotifyImpl_Create( IDirectSoundCaptureBufferImpl *dscb, IDirectSoundCaptureNotifyImpl **pdscn){ IDirectSoundCaptureNotifyImpl * dscn; TRACE("(%p,%p)\n",dscb,pdscn); dscn = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(dscn)); if (dscn == NULL) { WARN("out of memory\n"); return DSERR_OUTOFMEMORY; } dscn->ref = 0; dscn->lpVtbl = &dscnvt; dscn->dscb = dscb; dscb->notify = dscn; IDirectSoundCaptureBuffer_AddRef((LPDIRECTSOUNDCAPTUREBUFFER)dscb); *pdscn = dscn; return DS_OK;}/******************************************************************************* * IDirectSoundCaptureBuffer */static HRESULT WINAPIIDirectSoundCaptureBufferImpl_QueryInterface( LPDIRECTSOUNDCAPTUREBUFFER8 iface, REFIID riid, LPVOID* ppobj ){ IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface; HRESULT hres; TRACE( "(%p,%s,%p)\n", This, debugstr_guid(riid), ppobj ); if (ppobj == NULL) { WARN("invalid parameter\n"); return E_INVALIDARG; } *ppobj = NULL; if ( IsEqualGUID( &IID_IDirectSoundNotify, riid ) ) { if (!This->notify) hres = IDirectSoundCaptureNotifyImpl_Create(This, &This->notify); if (This->notify) { if (This->dsound->device->hwbuf) { hres = IDsCaptureDriverBuffer_QueryInterface(This->dsound->device->hwbuf, &IID_IDsDriverNotify, (LPVOID*)&(This->hwnotify)); if (hres != DS_OK) { WARN("IDsCaptureDriverBuffer_QueryInterface failed\n"); *ppobj = 0; return hres; } } IDirectSoundNotify_AddRef((LPDIRECTSOUNDNOTIFY)This->notify); *ppobj = (LPVOID)This->notify; return DS_OK; } WARN("IID_IDirectSoundNotify\n"); return E_FAIL; } if ( IsEqualGUID( &IID_IDirectSoundCaptureBuffer, riid ) || IsEqualGUID( &IID_IDirectSoundCaptureBuffer8, riid ) ) { IDirectSoundCaptureBuffer8_AddRef(iface); *ppobj = This; return NO_ERROR; } FIXME("(%p,%s,%p) unsupported GUID\n", This, debugstr_guid(riid), ppobj); return E_NOINTERFACE;}static ULONG WINAPIIDirectSoundCaptureBufferImpl_AddRef( LPDIRECTSOUNDCAPTUREBUFFER8 iface ){ IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface; ULONG ref = InterlockedIncrement(&(This->ref)); TRACE("(%p) ref was %ld\n", This, ref - 1); return ref;}static ULONG WINAPIIDirectSoundCaptureBufferImpl_Release( LPDIRECTSOUNDCAPTUREBUFFER8 iface ){ IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface; ULONG ref = InterlockedDecrement(&(This->ref)); TRACE("(%p) ref was %ld\n", This, ref + 1); if (!ref) { TRACE("deleting object\n"); if (This->dsound->device->state == STATE_CAPTURING) This->dsound->device->state = STATE_STOPPING; HeapFree(GetProcessHeap(),0, This->pdscbd); if (This->dsound->device->hwi) { waveInReset(This->dsound->device->hwi); waveInClose(This->dsound->device->hwi); HeapFree(GetProcessHeap(),0, This->dsound->device->pwave); This->dsound->device->pwave = 0; This->dsound->device->hwi = 0; } if (This->dsound->device->hwbuf) IDsCaptureDriverBuffer_Release(This->dsound->device->hwbuf); /* remove from IDirectSoundCaptureImpl */ if (This->dsound) This->dsound->device->capture_buffer = NULL; else ERR("does not reference dsound\n"); if (This->notify) IDirectSoundNotify_Release((LPDIRECTSOUNDNOTIFY)This->notify); HeapFree(GetProcessHeap(), 0, This->notifies); HeapFree( GetProcessHeap(), 0, This ); TRACE("(%p) released\n", This); } return ref;}static HRESULT WINAPIIDirectSoundCaptureBufferImpl_GetCaps( LPDIRECTSOUNDCAPTUREBUFFER8 iface, LPDSCBCAPS lpDSCBCaps ){ IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface; TRACE( "(%p,%p)\n", This, lpDSCBCaps ); if (This == NULL) { WARN("invalid parameter: This == NULL\n"); return DSERR_INVALIDPARAM; } if (lpDSCBCaps == NULL) { WARN("invalid parameter: lpDSCBCaps == NULL\n"); return DSERR_INVALIDPARAM; } if (lpDSCBCaps->dwSize < sizeof(DSCBCAPS)) { WARN("invalid parameter: lpDSCBCaps->dwSize = %ld < %d\n", lpDSCBCaps->dwSize, sizeof(DSCBCAPS)); return DSERR_INVALIDPARAM; } if (This->dsound == NULL) { WARN("invalid parameter: This->dsound == NULL\n"); return DSERR_INVALIDPARAM; } lpDSCBCaps->dwSize = sizeof(DSCBCAPS); lpDSCBCaps->dwFlags = This->flags; lpDSCBCaps->dwBufferBytes = This->pdscbd->dwBufferBytes; lpDSCBCaps->dwReserved = 0; TRACE("returning DS_OK\n"); return DS_OK;}static HRESULT WINAPIIDirectSoundCaptureBufferImpl_GetCurrentPosition( LPDIRECTSOUNDCAPTUREBUFFER8 iface, LPDWORD lpdwCapturePosition, LPDWORD lpdwReadPosition ){ IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface; HRESULT hres = DS_OK; TRACE( "(%p,%p,%p)\n", This, lpdwCapturePosition, lpdwReadPosition ); if (This == NULL) { WARN("invalid parameter: This == NULL\n"); return DSERR_INVALIDPARAM; } if (This->dsound == NULL) { WARN("invalid parameter: This->dsound == NULL\n"); return DSERR_INVALIDPARAM; } if (This->dsound->device->driver) { hres = IDsCaptureDriverBuffer_GetPosition(This->dsound->device->hwbuf, lpdwCapturePosition, lpdwReadPosition ); if (hres != DS_OK) WARN("IDsCaptureDriverBuffer_GetPosition failed\n"); } else if (This->dsound->device->hwi) { EnterCriticalSection(&(This->dsound->device->lock)); TRACE("old This->dsound->device->state=%s\n",captureStateString[This->dsound->device->state]); if (lpdwCapturePosition) { MMTIME mtime; mtime.wType = TIME_BYTES; waveInGetPosition(This->dsound->device->hwi, &mtime, sizeof(mtime)); TRACE("mtime.u.cb=%ld,This->dsound->device->buflen=%ld\n", mtime.u.cb, This->dsound->device->buflen); mtime.u.cb = mtime.u.cb % This->dsound->device->buflen; *lpdwCapturePosition = mtime.u.cb; } if (lpdwReadPosition) { if (This->dsound->device->state == STATE_STARTING) { if (lpdwCapturePosition) This->dsound->device->read_position = *lpdwCapturePosition; This->dsound->device->state = STATE_CAPTURING; } *lpdwReadPosition = This->dsound->device->read_position; } TRACE("new This->dsound->device->state=%s\n",captureStateString[This->dsound->device->state]); LeaveCriticalSection(&(This->dsound->device->lock)); if (lpdwCapturePosition) TRACE("*lpdwCapturePosition=%ld\n",*lpdwCapturePosition); if (lpdwReadPosition) TRACE("*lpdwReadPosition=%ld\n",*lpdwReadPosition); } else { WARN("no driver\n"); hres = DSERR_NODRIVER; } TRACE("returning %08lx\n", hres); return hres;}static HRESULT WINAPIIDirectSoundCaptureBufferImpl_GetFormat( LPDIRECTSOUNDCAPTUREBUFFER8 iface, LPWAVEFORMATEX lpwfxFormat, DWORD dwSizeAllocated, LPDWORD lpdwSizeWritten ){ IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface; HRESULT hres = DS_OK; TRACE( "(%p,%p,0x%08lx,%p)\n", This, lpwfxFormat, dwSizeAllocated, lpdwSizeWritten ); if (This == NULL) { WARN("invalid parameter: This == NULL\n"); return DSERR_INVALIDPARAM; } if (This->dsound == NULL) { WARN("invalid parameter: This->dsound == NULL\n"); return DSERR_INVALIDPARAM; } if (dwSizeAllocated > (sizeof(WAVEFORMATEX) + This->dsound->device->pwfx->cbSize)) dwSizeAllocated = sizeof(WAVEFORMATEX) + This->dsound->device->pwfx->cbSize; if (lpwfxFormat) { /* NULL is valid (just want size) */ CopyMemory(lpwfxFormat, This->dsound->device->pwfx, dwSizeAllocated); if (lpdwSizeWritten) *lpdwSizeWritten = dwSizeAllocated; } else { if (lpdwSizeWritten) *lpdwSizeWritten = sizeof(WAVEFORMATEX) + This->dsound->device->pwfx->cbSize; else { TRACE("invalid parameter: lpdwSizeWritten = NULL\n"); hres = DSERR_INVALIDPARAM; } } TRACE("returning %08lx\n", hres); return hres;}static HRESULT WINAPIIDirectSoundCaptureBufferImpl_GetStatus( LPDIRECTSOUNDCAPTUREBUFFER8 iface, LPDWORD lpdwStatus ){ IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface; TRACE( "(%p, %p), thread is %04lx\n", This, lpdwStatus, GetCurrentThreadId() ); if (This == NULL) { WARN("invalid parameter: This == NULL\n"); return DSERR_INVALIDPARAM; } if (This->dsound == NULL) { WARN("invalid parameter: This->dsound == NULL\n"); return DSERR_INVALIDPARAM; } if (lpdwStatus == NULL) { WARN("invalid parameter: lpdwStatus == NULL\n"); return DSERR_INVALIDPARAM; } *lpdwStatus = 0; EnterCriticalSection(&(This->dsound->device->lock)); TRACE("old This->dsound->state=%s, old lpdwStatus=%08lx\n", captureStateString[This->dsound->device->state],*lpdwStatus); if ((This->dsound->device->state == STATE_STARTING) || (This->dsound->device->state == STATE_CAPTURING)) { *lpdwStatus |= DSCBSTATUS_CAPTURING; if (This->flags & DSCBSTART_LOOPING) *lpdwStatus |= DSCBSTATUS_LOOPING; } TRACE("new This->dsound->state=%s, new lpdwStatus=%08lx\n", captureStateString[This->dsound->device->state],*lpdwStatus); LeaveCriticalSection(&(This->dsound->device->lock)); TRACE("status=%lx\n", *lpdwStatus); TRACE("returning DS_OK\n"); return DS_OK;}static HRESULT WINAPIIDirectSoundCaptureBufferImpl_Initialize( LPDIRECTSOUNDCAPTUREBUFFER8 iface, LPDIRECTSOUNDCAPTURE lpDSC, LPCDSCBUFFERDESC lpcDSCBDesc ){ IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface; FIXME( "(%p,%p,%p): stub\n", This, lpDSC, lpcDSCBDesc );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?