📄 ds3d8.c
字号:
/* * Tests the panning and 3D functions of DirectSound * * Part of this test involves playing test tones. But this only makes * sense if someone is going to carefully listen to it, and would only * bother everyone else. * So this is only done if the test is being run in interactive mode. * * Copyright (c) 2002-2004 Francois Gouget * * 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 "wine/test.h"#include "dsound.h"#include "dxerr8.h"#include "dsound_test.h"static HRESULT (WINAPI *pDirectSoundCreate8)(LPCGUID,LPDIRECTSOUND8*,LPUNKNOWN)=NULL;typedef struct { char* wave; DWORD wave_len; LPDIRECTSOUNDBUFFER dsbo; LPWAVEFORMATEX wfx; DWORD buffer_size; DWORD written; DWORD played; DWORD offset;} play_state_t;static int buffer_refill8(play_state_t* state, DWORD size){ LPVOID ptr1,ptr2; DWORD len1,len2; HRESULT rc; if (size>state->wave_len-state->written) size=state->wave_len-state->written; rc=IDirectSoundBuffer_Lock(state->dsbo,state->offset,size, &ptr1,&len1,&ptr2,&len2,0); ok(rc==DS_OK,"IDirectSoundBuffer_Lock() failed: %s\n", DXGetErrorString8(rc)); if (rc!=DS_OK) return -1; memcpy(ptr1,state->wave+state->written,len1); state->written+=len1; if (ptr2!=NULL) { memcpy(ptr2,state->wave+state->written,len2); state->written+=len2; } state->offset=state->written % state->buffer_size; rc=IDirectSoundBuffer_Unlock(state->dsbo,ptr1,len1,ptr2,len2); ok(rc==DS_OK,"IDirectSoundBuffer_Unlock() failed: %s\n", DXGetErrorString8(rc)); if (rc!=DS_OK) return -1; return size;}static int buffer_silence8(play_state_t* state, DWORD size){ LPVOID ptr1,ptr2; DWORD len1,len2; HRESULT rc; BYTE s; rc=IDirectSoundBuffer_Lock(state->dsbo,state->offset,size, &ptr1,&len1,&ptr2,&len2,0); ok(rc==DS_OK,"IDirectSoundBuffer_Lock() failed: %s\n", DXGetErrorString8(rc)); if (rc!=DS_OK) return -1; s=(state->wfx->wBitsPerSample==8?0x80:0); memset(ptr1,s,len1); if (ptr2!=NULL) { memset(ptr2,s,len2); } state->offset=(state->offset+size) % state->buffer_size; rc=IDirectSoundBuffer_Unlock(state->dsbo,ptr1,len1,ptr2,len2); ok(rc==DS_OK,"IDirectSoundBuffer_Unlock() failed: %s\n", DXGetErrorString8(rc)); if (rc!=DS_OK) return -1; return size;}static int buffer_service8(play_state_t* state){ DWORD last_play_pos,play_pos,buf_free; HRESULT rc; rc=IDirectSoundBuffer_GetCurrentPosition(state->dsbo,&play_pos,NULL); ok(rc==DS_OK,"IDirectSoundBuffer_GetCurrentPosition() failed: %s\n", DXGetErrorString8(rc)); if (rc!=DS_OK) { goto STOP; } /* Update the amount played */ last_play_pos=state->played % state->buffer_size; if (play_pos<last_play_pos) state->played+=state->buffer_size-last_play_pos+play_pos; else state->played+=play_pos-last_play_pos; if (winetest_debug > 1) trace("buf size=%ld last_play_pos=%ld play_pos=%ld played=%ld / %ld\n", state->buffer_size,last_play_pos,play_pos,state->played, state->wave_len); if (state->played>state->wave_len) { /* Everything has been played */ goto STOP; } /* Refill the buffer */ if (state->offset<=play_pos) buf_free=play_pos-state->offset; else buf_free=state->buffer_size-state->offset+play_pos; if (winetest_debug > 1) trace("offset=%ld free=%ld written=%ld / %ld\n", state->offset,buf_free,state->written,state->wave_len); if (buf_free==0) return 1; if (state->written<state->wave_len) { int w=buffer_refill8(state,buf_free); if (w==-1) goto STOP; buf_free-=w; if (state->written==state->wave_len && winetest_debug > 1) trace("last sound byte at %ld\n", (state->written % state->buffer_size)); } if (buf_free>0) { /* Fill with silence */ if (winetest_debug > 1) trace("writing %ld bytes of silence\n",buf_free); if (buffer_silence8(state,buf_free)==-1) goto STOP; } return 1;STOP: if (winetest_debug > 1) trace("stopping playback\n"); rc=IDirectSoundBuffer_Stop(state->dsbo); ok(rc==DS_OK,"IDirectSoundBuffer_Stop() failed: %s\n", DXGetErrorString8(rc)); return 0;}void test_buffer8(LPDIRECTSOUND8 dso, LPDIRECTSOUNDBUFFER dsbo, BOOL is_primary, BOOL set_volume, LONG volume, BOOL set_pan, LONG pan, BOOL play, double duration, BOOL buffer3d, LPDIRECTSOUND3DLISTENER listener, BOOL move_listener, BOOL move_sound){ HRESULT rc; DSBCAPS dsbcaps; WAVEFORMATEX wfx,wfx2; DWORD size,status,freq; int ref; /* DSOUND: Error: Invalid caps pointer */ rc=IDirectSoundBuffer_GetCaps(dsbo,0); ok(rc==DSERR_INVALIDPARAM,"IDirectSoundBuffer_GetCaps() should have " "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc)); ZeroMemory(&dsbcaps, sizeof(dsbcaps)); /* DSOUND: Error: Invalid caps pointer */ rc=IDirectSoundBuffer_GetCaps(dsbo,&dsbcaps); ok(rc==DSERR_INVALIDPARAM,"IDirectSoundBuffer_GetCaps() should have " "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc)); dsbcaps.dwSize=sizeof(dsbcaps); rc=IDirectSoundBuffer_GetCaps(dsbo,&dsbcaps); ok(rc==DS_OK,"IDirectSoundBuffer_GetCaps() failed: %s\n", DXGetErrorString8(rc)); if (rc==DS_OK && winetest_debug > 1) { trace(" Caps: flags=0x%08lx size=%ld\n",dsbcaps.dwFlags, dsbcaps.dwBufferBytes); } /* Query the format size. Note that it may not match sizeof(wfx) */ size=0; rc=IDirectSoundBuffer_GetFormat(dsbo,NULL,0,&size); ok(rc==DS_OK && size!=0,"IDirectSoundBuffer_GetFormat() should have " "returned the needed size: rc=%s size=%ld\n",DXGetErrorString8(rc),size); rc=IDirectSoundBuffer_GetFormat(dsbo,&wfx,sizeof(wfx),NULL); ok(rc==DS_OK,"IDirectSoundBuffer_GetFormat() failed: %s\n", DXGetErrorString8(rc)); if (rc==DS_OK && winetest_debug > 1) { trace(" Format: %s tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n", is_primary ? "Primary" : "Secondary", wfx.wFormatTag,wfx.nSamplesPerSec,wfx.wBitsPerSample, wfx.nChannels,wfx.nAvgBytesPerSec,wfx.nBlockAlign); } /* DSOUND: Error: Invalid frequency buffer */ rc=IDirectSoundBuffer_GetFrequency(dsbo,0); ok(rc==DSERR_INVALIDPARAM,"IDirectSoundBuffer_GetFrequency() should have " "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc)); /* DSOUND: Error: Primary buffers don't support CTRLFREQUENCY */ rc=IDirectSoundBuffer_GetFrequency(dsbo,&freq); ok((rc==DS_OK && !is_primary) || (rc==DSERR_CONTROLUNAVAIL&&is_primary) || (rc==DSERR_CONTROLUNAVAIL&&!(dsbcaps.dwFlags&DSBCAPS_CTRLFREQUENCY)), "IDirectSoundBuffer_GetFrequency() failed: %s\n",DXGetErrorString8(rc)); if (rc==DS_OK) { ok(freq==wfx.nSamplesPerSec,"The frequency returned by GetFrequency " "%ld does not match the format %ld\n",freq,wfx.nSamplesPerSec); } /* DSOUND: Error: Invalid status pointer */ rc=IDirectSoundBuffer_GetStatus(dsbo,0); ok(rc==DSERR_INVALIDPARAM,"IDirectSoundBuffer_GetStatus() should have " "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc)); rc=IDirectSoundBuffer_GetStatus(dsbo,&status); ok(rc==DS_OK,"IDirectSoundBuffer_GetStatus() failed: %s\n", DXGetErrorString8(rc)); ok(status==0,"status=0x%lx instead of 0\n",status); if (is_primary) { /* We must call SetCooperativeLevel to be allowed to call SetFormat */ /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */ rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY); ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel(DSSCL_PRIORITY) " "failed: %s\n",DXGetErrorString8(rc)); if (rc!=DS_OK) return; /* DSOUND: Error: Invalid format pointer */ rc=IDirectSoundBuffer_SetFormat(dsbo,0); ok(rc==DSERR_INVALIDPARAM,"IDirectSoundBuffer_SetFormat() should have " "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc)); init_format(&wfx2,WAVE_FORMAT_PCM,11025,16,2); rc=IDirectSoundBuffer_SetFormat(dsbo,&wfx2); ok(rc==DS_OK,"IDirectSoundBuffer_SetFormat() failed: %s\n", DXGetErrorString8(rc)); /* There is no garantee that SetFormat will actually change the * format to what we asked for. It depends on what the soundcard * supports. So we must re-query the format. */ rc=IDirectSoundBuffer_GetFormat(dsbo,&wfx,sizeof(wfx),NULL); ok(rc==DS_OK,"IDirectSoundBuffer_GetFormat() failed: %s\n", DXGetErrorString8(rc)); if (rc==DS_OK && (wfx.wFormatTag!=wfx2.wFormatTag || wfx.nSamplesPerSec!=wfx2.nSamplesPerSec || wfx.wBitsPerSample!=wfx2.wBitsPerSample || wfx.nChannels!=wfx2.nChannels)) { trace("Requested format tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n", wfx2.wFormatTag,wfx2.nSamplesPerSec,wfx2.wBitsPerSample,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -