capture.c
来自「Wine-20031016」· C语言 代码 · 共 431 行
C
431 行
/* * 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 <math.h>#include <stdlib.h>#include <stdio.h>#include "wine/test.h"#include "windef.h"#include "wingdi.h"#include "dsound.h"#include "mmreg.h"static const unsigned int formats[][3]={ { 8000, 8, 1}, { 8000, 8, 2}, { 8000, 16, 1}, { 8000, 16, 2}, {11025, 8, 1}, {11025, 8, 2}, {11025, 16, 1}, {11025, 16, 2}, {22050, 8, 1}, {22050, 8, 2}, {22050, 16, 1}, {22050, 16, 2}, {44100, 8, 1}, {44100, 8, 2}, {44100, 16, 1}, {44100, 16, 2}, {48000, 8, 1}, {48000, 8, 2}, {48000, 16, 1}, {48000, 16, 2}, {96000, 8, 1}, {96000, 8, 2}, {96000, 16, 1}, {96000, 16, 2}};#define NB_FORMATS (sizeof(formats)/sizeof(*formats))#define NOTIFICATIONS 5static void init_format(WAVEFORMATEX* wfx, int format, int rate, int depth, int channels){ wfx->wFormatTag=format; wfx->nChannels=channels; wfx->wBitsPerSample=depth; wfx->nSamplesPerSec=rate; wfx->nBlockAlign=wfx->nChannels*wfx->wBitsPerSample/8; if (wfx->nBlockAlign==0) /* align compressed formats to byte boundry */ wfx->nBlockAlign=1; wfx->nAvgBytesPerSec=wfx->nSamplesPerSec*wfx->nChannels*wfx->wBitsPerSample/8; wfx->cbSize=0;}static char * format_string(WAVEFORMATEX* wfx){ static char str[64]; sprintf(str, "%ldx%dx%d %s", wfx->nSamplesPerSec, wfx->wBitsPerSample, wfx->nChannels, wfx->wFormatTag == WAVE_FORMAT_PCM ? "PCM" : wfx->wFormatTag == WAVE_FORMAT_MULAW ? "MULAW" : wfx->wFormatTag == WAVE_FORMAT_IMA_ADPCM ? "IMA ADPCM" : "Unknown"); return str;}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,"GetCurrentPosition failed: 0x%lx\n",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,"Lock failed: 0x%lx\n",rc); if (rc!=DS_OK) return 0; rc=IDirectSoundCaptureBuffer_Unlock(state->dscbo,ptr1,len1,ptr2,len2); ok(rc==DS_OK,"Unlock failed: 0x%lx\n",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; /* Private dsound.dll: Error: Invalid caps pointer */ rc=IDirectSoundCaptureBuffer_GetCaps(dscbo,0); ok(rc==DSERR_INVALIDPARAM,"GetCaps should have failed: 0x%lx\n",rc); /* Private dsound.dll: Error: Invalid caps pointer */ dscbcaps.dwSize=0; rc=IDirectSoundCaptureBuffer_GetCaps(dscbo,&dscbcaps); ok(rc==DSERR_INVALIDPARAM,"GetCaps should have failed: 0x%lx\n",rc); dscbcaps.dwSize=sizeof(dscbcaps); rc=IDirectSoundCaptureBuffer_GetCaps(dscbo,&dscbcaps); ok(rc==DS_OK,"GetCaps failed: 0x%lx\n",rc); if (rc==DS_OK) { 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, "GetFormat should have returned an error: rc=0x%lx\n",rc); size=0; rc=IDirectSoundCaptureBuffer_GetFormat(dscbo,NULL,0,&size); ok(rc==DS_OK && size!=0, "GetFormat should have returned the needed size: rc=0x%lx size=%ld\n", rc,size); rc=IDirectSoundCaptureBuffer_GetFormat(dscbo,&wfx,sizeof(wfx),NULL); ok(rc==DS_OK,"GetFormat failed: 0x%lx\n",rc); if (rc==DS_OK) { trace(" tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n", wfx.wFormatTag,wfx.nSamplesPerSec,wfx.wBitsPerSample, wfx.nChannels,wfx.nAvgBytesPerSec,wfx.nBlockAlign); } /* Private dsound.dll: Error: Invalid status pointer */ rc=IDirectSoundCaptureBuffer_GetStatus(dscbo,0); ok(rc==DSERR_INVALIDPARAM,"GetStatus should have failed: 0x%lx\n",rc); rc=IDirectSoundCaptureBuffer_GetStatus(dscbo,&status); ok(rc==DS_OK,"GetStatus failed: 0x%lx\n",rc); if (rc==DS_OK) { trace(" status=0x%04lx\n",status); } ZeroMemory(&state, sizeof(state)); state.dscbo=dscbo; state.wfx=&wfx; state.buffer_size = dscbcaps.dwBufferBytes; for (i = 0; i < NOTIFICATIONS; i++) state.event[i] = CreateEvent( NULL, FALSE, FALSE, NULL ); state.size = dscbcaps.dwBufferBytes / NOTIFICATIONS; rc=IDirectSoundCaptureBuffer_QueryInterface(dscbo,&IID_IDirectSoundNotify,(void **)&(state.notify)); ok((rc==DS_OK)&&(state.notify!=NULL),"QueryInterface failed: 0x%lx\n",rc); if (rc!=DS_OK) return; for (i = 0; i < NOTIFICATIONS; i++) { state.posnotify[i].dwOffset = (i * state.size) + state.size - 1; state.posnotify[i].hEventNotify = state.event[i]; } rc=IDirectSoundNotify_SetNotificationPositions(state.notify,NOTIFICATIONS,state.posnotify); ok(rc==DS_OK,"SetNotificationPositions failed: 0x%lx\n",rc); if (rc!=DS_OK) return; rc=IDirectSoundNotify_Release(state.notify); ok(rc==0,"Release: 0x%lx\n",rc); if (rc!=0) return; if (record) { rc=IDirectSoundCaptureBuffer_Start(dscbo,DSCBSTART_LOOPING); ok(rc==DS_OK,"Start: 0x%lx\n",rc); if (rc!=DS_OK) return; rc=IDirectSoundCaptureBuffer_GetStatus(dscbo,&status); ok(rc==DS_OK,"GetStatus failed: 0x%lx\n",rc); ok(status==(DSCBSTATUS_CAPTURING|DSCBSTATUS_LOOPING), "GetStatus: bad status: %lx",status); if (rc!=DS_OK) return; /* wait for the notifications */ for (i = 0; i < (NOTIFICATIONS * 2); i++) { rc=MsgWaitForMultipleObjects( NOTIFICATIONS, state.event, FALSE, 3000, QS_ALLEVENTS ); ok(rc==(WAIT_OBJECT_0+(i%NOTIFICATIONS)),"MsgWaitForMultipleObjects failed: 0x%lx\n",rc); if (rc!=(WAIT_OBJECT_0+(i%NOTIFICATIONS))) { ok((rc==WAIT_TIMEOUT)||(rc==WAIT_FAILED),"Wrong notification: should be %d, got %ld\n", i%NOTIFICATIONS,rc-WAIT_OBJECT_0); } else break; if (!capture_buffer_service(&state)) break; } rc=IDirectSoundCaptureBuffer_Stop(dscbo); ok(rc==DS_OK,"Stop: 0x%lx\n",rc); if (rc!=DS_OK) return; }}static BOOL WINAPI dscenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription, LPCSTR lpcstrModule, LPVOID lpContext){ HRESULT rc; LPDIRECTSOUNDCAPTURE dsco=NULL; LPDIRECTSOUNDCAPTUREBUFFER dscbo=NULL; DSCBUFFERDESC bufdesc; WAVEFORMATEX wfx; DSCCAPS dsccaps; int f, ref; /* Private dsound.dll: Error: Invalid interface buffer */ trace("Testing %s - %s\n",lpcstrDescription,lpcstrModule); rc=DirectSoundCaptureCreate(lpGuid,NULL,NULL); ok(rc==DSERR_INVALIDPARAM,"DirectSoundCaptureCreate didn't fail: 0x%lx\n",rc); if (rc==DS_OK) { ref=IDirectSoundCapture_Release(dsco); ok(ref==0,"IDirectSoundCapture_Release has %d references, should have 0\n",ref); } rc=DirectSoundCaptureCreate(lpGuid,&dsco,NULL); ok((rc==DS_OK)||(rc==DSERR_NODRIVER),"DirectSoundCaptureCreate failed: 0x%lx\n",rc); if (rc!=DS_OK) goto EXIT; /* Private dsound.dll: Error: Invalid caps buffer */ rc=IDirectSoundCapture_GetCaps(dsco,NULL); ok(rc==DSERR_INVALIDPARAM,"GetCaps should have failed: 0x%lx\n",rc); /* Private dsound.dll: Error: Invalid caps buffer */ dsccaps.dwSize=0; rc=IDirectSoundCapture_GetCaps(dsco,&dsccaps); ok(rc==DSERR_INVALIDPARAM,"GetCaps should have failed: 0x%lx\n",rc); dsccaps.dwSize=sizeof(dsccaps); rc=IDirectSoundCapture_GetCaps(dsco,&dsccaps); ok(rc==DS_OK,"GetCaps failed: 0x%lx\n",rc); if (rc==DS_OK) { trace(" DirectSoundCapture Caps: size=%ld flags=0x%08lx formats=%05lx channels=%ld\n", dsccaps.dwSize,dsccaps.dwFlags,dsccaps.dwFormats,dsccaps.dwChannels); } /* Private dsound.dll: Error: Invalid size */ /* Private dsound.dll: Error: Invalid capture buffer description */ ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=0; bufdesc.dwFlags=0; bufdesc.dwBufferBytes=0; bufdesc.dwReserved=0; bufdesc.lpwfxFormat=NULL; rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL); ok(rc==DSERR_INVALIDPARAM,"CreateCaptureBuffer should have failed to create a capture buffer 0x%lx\n",rc); if (rc==DS_OK) { ref=IDirectSoundCaptureBuffer_Release(dscbo); ok(ref==0,"IDirectSoundCaptureBuffer_Release has %d references, should have 0\n",ref); } /* Private dsound.dll: Error: Invalid buffer size */ /* Private dsound.dll: Error: Invalid capture buffer description */ ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=sizeof(bufdesc); bufdesc.dwFlags=0; bufdesc.dwBufferBytes=0; bufdesc.dwReserved=0; bufdesc.lpwfxFormat=NULL; rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL); ok(rc==DSERR_INVALIDPARAM,"CreateCaptureBuffer should have failed to create a capture buffer 0x%lx\n",rc); if (rc==DS_OK) { ref=IDirectSoundCaptureBuffer_Release(dscbo); ok(ref==0,"IDirectSoundCaptureBuffer_Release has %d references, should have 0\n",ref); } /* Private dsound.dll: Error: Invalid buffer size */ /* Private dsound.dll: Error: Invalid capture buffer description */ ZeroMemory(&bufdesc, sizeof(bufdesc)); ZeroMemory(&wfx, sizeof(wfx)); bufdesc.dwSize=sizeof(bufdesc); bufdesc.dwFlags=0; bufdesc.dwBufferBytes=0; bufdesc.dwReserved=0; bufdesc.lpwfxFormat=&wfx; rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL); ok(rc==DSERR_INVALIDPARAM,"CreateCaptureBuffer should have failed to create a capture buffer 0x%lx\n",rc); if (rc==DS_OK) { ref=IDirectSoundCaptureBuffer_Release(dscbo); ok(ref==0,"IDirectSoundCaptureBuffer_Release has %d references, should have 0\n",ref); } /* Private dsound.dll: Error: Invalid buffer size */ /* Private dsound.dll: Error: Invalid capture buffer description */ init_format(&wfx,WAVE_FORMAT_PCM,11025,8,1); ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=sizeof(bufdesc); bufdesc.dwFlags=0; bufdesc.dwBufferBytes=0; bufdesc.dwReserved=0; bufdesc.lpwfxFormat=&wfx; rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL); ok(rc==DSERR_INVALIDPARAM,"CreateCaptureBuffer should have failed to create a capture buffer 0x%lx\n",rc); if (rc==DS_OK) { ref=IDirectSoundCaptureBuffer_Release(dscbo); ok(ref==0,"IDirectSoundCaptureBuffer_Release has %d references, should have 0\n",ref); } for (f=0;f<NB_FORMATS;f++) { dscbo=NULL; init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],formats[f][2]); ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=sizeof(bufdesc); bufdesc.dwFlags=0; bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec; bufdesc.dwReserved=0; bufdesc.lpwfxFormat=&wfx; trace(" Testing the capture buffer at %s\n", format_string(&wfx)); rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL); ok((rc==DS_OK)&&(dscbo!=NULL),"CreateCaptureBuffer failed to create a capture buffer 0x%lx\n",rc); if (rc==DS_OK) { test_capture_buffer(dsco, dscbo, winetest_interactive); ref=IDirectSoundCaptureBuffer_Release(dscbo); ok(ref==0,"IDirectSoundCaptureBuffer_Release has %d references, should have 0\n",ref); } } /* try a non PCM format */#if 0 init_format(&wfx,WAVE_FORMAT_MULAW,8000,8,1); ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=sizeof(bufdesc); bufdesc.dwFlags=DSCBCAPS_WAVEMAPPED; bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec; bufdesc.dwReserved=0; bufdesc.lpwfxFormat=&wfx; trace(" Testing the capture buffer at %s\n", format_string(&wfx)); rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL); ok((rc==DS_OK)&&(dscbo!=NULL),"CreateCaptureBuffer failed to create a capture buffer 0x%lx\n",rc); if ((rc==DS_OK)&&(dscbo!=NULL)) { test_capture_buffer(dsco, dscbo, winetest_interactive); ref=IDirectSoundCaptureBuffer_Release(dscbo); ok(ref==0,"IDirectSoundCaptureBuffer_Release has %d references, should have 0\n",ref); }#endif /* Try an invalid format to test error handling */#if 0 init_format(&wfx,WAVE_FORMAT_PCM,2000000,16,2); ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=sizeof(bufdesc); bufdesc.dwFlags=DSCBCAPS_WAVEMAPPED; bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec; bufdesc.dwReserved=0; bufdesc.lpwfxFormat=&wfx; trace(" Testing the capture buffer at %s\n", format_string(&wfx)); rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL); ok(rc!=DS_OK,"CreateCaptureBuffer should have failed at 2 MHz 0x%lx\n",rc);#endifEXIT: if (dsco!=NULL) { ref=IDirectSoundCapture_Release(dsco); ok(ref==0,"IDirectSoundCapture_Release has %d references, should have 0\n",ref); } return TRUE;}static void capture_tests(){ HRESULT rc; rc=DirectSoundCaptureEnumerateA(&dscenum_callback,NULL); ok(rc==DS_OK,"DirectSoundCaptureEnumerate failed: %ld\n",rc);}START_TEST(capture){ capture_tests();}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?