capture.c
来自「一个类似windows」· C语言 代码 · 共 1,798 行 · 第 1/4 页
C
1,798 行
/* DirectSoundCapture * * Copyright 1998 Marcus Meissner * Copyright 1998 Rob Riggs * Copyright 2000-2001 TransGaming Technologies, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//* * TODO: * Implement FX support. * Implement both IDirectSoundCaptureBuffer and IDirectSoundCaptureBuffer8 * Make DirectSoundCaptureCreate and DirectSoundCaptureCreate8 behave differently */#include <stdarg.h>#define NONAMELESSSTRUCT#define NONAMELESSUNION#include "windef.h"#include "winbase.h"#include "mmsystem.h"#include "mmddk.h"#include "winreg.h"#include "winternl.h"#include "winnls.h"#include "wine/debug.h"#include "dsound.h"#include "dsdriver.h"#include "dsound_private.h"WINE_DEFAULT_DEBUG_CHANNEL(dsound);static HRESULT WINAPI IDirectSoundCaptureImpl_Initialize( LPDIRECTSOUNDCAPTURE iface, LPCGUID lpcGUID );static ULONG WINAPI IDirectSoundCaptureImpl_Release( LPDIRECTSOUNDCAPTURE iface );static ULONG WINAPI IDirectSoundCaptureBufferImpl_Release( LPDIRECTSOUNDCAPTUREBUFFER8 iface );static HRESULT DSOUND_CreateDirectSoundCaptureBuffer( IDirectSoundCaptureImpl *ipDSC, LPCDSCBUFFERDESC lpcDSCBufferDesc, LPVOID* ppobj );static const IDirectSoundCaptureVtbl dscvt;static const IDirectSoundCaptureBuffer8Vtbl dscbvt;DirectSoundCaptureDevice * DSOUND_capture[MAXWAVEDRIVERS];static const char * captureStateString[] = { "STATE_STOPPED", "STATE_STARTING", "STATE_CAPTURING", "STATE_STOPPING"};HRESULT WINAPI IDirectSoundCaptureImpl_Create( LPDIRECTSOUNDCAPTURE8 * ppDSC){ IDirectSoundCaptureImpl *pDSC; TRACE("(%p)\n", ppDSC); /* Allocate memory */ pDSC = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectSoundCaptureImpl)); if (pDSC == NULL) { WARN("out of memory\n"); *ppDSC = NULL; return DSERR_OUTOFMEMORY; } pDSC->lpVtbl = &dscvt; pDSC->ref = 0; pDSC->device = NULL; *ppDSC = (LPDIRECTSOUNDCAPTURE8)pDSC; return DS_OK;}HRESULT WINAPI DSOUND_CaptureCreate( LPDIRECTSOUNDCAPTURE *ppDSC, IUnknown *pUnkOuter){ LPDIRECTSOUNDCAPTURE pDSC; HRESULT hr; TRACE("(%p,%p)\n",ppDSC,pUnkOuter); /* Get dsound configuration */ setup_dsound_options(); hr = IDirectSoundCaptureImpl_Create(&pDSC); if (hr == DS_OK) { IDirectSoundCapture_AddRef(pDSC); *ppDSC = pDSC; } else { WARN("IDirectSoundCaptureImpl_Create failed\n"); *ppDSC = 0; } return hr;}HRESULT WINAPI DSOUND_CaptureCreate8( LPDIRECTSOUNDCAPTURE8 *ppDSC8, IUnknown *pUnkOuter){ LPDIRECTSOUNDCAPTURE8 pDSC8; HRESULT hr; TRACE("(%p,%p)\n",ppDSC8,pUnkOuter); /* Get dsound configuration */ setup_dsound_options(); hr = IDirectSoundCaptureImpl_Create(&pDSC8); if (hr == DS_OK) { IDirectSoundCapture_AddRef(pDSC8); *ppDSC8 = pDSC8; } else { WARN("IDirectSoundCaptureImpl_Create failed\n"); *ppDSC8 = 0; } return hr;}/*************************************************************************** * DirectSoundCaptureCreate [DSOUND.6] * * Create and initialize a DirectSoundCapture interface. * * PARAMS * lpcGUID [I] Address of the GUID that identifies the sound capture device. * lplpDSC [O] Address of a variable to receive the interface pointer. * pUnkOuter [I] Must be NULL. * * RETURNS * Success: DS_OK * Failure: DSERR_NOAGGREGATION, DSERR_ALLOCATED, DSERR_INVALIDPARAM, * DSERR_OUTOFMEMORY * * NOTES * lpcGUID must be one of the values returned from DirectSoundCaptureEnumerate * or NULL for the default device or DSDEVID_DefaultCapture or * DSDEVID_DefaultVoiceCapture. * * DSERR_ALLOCATED is returned for sound devices that do not support full duplex. */HRESULT WINAPI DirectSoundCaptureCreate( LPCGUID lpcGUID, LPDIRECTSOUNDCAPTURE *ppDSC, LPUNKNOWN pUnkOuter){ HRESULT hr; LPDIRECTSOUNDCAPTURE pDSC; TRACE("(%s,%p,%p)\n", debugstr_guid(lpcGUID), ppDSC, pUnkOuter); if (ppDSC == NULL) { WARN("invalid parameter: ppDSC == NULL\n"); return DSERR_INVALIDPARAM; } if (pUnkOuter) { WARN("invalid parameter: pUnkOuter != NULL\n"); *ppDSC = NULL; return DSERR_NOAGGREGATION; } hr = DSOUND_CaptureCreate(&pDSC, (IUnknown *)pUnkOuter); if (hr == DS_OK) { hr = IDirectSoundCapture_Initialize(pDSC, lpcGUID); if (hr != DS_OK) { IDirectSoundCapture_Release(pDSC); pDSC = 0; } } *ppDSC = pDSC; return hr;}/*************************************************************************** * DirectSoundCaptureCreate8 [DSOUND.12] * * Create and initialize a DirectSoundCapture interface. * * PARAMS * lpcGUID [I] Address of the GUID that identifies the sound capture device. * lplpDSC [O] Address of a variable to receive the interface pointer. * pUnkOuter [I] Must be NULL. * * RETURNS * Success: DS_OK * Failure: DSERR_NOAGGREGATION, DSERR_ALLOCATED, DSERR_INVALIDPARAM, * DSERR_OUTOFMEMORY * * NOTES * lpcGUID must be one of the values returned from DirectSoundCaptureEnumerate * or NULL for the default device or DSDEVID_DefaultCapture or * DSDEVID_DefaultVoiceCapture. * * DSERR_ALLOCATED is returned for sound devices that do not support full duplex. */HRESULT WINAPI DirectSoundCaptureCreate8( LPCGUID lpcGUID, LPDIRECTSOUNDCAPTURE8 *ppDSC8, LPUNKNOWN pUnkOuter){ HRESULT hr; LPDIRECTSOUNDCAPTURE8 pDSC8; TRACE("(%s,%p,%p)\n", debugstr_guid(lpcGUID), ppDSC8, pUnkOuter); if (ppDSC8 == NULL) { WARN("invalid parameter: ppDSC8 == NULL\n"); return DSERR_INVALIDPARAM; } if (pUnkOuter) { WARN("invalid parameter: pUnkOuter != NULL\n"); *ppDSC8 = NULL; return DSERR_NOAGGREGATION; } hr = DSOUND_CaptureCreate8(&pDSC8, (IUnknown *)pUnkOuter); if (hr == DS_OK) { hr = IDirectSoundCapture_Initialize(pDSC8, lpcGUID); if (hr != DS_OK) { IDirectSoundCapture_Release(pDSC8); pDSC8 = 0; } } *ppDSC8 = pDSC8; return hr;}static HRESULT DirectSoundCaptureDevice_Create( DirectSoundCaptureDevice ** ppDevice){ DirectSoundCaptureDevice * device; TRACE("(%p)\n", ppDevice); /* Allocate memory */ device = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DirectSoundCaptureDevice)); if (device == NULL) { WARN("out of memory\n"); return DSERR_OUTOFMEMORY; } device->ref = 1; device->state = STATE_STOPPED; InitializeCriticalSection( &(device->lock) ); device->lock.DebugInfo->Spare[0] = (DWORD_PTR)"DSCAPTURE_lock"; *ppDevice = device; return DS_OK;}/*************************************************************************** * DirectSoundCaptureEnumerateA [DSOUND.7] * * Enumerate all DirectSound drivers installed in the system. * * PARAMS * lpDSEnumCallback [I] Address of callback function. * lpContext [I] Address of user defined context passed to callback function. * * RETURNS * Success: DS_OK * Failure: DSERR_INVALIDPARAM */HRESULT WINAPIDirectSoundCaptureEnumerateA( LPDSENUMCALLBACKA lpDSEnumCallback, LPVOID lpContext){ unsigned devs, wid; DSDRIVERDESC desc; GUID guid; int err; TRACE("(%p,%p)\n", lpDSEnumCallback, lpContext ); if (lpDSEnumCallback == NULL) { WARN("invalid parameter: lpDSEnumCallback == NULL\n"); return DSERR_INVALIDPARAM; } devs = waveInGetNumDevs(); if (devs > 0) { if (GetDeviceID(&DSDEVID_DefaultCapture, &guid) == DS_OK) { for (wid = 0; wid < devs; ++wid) { if (IsEqualGUID( &guid, &DSOUND_capture_guids[wid] ) ) { err = mmErr(WineWaveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0)); if (err == DS_OK) { TRACE("calling lpDSEnumCallback(NULL,\"%s\",\"%s\",%p)\n", "Primary Sound Capture Driver",desc.szDrvname,lpContext); if (lpDSEnumCallback(NULL, "Primary Sound Capture Driver", desc.szDrvname, lpContext) == FALSE) return DS_OK; } } } } } for (wid = 0; wid < devs; ++wid) { err = mmErr(WineWaveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0)); if (err == DS_OK) { TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n", debugstr_guid(&DSOUND_capture_guids[wid]),desc.szDesc,desc.szDrvname,lpContext); if (lpDSEnumCallback(&DSOUND_capture_guids[wid], desc.szDesc, desc.szDrvname, lpContext) == FALSE) return DS_OK; } } return DS_OK;}/*************************************************************************** * DirectSoundCaptureEnumerateW [DSOUND.8] * * Enumerate all DirectSound drivers installed in the system. * * PARAMS * lpDSEnumCallback [I] Address of callback function. * lpContext [I] Address of user defined context passed to callback function. * * RETURNS * Success: DS_OK * Failure: DSERR_INVALIDPARAM */HRESULT WINAPIDirectSoundCaptureEnumerateW( LPDSENUMCALLBACKW lpDSEnumCallback, LPVOID lpContext){ unsigned devs, wid; DSDRIVERDESC desc; GUID guid; int err; WCHAR wDesc[MAXPNAMELEN]; WCHAR wName[MAXPNAMELEN]; TRACE("(%p,%p)\n", lpDSEnumCallback, lpContext ); if (lpDSEnumCallback == NULL) { WARN("invalid parameter: lpDSEnumCallback == NULL\n"); return DSERR_INVALIDPARAM; } devs = waveInGetNumDevs(); if (devs > 0) { if (GetDeviceID(&DSDEVID_DefaultCapture, &guid) == DS_OK) { for (wid = 0; wid < devs; ++wid) { if (IsEqualGUID( &guid, &DSOUND_capture_guids[wid] ) ) { err = mmErr(WineWaveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0)); if (err == DS_OK) { TRACE("calling lpDSEnumCallback(NULL,\"%s\",\"%s\",%p)\n", "Primary Sound Capture Driver",desc.szDrvname,lpContext); MultiByteToWideChar( CP_ACP, 0, "Primary Sound Capture Driver", -1, wDesc, sizeof(wDesc)/sizeof(WCHAR) ); MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wName, sizeof(wName)/sizeof(WCHAR) ); if (lpDSEnumCallback(NULL, wDesc, wName, lpContext) == FALSE) return DS_OK; } } } } } for (wid = 0; wid < devs; ++wid) { err = mmErr(WineWaveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0)); if (err == DS_OK) { TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n", debugstr_guid(&DSOUND_capture_guids[wid]),desc.szDesc,desc.szDrvname,lpContext); MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDesc, sizeof(wDesc)/sizeof(WCHAR) ); MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wName, sizeof(wName)/sizeof(WCHAR) ); if (lpDSEnumCallback((LPGUID)&DSOUND_capture_guids[wid], wDesc, wName, lpContext) == FALSE) return DS_OK; } } return DS_OK;}static void CALLBACKDSOUND_capture_callback( HWAVEIN hwi, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2 ){ DirectSoundCaptureDevice * This = (DirectSoundCaptureDevice*)dwUser; TRACE("(%p,%08x(%s),%08lx,%08lx,%08lx) entering at %ld\n",hwi,msg, msg == MM_WIM_OPEN ? "MM_WIM_OPEN" : msg == MM_WIM_CLOSE ? "MM_WIM_CLOSE" : msg == MM_WIM_DATA ? "MM_WIM_DATA" : "UNKNOWN",dwUser,dw1,dw2,GetTickCount()); if (msg == MM_WIM_DATA) { LPWAVEHDR pHdr = (LPWAVEHDR)dw1; EnterCriticalSection( &(This->lock) ); TRACE("DirectSoundCapture msg=MM_WIM_DATA, old This->state=%s, old This->index=%d\n", captureStateString[This->state],This->index); if (This->state != STATE_STOPPED) { int index = This->index; if (This->state == STATE_STARTING) { This->read_position = pHdr->dwBytesRecorded; This->state = STATE_CAPTURING; } if (This->capture_buffer->nrofnotifies) SetEvent(This->capture_buffer->notifies[This->index].hEventNotify); This->index = (This->index + 1) % This->nrofpwaves; if ( (This->index == 0) && !(This->capture_buffer->flags & DSCBSTART_LOOPING) ) { TRACE("end of buffer\n"); This->state = STATE_STOPPED; } else { if (This->state == STATE_CAPTURING) { waveInAddBuffer(hwi, &(This->pwave[index]), sizeof(WAVEHDR)); } else if (This->state == STATE_STOPPING) { TRACE("stopping\n"); This->state = STATE_STOPPED; } } } TRACE("DirectSoundCapture new This->state=%s, new This->index=%d\n", captureStateString[This->state],This->index); LeaveCriticalSection( &(This->lock) ); } TRACE("completed\n");
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?