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