我已經實現了基於tutorial的直接聲音類,但在測試時遇到問題。我已經將錯誤追溯到IDirectSound8 :: SetCooperativeLevel,它返回一個錯誤。IDirectSound8 SetCooperativeLevel返回不正確的參數
這裏是我的DirectSound的初始化方法的snipit
HRESULT r;
DSBUFFERDESC bufferDesc;
WAVEFORMATEX wavFormat;
r = DirectSoundCreate8(NULL, &DSound, NULL);
if (FAILED(r))
{
_com_error error(r);
LPCTSTR errText = error.ErrorMessage();
OutputDebugString(errText);
return false;
}
OutputDebugStringA("\nCOMPLETE: DSound Stage 1 ");
r = DSound->SetCooperativeLevel(hwnd, DSSCL_PRIORITY);
if (FAILED(r))
{
_com_error error(r);
LPCTSTR errText = error.ErrorMessage();
OutputDebugString(errText);
return false;
}
OutputDebugStringA("\nCOMPLETE: DSound Stage 2 ");
的程序得到過去我的「DSOUND第1階段」,但在r = DSound->SetCooperativeLevel(hwnd, DSSCL_PRIORITY);
聲明失敗「的參數不正確。」
在這一點上,我不知道爲什麼這個錯誤發生或如何解決它。我認爲問題在於我傳入的HWND參數,但是我不知道是否有問題。
這個問題可能是由運行時沒有創建物理窗口引起的嗎?我的意思是,當我編譯這個項目時,沒有生成窗口 - 雖然看起來好像應該有。
這裏是Main.cpp,我發送給我的音頻類的HWND被設置,值得注意的是我沒有寫這個文件,也沒有完全理解它是否應該創建一個窗口。
#include <windows.h>
#include <windowsx.h>
#include "RenderEngine.h"
#include "Timer.h"
#include "Audio.h"
//WindowProc function prototype
LRESULT CALLBACK WindowProc(HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, //Handle to and Instance, This is how windows keeps track of which program is which.
HINSTANCE hPrevInstance, //Handle to the Previous Instance, this is a backwards compatibility requirement
LPSTR lpCmdLine, //This is a Long Pointer to a string that contains the command line creating the application.
int nShowCmd) //This determines what the window will look like.
{
//First we create our Handle for the Window
HWND hWnd;
//Next we create our WindowClass Struct
WNDCLASSEX wc;
///////////////////////////////////////////////////////////////
//Create our Render Engine Class
Timer GameTimer;
RenderEngine Renderer;
///////////////////////////////////////////////////////////////
//Create our Audio Class
Audio* audio;
///////////////////////////////////////////////////////////////
//Ensure the class is empty for use...
ZeroMemory(&wc, sizeof(WNDCLASSEX));
//Initialize the Struct
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
wc.lpszClassName = L"WIndowClass1";
//Regist the Window Class
RegisterClassEx(&wc);
//Create the windows and use the result as the handle
hWnd = CreateWindowEx(NULL,
L"GSP420 WindowClass", //Name of the Window Class
L"GSP420 Project", //Title of the Window
WS_OVERLAPPEDWINDOW, //Window style
300, //x-position of the Window
300, //y-position of the Window
SCREENWIDTH, //Width of the Window
SCREENHEIGHT, //Heigt of the Window
NULL, //There is no parent window
NULL, //No menus are being used
hInstance, //The application handle
NULL); //We're not using Multiple-Windows
//Display the Window
ShowWindow(hWnd, nShowCmd);
////////////////////////////////////////////////////////////////////
//Setup and Initialize Direct3D
Renderer.initD3D(hWnd);
////////////////////////////////////////////////////////////////////
//Setup and Initialize DirectSound
OutputDebugStringA("BEGIN: AudioInit");
audio = new Audio;
audio->AudioInit(hWnd);
OutputDebugStringA("\nCOMPLETE: AudioInit\n");
////////////////////////////////////////////////////////////////////
//Enter the main loop
//Windows Event Message Struct
MSG msg;
//Enter our Loop
while (TRUE)
{
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
//Translate keystrokes into the correct format
TranslateMessage(&msg);
//Send the messages to WindowProc
DispatchMessage(&msg);
}
//If the message is WM_QUIT, exit the loop
if (msg.message == WM_QUIT)
break;
////////////////////////////////////
////////RUN OUR GAME CODE HERE//////
////////////////////////////////////
GameTimer.calculateTime();
Renderer.renderFrame();
////////////////////////////////////
////////RUN OUR GAME CODE HERE//////
////////////////////////////////////
}
////////////////////////////////////////////////////////
//Clean up DirectX and COM
Renderer.cleanD3D();
//Return this part of the WM_QUIT message to Windows
return msg.wParam;
}
//Main Message Handler for the Program
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
//Sort through and find the code to execute
switch (message)
{
//This message is read when the window is closed
case WM_DESTROY:
{
//Close the application
PostQuitMessage(0);
return 0;
}break;
}
//Handle any messages the switch statement didn't
return DefWindowProc(hWnd, message, wParam, lParam);
}
以供參考整個InitDSound方法
bool Audio::InitDSound(HWND hwnd)
{
HRESULT r; // Create result variable
DSBUFFERDESC bufferDesc;
WAVEFORMATEX wavFormat;
r = DirectSoundCreate8(NULL, &DSound, NULL); // Initialize DSound
if (FAILED(r)) // Check result, break if initialization failed
{
_com_error error(r);
LPCTSTR errText = error.ErrorMessage();
OutputDebugString(errText);
return false;
}
OutputDebugStringA("\nCOMPLETE: DSound Stage 1 ");
r = DSound->SetCooperativeLevel(hwnd, DSSCL_PRIORITY); // No idea, allows the format of the primary buffer to be modified
if (FAILED(r)) // Check result, break if that thing didnt work
{
_com_error error(r);
LPCTSTR errText = error.ErrorMessage();
OutputDebugString(errText);
return false;
}
OutputDebugStringA("\nCOMPLETE: DSound Stage 2 ");
//////////////////////////////////
// Primary Buffer Descritpion
//////////////////////////////////
bufferDesc.dwSize = sizeof(DSBUFFERDESC);
bufferDesc.dwFlags = DSBCAPS_PRIMARYBUFFER | DSBCAPS_CTRLVOLUME;
bufferDesc.dwBufferBytes = 0;
bufferDesc.dwReserved = 0;
bufferDesc.lpwfxFormat = NULL;
bufferDesc.guid3DAlgorithm = GUID_NULL;
r = DSound->CreateSoundBuffer(&bufferDesc, &pBuffer, NULL); // Get control of the primary sound buffer on the sounde device
if (FAILED(r)) // Check result, break if that failed
{
_com_error error(r);
LPCTSTR errText = error.ErrorMessage();
OutputDebugString(errText);
return false;
}
OutputDebugStringA("\nCOMPLETE: DSound Stage 3 ");
//////////////////////////////////
// Primary Buffer Format
// (WAV @44,100 16bit stereo)
//////////////////////////////////
wavFormat.wFormatTag = WAVE_FORMAT_PCM;
wavFormat.nSamplesPerSec = 44100;
wavFormat.wBitsPerSample = 16;
wavFormat.nChannels = 2;
wavFormat.nBlockAlign = (wavFormat.wBitsPerSample/8) * wavFormat.nChannels;
wavFormat.nAvgBytesPerSec = wavFormat.nSamplesPerSec * wavFormat.nBlockAlign;
wavFormat.cbSize = 0;
r = pBuffer->SetFormat(&wavFormat); // Set the primary buffer format
if (FAILED(r)) // Check result, break if that failed
{
_com_error error(r);
LPCTSTR errText = error.ErrorMessage();
OutputDebugString(errText);
return false;
}
OutputDebugStringA("\nCOMPLETE: DSound Stage 4 ");
return true;
}