📄 capture.c
字号:
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 WINAPI
IDirectSoundCaptureBufferImpl_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 WINAPI
IDirectSoundCaptureBufferImpl_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 WINAPI
IDirectSoundCaptureBufferImpl_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 WINAPI
IDirectSoundCaptureBufferImpl_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 WINAPI
IDirectSoundCaptureBufferImpl_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 WINAPI
IDirectSoundCaptureBufferImpl_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 WINAPI
IDirectSoundCaptureBufferImpl_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 WINAPI
IDirectSoundCaptureBufferImpl_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 + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -