📄 capture.c
字号:
return DS_OK;
}
static HRESULT WINAPI
IDirectSoundCaptureBufferImpl_Lock(
LPDIRECTSOUNDCAPTUREBUFFER8 iface,
DWORD dwReadCusor,
DWORD dwReadBytes,
LPVOID* lplpvAudioPtr1,
LPDWORD lpdwAudioBytes1,
LPVOID* lplpvAudioPtr2,
LPDWORD lpdwAudioBytes2,
DWORD dwFlags )
{
HRESULT hres = DS_OK;
IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface;
TRACE( "(%p,%08lu,%08lu,%p,%p,%p,%p,0x%08lx) at %ld\n", This, dwReadCusor,
dwReadBytes, lplpvAudioPtr1, lpdwAudioBytes1, lplpvAudioPtr2,
lpdwAudioBytes2, dwFlags, GetTickCount() );
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 (lplpvAudioPtr1 == NULL) {
WARN("invalid parameter: lplpvAudioPtr1 == NULL\n");
return DSERR_INVALIDPARAM;
}
if (lpdwAudioBytes1 == NULL) {
WARN("invalid parameter: lpdwAudioBytes1 == NULL\n");
return DSERR_INVALIDPARAM;
}
EnterCriticalSection(&(This->dsound->device->lock));
if (This->dsound->device->driver) {
hres = IDsCaptureDriverBuffer_Lock(This->dsound->device->hwbuf, lplpvAudioPtr1,
lpdwAudioBytes1, lplpvAudioPtr2,
lpdwAudioBytes2, dwReadCusor,
dwReadBytes, dwFlags);
if (hres != DS_OK)
WARN("IDsCaptureDriverBuffer_Lock failed\n");
} else if (This->dsound->device->hwi) {
*lplpvAudioPtr1 = This->dsound->device->buffer + dwReadCusor;
if ( (dwReadCusor + dwReadBytes) > This->dsound->device->buflen) {
*lpdwAudioBytes1 = This->dsound->device->buflen - dwReadCusor;
if (lplpvAudioPtr2)
*lplpvAudioPtr2 = This->dsound->device->buffer;
if (lpdwAudioBytes2)
*lpdwAudioBytes2 = dwReadBytes - *lpdwAudioBytes1;
} else {
*lpdwAudioBytes1 = dwReadBytes;
if (lplpvAudioPtr2)
*lplpvAudioPtr2 = 0;
if (lpdwAudioBytes2)
*lpdwAudioBytes2 = 0;
}
} else {
TRACE("invalid call\n");
hres = DSERR_INVALIDCALL; /* DSERR_NODRIVER ? */
}
LeaveCriticalSection(&(This->dsound->device->lock));
TRACE("returning %08lx\n", hres);
return hres;
}
static HRESULT WINAPI
IDirectSoundCaptureBufferImpl_Start(
LPDIRECTSOUNDCAPTUREBUFFER8 iface,
DWORD dwFlags )
{
HRESULT hres = DS_OK;
IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface;
TRACE( "(%p,0x%08lx)\n", This, dwFlags );
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 == 0) && (This->dsound->device->hwi == 0) ) {
WARN("no driver\n");
return DSERR_NODRIVER;
}
EnterCriticalSection(&(This->dsound->device->lock));
This->flags = dwFlags;
TRACE("old This->dsound->state=%s\n",captureStateString[This->dsound->device->state]);
if (This->dsound->device->state == STATE_STOPPED)
This->dsound->device->state = STATE_STARTING;
else if (This->dsound->device->state == STATE_STOPPING)
This->dsound->device->state = STATE_CAPTURING;
TRACE("new This->dsound->device->state=%s\n",captureStateString[This->dsound->device->state]);
LeaveCriticalSection(&(This->dsound->device->lock));
if (This->dsound->device->driver) {
hres = IDsCaptureDriverBuffer_Start(This->dsound->device->hwbuf, dwFlags);
if (hres != DS_OK)
WARN("IDsCaptureDriverBuffer_Start failed\n");
} else if (This->dsound->device->hwi) {
IDirectSoundCaptureImpl* ipDSC = This->dsound;
if (ipDSC->device->buffer) {
if (This->nrofnotifies) {
int c;
ipDSC->device->nrofpwaves = This->nrofnotifies;
TRACE("nrofnotifies=%d\n", This->nrofnotifies);
/* prepare headers */
if (ipDSC->device->pwave)
ipDSC->device->pwave = HeapReAlloc(GetProcessHeap(),0,ipDSC->device->pwave,
ipDSC->device->nrofpwaves*sizeof(WAVEHDR));
else
ipDSC->device->pwave = HeapAlloc(GetProcessHeap(),0,
ipDSC->device->nrofpwaves*sizeof(WAVEHDR));
for (c = 0; c < ipDSC->device->nrofpwaves; c++) {
if (This->notifies[c].dwOffset == DSBPN_OFFSETSTOP) {
TRACE("got DSBPN_OFFSETSTOP\n");
ipDSC->device->nrofpwaves = c;
break;
}
if (c == 0) {
ipDSC->device->pwave[0].lpData = (LPSTR)ipDSC->device->buffer;
ipDSC->device->pwave[0].dwBufferLength =
This->notifies[0].dwOffset + 1;
} else {
ipDSC->device->pwave[c].lpData = (LPSTR)ipDSC->device->buffer +
This->notifies[c-1].dwOffset + 1;
ipDSC->device->pwave[c].dwBufferLength =
This->notifies[c].dwOffset -
This->notifies[c-1].dwOffset;
}
ipDSC->device->pwave[c].dwBytesRecorded = 0;
ipDSC->device->pwave[c].dwUser = (DWORD)ipDSC;
ipDSC->device->pwave[c].dwFlags = 0;
ipDSC->device->pwave[c].dwLoops = 0;
hres = mmErr(waveInPrepareHeader(ipDSC->device->hwi,
&(ipDSC->device->pwave[c]),sizeof(WAVEHDR)));
if (hres != DS_OK) {
WARN("waveInPrepareHeader failed\n");
while (c--)
waveInUnprepareHeader(ipDSC->device->hwi,
&(ipDSC->device->pwave[c]),sizeof(WAVEHDR));
break;
}
hres = mmErr(waveInAddBuffer(ipDSC->device->hwi,
&(ipDSC->device->pwave[c]), sizeof(WAVEHDR)));
if (hres != DS_OK) {
WARN("waveInAddBuffer failed\n");
while (c--)
waveInUnprepareHeader(ipDSC->device->hwi,
&(ipDSC->device->pwave[c]),sizeof(WAVEHDR));
break;
}
}
FillMemory(ipDSC->device->buffer, ipDSC->device->buflen,
(ipDSC->device->pwfx->wBitsPerSample == 8) ? 128 : 0);
} else {
TRACE("no notifiers specified\n");
/* no notifiers specified so just create a single default header */
ipDSC->device->nrofpwaves = 1;
if (ipDSC->device->pwave)
ipDSC->device->pwave = HeapReAlloc(GetProcessHeap(),0,ipDSC->device->pwave,sizeof(WAVEHDR));
else
ipDSC->device->pwave = HeapAlloc(GetProcessHeap(),0,sizeof(WAVEHDR));
ipDSC->device->pwave[0].lpData = (LPSTR)ipDSC->device->buffer;
ipDSC->device->pwave[0].dwBufferLength = ipDSC->device->buflen;
ipDSC->device->pwave[0].dwBytesRecorded = 0;
ipDSC->device->pwave[0].dwUser = (DWORD)ipDSC;
ipDSC->device->pwave[0].dwFlags = 0;
ipDSC->device->pwave[0].dwLoops = 0;
hres = mmErr(waveInPrepareHeader(ipDSC->device->hwi,
&(ipDSC->device->pwave[0]),sizeof(WAVEHDR)));
if (hres != DS_OK) {
WARN("waveInPrepareHeader failed\n");
waveInUnprepareHeader(ipDSC->device->hwi,
&(ipDSC->device->pwave[0]),sizeof(WAVEHDR));
}
hres = mmErr(waveInAddBuffer(ipDSC->device->hwi,
&(ipDSC->device->pwave[0]), sizeof(WAVEHDR)));
if (hres != DS_OK) {
WARN("waveInAddBuffer failed\n");
waveInUnprepareHeader(ipDSC->device->hwi,
&(ipDSC->device->pwave[0]),sizeof(WAVEHDR));
}
}
}
ipDSC->device->index = 0;
ipDSC->device->read_position = 0;
if (hres == DS_OK) {
/* start filling the first buffer */
hres = mmErr(waveInStart(ipDSC->device->hwi));
if (hres != DS_OK)
WARN("waveInStart failed\n");
}
if (hres != DS_OK) {
WARN("calling waveInClose because of error\n");
waveInClose(This->dsound->device->hwi);
This->dsound->device->hwi = 0;
}
} else {
WARN("no driver\n");
hres = DSERR_NODRIVER;
}
TRACE("returning %08lx\n", hres);
return hres;
}
static HRESULT WINAPI
IDirectSoundCaptureBufferImpl_Stop( LPDIRECTSOUNDCAPTUREBUFFER8 iface )
{
HRESULT hres = DS_OK;
IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface;
TRACE( "(%p)\n", This );
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;
}
EnterCriticalSection(&(This->dsound->device->lock));
TRACE("old This->dsound->state=%s\n",captureStateString[This->dsound->device->state]);
if (This->dsound->device->state == STATE_CAPTURING)
This->dsound->device->state = STATE_STOPPING;
else if (This->dsound->device->state == STATE_STARTING)
This->dsound->device->state = STATE_STOPPED;
TRACE("new This->dsound->device->state=%s\n",captureStateString[This->dsound->device->state]);
LeaveCriticalSection(&(This->dsound->device->lock));
if (This->dsound->device->driver) {
hres = IDsCaptureDriverBuffer_Stop(This->dsound->device->hwbuf);
if (hres != DS_OK)
WARN("IDsCaptureDriverBuffer_Stop() failed\n");
} else if (This->dsound->device->hwi) {
hres = mmErr(waveInReset(This->dsound->device->hwi));
if (hres != DS_OK)
WARN("waveInReset() failed\n");
} else {
WARN("no driver\n");
hres = DSERR_NODRIVER;
}
TRACE("returning %08lx\n", hres);
return hres;
}
static HRESULT WINAPI
IDirectSoundCaptureBufferImpl_Unlock(
LPDIRECTSOUNDCAPTUREBUFFER8 iface,
LPVOID lpvAudioPtr1,
DWORD dwAudioBytes1,
LPVOID lpvAudioPtr2,
DWORD dwAudioBytes2 )
{
HRESULT hres = DS_OK;
IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface;
TRACE( "(%p,%p,%08lu,%p,%08lu)\n", This, lpvAudioPtr1, dwAudioBytes1,
lpvAudioPtr2, dwAudioBytes2 );
if (This == NULL) {
WARN("invalid parameter: This == NULL\n");
return DSERR_INVALIDPARAM;
}
if (lpvAudioPtr1 == NULL) {
WARN("invalid parameter: lpvAudioPtr1 == NULL\n");
return DSERR_INVALIDPARAM;
}
if (This->dsound->device->driver) {
hres = IDsCaptureDriverBuffer_Unlock(This->dsound->device->hwbuf, lpvAudioPtr1,
dwAudioBytes1, lpvAudioPtr2, dwAudioBytes2);
if (hres != DS_OK)
WARN("IDsCaptureDriverBuffer_Unlock failed\n");
} else if (This->dsound->device->hwi) {
This->dsound->device->read_position = (This->dsound->device->read_position +
(dwAudioBytes1 + dwAudioBytes2)) % This->dsound->device->buflen;
} else {
WARN("invalid call\n");
hres = DSERR_INVALIDCALL;
}
TRACE("returning %08lx\n", hres);
return hres;
}
static HRESULT WINAPI
IDirectSoundCaptureBufferImpl_GetObjectInPath(
LPDIRECTSOUNDCAPTUREBUFFER8 iface,
REFGUID rguidObject,
DWORD dwIndex,
REFGUID rguidInterface,
LPVOID* ppObject )
{
IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface;
FIXME( "(%p,%s,%lu,%s,%p): stub\n", This, debugstr_guid(rguidObject),
dwIndex, debugstr_guid(rguidInterface), ppObject );
return DS_OK;
}
static HRESULT WINAPI
IDirectSoundCaptureBufferImpl_GetFXStatus(
LPDIRECTSOUNDCAPTUREBUFFER8 iface,
DWORD dwFXCount,
LPDWORD pdwFXStatus )
{
IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface;
FIXME( "(%p,%lu,%p): stub\n", This, dwFXCount, pdwFXStatus );
return DS_OK;
}
static const IDirectSoundCaptureBuffer8Vtbl dscbvt =
{
/* IUnknown methods */
IDirectSoundCaptureBufferImpl_QueryInterface,
IDirectSoundCaptureBufferImpl_AddRef,
IDirectSoundCaptureBufferImpl_Release,
/* IDirectSoundCaptureBuffer methods */
IDirectSoundCaptureBufferImpl_GetCaps,
IDirectSoundCaptureBufferImpl_GetCurrentPosition,
IDirectSoundCaptureBufferImpl_GetFormat,
IDirectSoundCaptureBufferImpl_GetStatus,
IDirectSoundCaptureBufferImpl_Initialize,
IDirectSoundCaptureBufferImpl_Lock,
IDirectSoundCaptureBufferImpl_Start,
IDirectSoundCaptureBufferImpl_Stop,
IDirectSoundCaptureBufferImpl_Unlock,
/* IDirectSoundCaptureBuffer methods */
IDirectSoundCaptureBufferImpl_GetObjectInPath,
IDirectSoundCaptureBufferImpl_GetFXStatus
};
/*******************************************************************************
* DirectSoundCapture ClassFactory
*/
static HRESULT WINAPI
DSCCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj)
{
IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj);
return E_NOINTERFACE;
}
static ULONG WINAPI
DSCCF_AddRef(LPCLASSFACTORY iface)
{
IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
ULONG ref = InterlockedIncrement(&(This->ref));
TRACE("(%p) ref was %ld\n", This, ref - 1);
return ref;
}
static ULONG WINAPI
DSCCF_Release(LPCLASSFACTORY iface)
{
IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
ULONG ref = InterlockedDecrement(&(This->ref));
TRACE("(%p) ref was %ld\n", This, ref + 1);
/* static class, won't be freed */
return ref;
}
static HRESULT WINAPI
DSCCF_CreateInstance(
LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj )
{
IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
if (pOuter) {
WARN("aggregation not supported\n");
return CLASS_E_NOAGGREGATION;
}
if (ppobj == NULL) {
WARN("invalid parameter\n");
return E_INVALIDARG;
}
*ppobj = NULL;
if ( IsEqualGUID( &IID_IDirectSoundCapture, riid ) )
return DSOUND_CaptureCreate8((LPDIRECTSOUNDCAPTURE*)ppobj,pOuter);
WARN("(%p,%p,%s,%p) Interface not found!\n",This,pOuter,debugstr_guid(riid),ppobj);
return E_NOINTERFACE;
}
static HRESULT WINAPI
DSCCF_LockServer(LPCLASSFACTORY iface,BOOL dolock)
{
IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
FIXME("(%p)->(%d),stub!\n",This,dolock);
return S_OK;
}
static const IClassFactoryVtbl DSCCF_Vtbl =
{
DSCCF_QueryInterface,
DSCCF_AddRef,
DSCCF_Release,
DSCCF_CreateInstance,
DSCCF_LockServer
};
IClassFactoryImpl DSOUND_CAPTURE_CF = { &DSCCF_Vtbl, 1 };
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -