capture.c
来自「一个类似windows」· C语言 代码 · 共 1,798 行 · 第 1/4 页
C
1,798 行
return DS_OK;}static HRESULT WINAPIIDirectSoundCaptureBufferImpl_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 WINAPIIDirectSoundCaptureBufferImpl_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 WINAPIIDirectSoundCaptureBufferImpl_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 WINAPIIDirectSoundCaptureBufferImpl_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 WINAPIIDirectSoundCaptureBufferImpl_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 WINAPIIDirectSoundCaptureBufferImpl_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 WINAPIDSCCF_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 WINAPIDSCCF_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 WINAPIDSCCF_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 WINAPIDSCCF_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 WINAPIDSCCF_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 + =
减小字号Ctrl + -
显示快捷键?