|
|
if (KEYDOWN(buffer, DIK_DOWN))
{
curVol=curVol-1000;
hr=DSBuffer->SetVolume(curVol);
if FAILED(hr)
{
if(hr==DSERR_INVALIDPARAM)
return FALSE;
}
}
这是Beginning DirecX9这本书中的一个例子 ,原例只是循环的播放一个声音
为了实现用方向键递减音量。我加了关于Input Keyboard的代码
各位前辈请看上面的代码 如果我把断点打在这句 "hr=DSBuffer->SetVolume(curVol);"
然后再执行。就没有问题。(curVol每次递减1000)
可是断点打在if(hr==DSERR_INVALIDPARAM) 或 return FALSE这两句;
curVol的值就成了"11000"
于是得到一个DSERR_INVALIDPARAM 然后程序退出。
直接运行也是这个结果(程序直接退出)。
如果注释掉return FALSE 声音就消失了。
麻烦各位大侠前辈救救小弟。。。被这问题困扰了一下午。。。
以下是全部源代码
#include <windows.h>
#define DIRECTINPUT_VERSION 0x0800
#include <dxerr9.h>
#include <dsound.h>
#include <dinput.h>
#include "dsutil.h"
#include <string>
using namespace std;
// Window functions and variables
HINSTANCE hInst; // holds the instance for this app
HWND wndHandle; // global window handle
LPDIRECTINPUT8 g_lpDI; // the direct input object
LPDIRECTINPUTDEVICE8 g_lpDIDevice; // the direct input device
char buffer[256];
#define KEYDOWN(name, key) (name[key] & 0x80)
bool initWindow(HINSTANCE hInstance);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
// DirectSound functions and variables
LPDIRECTSOUND8 g_pDS; // The DirectSound Device
bool initDirectSound(HWND hwnd);
void shutdownDirectSound(void);
LPDIRECTSOUNDBUFFER LoadWaveToSoundBuffer(std::string wavFilename);
void playSound(LPDIRECTSOUNDBUFFER whichBuffer);
void playSoundLoop(LPDIRECTSOUNDBUFFER whichBuffer);
void stopSound(LPDIRECTSOUNDBUFFER whichBuffer);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
HRESULT hr;
static long curVol=0;
// call our function to init and create our window
if (!initWindow(hInstance))
{
MessageBox(NULL, "Unable to create window", "ERROR", MB_OK);
return 0;
}
// initialize DirectSound
if (!initDirectSound(wndHandle))
{
MessageBox(NULL, "Unable to init DirectSound", "ERROR", MB_OK);
return 0;
}
// load a wave file into a directsound buffer
LPDIRECTSOUNDBUFFER DSBuffer = LoadWaveToSoundBuffer("sound1.wav");
if (!DSBuffer)
{
MessageBox(NULL, "Unable to load sound1.wav", "ERROR", MB_OK);
return 0;
}
hr = DirectInput8Create(hInstance, DIRECTINPUT_VERSION,
IID_IDirectInput8, (void**)&g_lpDI, NULL);
if FAILED(hr) return FALSE;
// Retrieve a pointer to an IDirectInputDevice8 interface
hr = g_lpDI->CreateDevice(GUID_SysKeyboard, &g_lpDIDevice, NULL);
hr = g_lpDIDevice->SetDataFormat(&c_dfDIKeyboard);
if FAILED(hr) {
return FALSE;
}
// Set the cooperative level
hr = g_lpDIDevice->SetCooperativeLevel(wndHandle,
DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
if FAILED(hr)
{
return FALSE;
}
// Get access to the input device.
hr = g_lpDIDevice->Acquire();
if FAILED(hr)
{
return FALSE;
}
hr = DSBuffer->SetVolume(curVol);
if FAILED(hr)
{
if(hr==DSERR_INVALIDPARAM)
return FALSE;
}
// Main message loop:
// Enter the message loop
MSG msg;
ZeroMemory( &msg, sizeof(msg) );
while( msg.message!=WM_QUIT )
{
// check for messages
if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
// play this sound
hr = g_lpDIDevice->GetDeviceState(sizeof(buffer),(LPVOID)&buffer);
// check the return state to see if the device is still accessible
if (FAILED ( hr ))
{
// try and reacquire the input device
hr = g_lpDIDevice->Acquire();
// do a continuous loop until the device is reacquired
while( hr == DIERR_INPUTLOST )
hr = g_lpDIDevice->Acquire();
// just continue and do nothing this frame
continue;
}
if (KEYDOWN(buffer, DIK_DOWN))
{
curVol=curVol-1000;
hr=DSBuffer->SetVolume(curVol);
if FAILED(hr)
{
if(hr==DSERR_INVALIDPARAM)
return FALSE;
}
}
playSoundLoop(DSBuffer);
}
}
// Release the DirectSound buffer created above
if (DSBuffer)
{
DSBuffer->Release();
DSBuffer = NULL;
}
// shutdown DirectSound
shutdownDirectSound();
return (int) msg.wParam;
}
/*******************************************************************
* shutdownDirectSound
* Releases the DirecSound device
*******************************************************************/
void shutdownDirectSound(void)
{
if (g_pDS)
{
g_pDS->Release();
g_pDS = NULL;
}
}
/*******************************************************************
* initDirectSound
* Initializes DirectSound
*******************************************************************/
bool initDirectSound(HWND hwnd)
{
HRESULT hr;
hr = DirectSoundCreate8( NULL, &g_pDS, NULL );
if FAILED (hr)
return false;
// Set DirectSound cooperative level
hr = g_pDS->SetCooperativeLevel( hwnd, DSSCL_PRIORITY );
if FAILED ( hr )
return false;
return true;
}
/*******************************************************************
* LoadWaveToSoundBuffer
* Loads a wave file into a DirectSound Buffer
*******************************************************************/
LPDIRECTSOUNDBUFFER LoadWaveToSoundBuffer(std::string wavFilename)
{
LPDIRECTSOUNDBUFFER apDSBuffer = NULL;
CWaveFile *wavFile;
HRESULT hr;
wavFile = new CWaveFile();
wavFile->Open((char*)wavFilename.c_str(), NULL, WAVEFILE_READ );
if( wavFile->GetSize() == 0 )
{
MessageBox(wndHandle, "invalid file", "ERROR", MB_OK);
return false;
}
DSBUFFERDESC dsbd;
ZeroMemory( &dsbd, sizeof(DSBUFFERDESC) );
dsbd.dwSize = sizeof(DSBUFFERDESC);
dsbd.dwFlags = DSBCAPS_CTRLVOLUME;
dsbd.dwBufferBytes = wavFile->GetSize();
dsbd.guid3DAlgorithm = GUID_NULL;
dsbd.lpwfxFormat = wavFile->m_pwfx;
hr = g_pDS->CreateSoundBuffer( &dsbd, &apDSBuffer, NULL );
if FAILED (hr)
{
MessageBox(NULL, "unable to create sound buffer", "ERROR", MB_OK);
return NULL;
}
VOID* pDSLockedBuffer = NULL; // Pointer to locked buffer memory
DWORD dwDSLockedBufferSize = 0; // Size of the locked DirectSound buffer
DWORD dwWavDataRead = 0; // Amount of data read from the wav file
hr = apDSBuffer->Lock( 0, wavFile->GetSize(),
&pDSLockedBuffer, &dwDSLockedBufferSize,
NULL, NULL, 0L );
if FAILED (hr)
return NULL;
// Reset the wave file to the beginning
wavFile->ResetFile();
// Read the wave file
hr = wavFile->Read( (BYTE*) pDSLockedBuffer,
dwDSLockedBufferSize,
&dwWavDataRead );
// Check to make sure that this was successful
if FAILED (hr)
return NULL;
// Check to make sure the wav file is not empty
if( dwWavDataRead == 0 )
{
// Wav is blank, so just fill with silence
FillMemory( (BYTE*) pDSLockedBuffer,
dwDSLockedBufferSize,
(BYTE)(wavFile->m_pwfx->wBitsPerSample == 8 ? 128 : 0 ) );
}
else if( dwWavDataRead < dwDSLockedBufferSize )
{
// Don't repeat the wav file, just fill in silence
FillMemory( (BYTE*) pDSLockedBuffer + dwWavDataRead,
dwDSLockedBufferSize - dwWavDataRead,
(BYTE)(wavFile->m_pwfx->wBitsPerSample == 8 ? 128 : 0 ) );
}
// Unlock the buffer, we don't need it anymore.
apDSBuffer->Unlock( pDSLockedBuffer, dwDSLockedBufferSize, NULL, 0 );
// Clean up
delete wavFile;
return apDSBuffer;
}
/*******************************************************************
* playSound
* plays a sound currently in a buffer only once
*******************************************************************/
void playSound(LPDIRECTSOUNDBUFFER whichBuffer)
{
whichBuffer-> lay( 0, 0, 0);
}
/*******************************************************************
* playSoundLoop
* plays a sound in a buffer repeatedly
*******************************************************************/
void playSoundLoop(LPDIRECTSOUNDBUFFER whichBuffer)
{
whichBuffer->Play( 0, 0, DSBPLAY_LOOPING );
}
/*******************************************************************
* stopSound
* stops the sound in this buffer from playing
*******************************************************************/
void stopSound(LPDIRECTSOUNDBUFFER whichBuffer)
{
whichBuffer->Stop();
}
/*******************************************************************
* initWindow
* inits and creates the window
*******************************************************************/
bool initWindow(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = 0;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = "DirectXExample";
wcex.hIconSm = 0;
RegisterClassEx(&wcex);
wndHandle = CreateWindow("DirectXExample",
"DirectXExample",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
640,
480,
NULL,
NULL,
hInstance,
NULL);
if (!wndHandle)
return false;
ShowWindow(wndHandle, SW_SHOW);
UpdateWindow(wndHandle);
return true;
}
/*******************************************************************
* WndProc
* The window procedure for this window
*******************************************************************/
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
|
|