📄 capture.c
字号:
/*
* Unit tests for capture functions
*
* Copyright (c) 2002 Francois Gouget
* Copyright (c) 2003 Robert Reif
*
* 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
*/
#define NONAMELESSSTRUCT
#define NONAMELESSUNION
#include <windows.h>
#include <stdio.h>
#include "wine/test.h"
#include "dsound.h"
#include "mmreg.h"
#include "dxerr8.h"
#include "dsconf.h"
#include "dsound_test.h"
#define NOTIFICATIONS 5
static HRESULT (WINAPI *pDirectSoundCaptureCreate)(LPCGUID,LPDIRECTSOUNDCAPTURE*,LPUNKNOWN)=NULL;
static HRESULT (WINAPI *pDirectSoundCaptureEnumerateA)(LPDSENUMCALLBACKA,LPVOID)=NULL;
static const char * get_format_str(WORD format)
{
static char msg[32];
#define WAVE_FORMAT(f) case f: return #f
switch (format) {
WAVE_FORMAT(WAVE_FORMAT_PCM);
WAVE_FORMAT(WAVE_FORMAT_ADPCM);
WAVE_FORMAT(WAVE_FORMAT_IBM_CVSD);
WAVE_FORMAT(WAVE_FORMAT_ALAW);
WAVE_FORMAT(WAVE_FORMAT_MULAW);
WAVE_FORMAT(WAVE_FORMAT_OKI_ADPCM);
WAVE_FORMAT(WAVE_FORMAT_IMA_ADPCM);
WAVE_FORMAT(WAVE_FORMAT_MEDIASPACE_ADPCM);
WAVE_FORMAT(WAVE_FORMAT_SIERRA_ADPCM);
WAVE_FORMAT(WAVE_FORMAT_G723_ADPCM);
WAVE_FORMAT(WAVE_FORMAT_DIGISTD);
WAVE_FORMAT(WAVE_FORMAT_DIGIFIX);
WAVE_FORMAT(WAVE_FORMAT_DIALOGIC_OKI_ADPCM);
WAVE_FORMAT(WAVE_FORMAT_YAMAHA_ADPCM);
WAVE_FORMAT(WAVE_FORMAT_SONARC);
WAVE_FORMAT(WAVE_FORMAT_DSPGROUP_TRUESPEECH);
WAVE_FORMAT(WAVE_FORMAT_ECHOSC1);
WAVE_FORMAT(WAVE_FORMAT_AUDIOFILE_AF36);
WAVE_FORMAT(WAVE_FORMAT_APTX);
WAVE_FORMAT(WAVE_FORMAT_AUDIOFILE_AF10);
WAVE_FORMAT(WAVE_FORMAT_DOLBY_AC2);
WAVE_FORMAT(WAVE_FORMAT_GSM610);
WAVE_FORMAT(WAVE_FORMAT_ANTEX_ADPCME);
WAVE_FORMAT(WAVE_FORMAT_CONTROL_RES_VQLPC);
WAVE_FORMAT(WAVE_FORMAT_DIGIREAL);
WAVE_FORMAT(WAVE_FORMAT_DIGIADPCM);
WAVE_FORMAT(WAVE_FORMAT_CONTROL_RES_CR10);
WAVE_FORMAT(WAVE_FORMAT_NMS_VBXADPCM);
WAVE_FORMAT(WAVE_FORMAT_G721_ADPCM);
WAVE_FORMAT(WAVE_FORMAT_MPEG);
WAVE_FORMAT(WAVE_FORMAT_MPEGLAYER3);
WAVE_FORMAT(WAVE_FORMAT_CREATIVE_ADPCM);
WAVE_FORMAT(WAVE_FORMAT_CREATIVE_FASTSPEECH8);
WAVE_FORMAT(WAVE_FORMAT_CREATIVE_FASTSPEECH10);
WAVE_FORMAT(WAVE_FORMAT_FM_TOWNS_SND);
WAVE_FORMAT(WAVE_FORMAT_OLIGSM);
WAVE_FORMAT(WAVE_FORMAT_OLIADPCM);
WAVE_FORMAT(WAVE_FORMAT_OLICELP);
WAVE_FORMAT(WAVE_FORMAT_OLISBC);
WAVE_FORMAT(WAVE_FORMAT_OLIOPR);
WAVE_FORMAT(WAVE_FORMAT_DEVELOPMENT);
WAVE_FORMAT(WAVE_FORMAT_EXTENSIBLE);
}
#undef WAVE_FORMAT
sprintf(msg, "Unknown(0x%04x)", format);
return msg;
}
static char * format_string(WAVEFORMATEX* wfx)
{
static char str[64];
sprintf(str, "%5ldx%2dx%d %s",
wfx->nSamplesPerSec, wfx->wBitsPerSample, wfx->nChannels,
get_format_str(wfx->wFormatTag));
return str;
}
static void IDirectSoundCapture_test(LPDIRECTSOUNDCAPTURE dsco,
BOOL initialized, LPCGUID lpGuid)
{
HRESULT rc;
DSCCAPS dsccaps;
int ref;
IUnknown * unknown;
IDirectSoundCapture * dsc;
/* Try to Query for objects */
rc=IDirectSoundCapture_QueryInterface(dsco, &IID_IUnknown,
(LPVOID*)&unknown);
ok(rc==DS_OK, "IDirectSoundCapture_QueryInterface(IID_IUnknown) "
"failed: %s\n", DXGetErrorString8(rc));
if (rc==DS_OK)
IDirectSoundCapture_Release(unknown);
rc=IDirectSoundCapture_QueryInterface(dsco, &IID_IDirectSoundCapture,
(LPVOID*)&dsc);
ok(rc==DS_OK, "IDirectSoundCapture_QueryInterface(IID_IDirectSoundCapture) "
"failed: %s\n", DXGetErrorString8(rc));
if (rc==DS_OK)
IDirectSoundCapture_Release(dsc);
if (initialized == FALSE) {
/* try unitialized object */
rc=IDirectSoundCapture_GetCaps(dsco,0);
ok(rc==DSERR_UNINITIALIZED, "IDirectSoundCapture_GetCaps(NULL) "
"should have returned DSERR_UNINITIALIZED, returned: %s\n",
DXGetErrorString8(rc));
rc=IDirectSoundCapture_GetCaps(dsco, &dsccaps);
ok(rc==DSERR_UNINITIALIZED,"IDirectSoundCapture_GetCaps() "
"should have returned DSERR_UNINITIALIZED, returned: %s\n",
DXGetErrorString8(rc));
rc=IDirectSoundCapture_Initialize(dsco, lpGuid);
ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
"IDirectSoundCapture_Initialize() failed: %s\n",
DXGetErrorString8(rc));
if (rc==DSERR_NODRIVER) {
trace(" No Driver\n");
goto EXIT;
} else if (rc==E_FAIL) {
trace(" No Device\n");
goto EXIT;
} else if (rc==DSERR_ALLOCATED) {
trace(" Already In Use\n");
goto EXIT;
}
}
rc=IDirectSoundCapture_Initialize(dsco, lpGuid);
ok(rc==DSERR_ALREADYINITIALIZED, "IDirectSoundCapture_Initialize() "
"should have returned DSERR_ALREADYINITIALIZED: %s\n",
DXGetErrorString8(rc));
/* DSOUND: Error: Invalid caps buffer */
rc=IDirectSoundCapture_GetCaps(dsco, 0);
ok(rc==DSERR_INVALIDPARAM, "IDirectSoundCapture_GetCaps(NULL) "
"should have returned DSERR_INVALIDPARAM, returned: %s\n",
DXGetErrorString8(rc));
ZeroMemory(&dsccaps, sizeof(dsccaps));
/* DSOUND: Error: Invalid caps buffer */
rc=IDirectSound_GetCaps(dsco, &dsccaps);
ok(rc==DSERR_INVALIDPARAM, "IDirectSound_GetCaps() "
"should have returned DSERR_INVALIDPARAM, returned: %s\n",
DXGetErrorString8(rc));
dsccaps.dwSize=sizeof(dsccaps);
/* DSOUND: Running on a certified driver */
rc=IDirectSoundCapture_GetCaps(dsco, &dsccaps);
ok(rc==DS_OK, "IDirectSoundCapture_GetCaps() failed: %s\n",
DXGetErrorString8(rc));
EXIT:
ref=IDirectSoundCapture_Release(dsco);
ok(ref==0, "IDirectSoundCapture_Release() has %d references, "
"should have 0\n", ref);
}
static void IDirectSoundCapture_tests(void)
{
HRESULT rc;
LPDIRECTSOUNDCAPTURE dsco=NULL;
trace("Testing IDirectSoundCapture\n");
/* try the COM class factory method of creation with no device specified */
rc=CoCreateInstance(&CLSID_DirectSoundCapture, NULL, CLSCTX_INPROC_SERVER,
&IID_IDirectSoundCapture, (void**)&dsco);
ok(rc==S_OK||rc==REGDB_E_CLASSNOTREG,"CoCreateInstance(CLSID_DirectSoundCapture) failed: %s\n",
DXGetErrorString8(rc));
if (rc==REGDB_E_CLASSNOTREG) {
trace(" Class Not Registered\n");
return;
}
if (dsco)
IDirectSoundCapture_test(dsco, FALSE, NULL);
/* try the COM class factory method of creation with default capture
* device specified */
rc=CoCreateInstance(&CLSID_DirectSoundCapture, NULL, CLSCTX_INPROC_SERVER,
&IID_IDirectSoundCapture, (void**)&dsco);
ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSoundCapture) failed: %s\n",
DXGetErrorString8(rc));
if (dsco)
IDirectSoundCapture_test(dsco, FALSE, &DSDEVID_DefaultCapture);
/* try the COM class factory method of creation with default voice
* capture device specified */
rc=CoCreateInstance(&CLSID_DirectSoundCapture, NULL, CLSCTX_INPROC_SERVER,
&IID_IDirectSoundCapture, (void**)&dsco);
ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSoundCapture) failed: %s\n",
DXGetErrorString8(rc));
if (dsco)
IDirectSoundCapture_test(dsco, FALSE, &DSDEVID_DefaultVoiceCapture);
/* try the COM class factory method of creation with a bad
* IID specified */
rc=CoCreateInstance(&CLSID_DirectSoundCapture, NULL, CLSCTX_INPROC_SERVER,
&CLSID_DirectSoundPrivate, (void**)&dsco);
ok(rc==E_NOINTERFACE,
"CoCreateInstance(CLSID_DirectSoundCapture,CLSID_DirectSoundPrivate) "
"should have failed: %s\n",DXGetErrorString8(rc));
/* try with no device specified */
rc=pDirectSoundCaptureCreate(NULL,&dsco,NULL);
ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
"DirectSoundCaptureCreate(NULL) failed: %s\n",DXGetErrorString8(rc));
if (rc==S_OK && dsco)
IDirectSoundCapture_test(dsco, TRUE, NULL);
/* try with default capture device specified */
rc=pDirectSoundCaptureCreate(&DSDEVID_DefaultCapture,&dsco,NULL);
ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
"DirectSoundCaptureCreate(DSDEVID_DefaultCapture) failed: %s\n",
DXGetErrorString8(rc));
if (rc==DS_OK && dsco)
IDirectSoundCapture_test(dsco, TRUE, NULL);
/* try with default voice capture device specified */
rc=pDirectSoundCaptureCreate(&DSDEVID_DefaultVoiceCapture,&dsco,NULL);
ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
"DirectSoundCaptureCreate(DSDEVID_DefaultVoiceCapture) failed: %s\n",
DXGetErrorString8(rc));
if (rc==DS_OK && dsco)
IDirectSoundCapture_test(dsco, TRUE, NULL);
/* try with a bad device specified */
rc=pDirectSoundCaptureCreate(&DSDEVID_DefaultVoicePlayback,&dsco,NULL);
ok(rc==DSERR_NODRIVER,
"DirectSoundCaptureCreate(DSDEVID_DefaultVoicePlatback) "
"should have failed: %s\n",DXGetErrorString8(rc));
if (rc==DS_OK && dsco)
IDirectSoundCapture_Release(dsco);
}
typedef struct {
char* wave;
DWORD wave_len;
LPDIRECTSOUNDCAPTUREBUFFER dscbo;
LPWAVEFORMATEX wfx;
DSBPOSITIONNOTIFY posnotify[NOTIFICATIONS];
HANDLE event[NOTIFICATIONS];
LPDIRECTSOUNDNOTIFY notify;
DWORD buffer_size;
DWORD read;
DWORD offset;
DWORD size;
DWORD last_pos;
} capture_state_t;
static int capture_buffer_service(capture_state_t* state)
{
HRESULT rc;
LPVOID ptr1,ptr2;
DWORD len1,len2;
DWORD capture_pos,read_pos;
rc=IDirectSoundCaptureBuffer_GetCurrentPosition(state->dscbo,&capture_pos,
&read_pos);
ok(rc==DS_OK,"IDirectSoundCaptureBuffer_GetCurrentPosition() failed: %s\n",
DXGetErrorString8(rc));
if (rc!=DS_OK)
return 0;
rc=IDirectSoundCaptureBuffer_Lock(state->dscbo,state->offset,state->size,
&ptr1,&len1,&ptr2,&len2,0);
ok(rc==DS_OK,"IDirectSoundCaptureBuffer_Lock() failed: %s\n",
DXGetErrorString8(rc));
if (rc!=DS_OK)
return 0;
rc=IDirectSoundCaptureBuffer_Unlock(state->dscbo,ptr1,len1,ptr2,len2);
ok(rc==DS_OK,"IDirectSoundCaptureBuffer_Unlock() failed: %s\n",
DXGetErrorString8(rc));
if (rc!=DS_OK)
return 0;
state->offset = (state->offset + state->size) % state->buffer_size;
return 1;
}
static void test_capture_buffer(LPDIRECTSOUNDCAPTURE dsco,
LPDIRECTSOUNDCAPTUREBUFFER dscbo, int record)
{
HRESULT rc;
DSCBCAPS dscbcaps;
WAVEFORMATEX wfx;
DWORD size,status;
capture_state_t state;
int i, ref;
/* Private dsound.dll: Error: Invalid caps pointer */
rc=IDirectSoundCaptureBuffer_GetCaps(dscbo,0);
ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCaptureBuffer_GetCaps() should "
"have returned DSERR_INVALIDPARAM, returned: %s\n",
DXGetErrorString8(rc));
/* Private dsound.dll: Error: Invalid caps pointer */
dscbcaps.dwSize=0;
rc=IDirectSoundCaptureBuffer_GetCaps(dscbo,&dscbcaps);
ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCaptureBuffer_GetCaps() should "
"have returned DSERR_INVALIDPARAM, returned: %s\n",
DXGetErrorString8(rc));
dscbcaps.dwSize=sizeof(dscbcaps);
rc=IDirectSoundCaptureBuffer_GetCaps(dscbo,&dscbcaps);
ok(rc==DS_OK,"IDirectSoundCaptureBuffer_GetCaps() failed: %s\n",
DXGetErrorString8(rc));
if (rc==DS_OK && winetest_debug > 1) {
trace(" Caps: size = %ld flags=0x%08lx buffer size=%ld\n",
dscbcaps.dwSize,dscbcaps.dwFlags,dscbcaps.dwBufferBytes);
}
/* Query the format size. Note that it may not match sizeof(wfx) */
/* Private dsound.dll: Error: Either pwfxFormat or pdwSizeWritten must
* be non-NULL */
rc=IDirectSoundCaptureBuffer_GetFormat(dscbo,NULL,0,NULL);
ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCaptureBuffer_GetFormat() should "
"have returned DSERR_INVALIDPARAM, returned: %s\n",
DXGetErrorString8(rc));
size=0;
rc=IDirectSoundCaptureBuffer_GetFormat(dscbo,NULL,0,&size);
ok(rc==DS_OK && size!=0,"IDirectSoundCaptureBuffer_GetFormat() should "
"have returned the needed size: rc=%s, size=%ld\n",
DXGetErrorString8(rc),size);
rc=IDirectSoundCaptureBuffer_GetFormat(dscbo,&wfx,sizeof(wfx),NULL);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -