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 + -
显示快捷键?