Windows API "Playsound" not working.......

Started by
21 comments, last by BekkiBlack 13 years ago
I linked winMM, it compiles, but it doesn't play the target file.

I included a .wav file to the project, made a function declaration for the filename and such, plus flags, included mmsystem.h and used a wParam switch statement under WM_KEYUP case label with a VK_ESCAPE function so when you press escape it will call on the PlaySound function but it just makes an error noise when you play it and fails.

Here's the exact code I'm using.....


#include <d3d9.h>
#include <mmsystem.h>
BOOL PlaySound(LPCSTR FILE, HMODULE FLAG, DWORD OTHER);
LPDIRECT3D9 g_pD3D = NULL;
LPDIRECT3DDEVICE9 g_pD3DDevice = NULL;
HRESULT InitialiseD3D(HWND hWnd)
{
// First of all, create the main D3D object. If it is created successfully
// we should get a pointer to an IDirect3D8 interface.
g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);

if(g_pD3D == NULL)
{
return E_FAIL;
}

//Get the current display mode
D3DDISPLAYMODE d3ddm;
if(FAILED(g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm)))
{
return E_FAIL;
}

// Create a structure to hold the settings for our device
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));

// Fill the structure: Program shall be windowed,
// back buffer format matches current display mode
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = d3ddm.Format;

//Create a Direct3D device.
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pD3DDevice)))
{
return E_FAIL;
}

return S_OK;
}

void Render()
{
if(g_pD3DDevice == NULL)
{
return;
}

// Clear the backbuffer to blue
g_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET,
D3DCOLOR_XRGB(0, 0, 255), 1.0f, 0);

// Begin the scene
g_pD3DDevice->BeginScene();

// Fill in here the rendering of other objects

// End the scene
g_pD3DDevice->EndScene();

// Fill back and front buffers so that back buffer will be visible on screen
g_pD3DDevice->Present(NULL, NULL, NULL, NULL);
}

void CleanUp()
{
if(g_pD3DDevice != NULL)
{
g_pD3DDevice->Release();
g_pD3DDevice = NULL;
}

if(g_pD3D != NULL)
{
g_pD3D->Release();
g_pD3D = NULL;
}
}

void MainLoop()
{
// Enter the main loop
MSG msg;
BOOL bMessage;

PeekMessage(&msg, NULL, 0U, 0U, PM_NOREMOVE);

while(msg.message != WM_QUIT)
{
bMessage = PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE);

if(bMessage)
{
// Process message
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
Render(); // No message to process -> render the scene
}
}// while
}

// The windows message handler
LRESULT WINAPI WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
break;

case WM_KEYUP:
switch (wParam)
{
case VK_ESCAPE:
// Escape key pressed -> PlaySound should return true.
PlaySound("blah.wav", NULL, SND_FILENAME);
break;
}
break;
}// switch

return DefWindowProc(hWnd, msg, wParam, lParam);
}

// Application main entry point
INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, INT)
{
//Register the window class
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WinProc, 0L, 0L,
GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
"DirectX Project", NULL };
RegisterClassEx(&wc);

// Create the application's main window
HWND hWnd = CreateWindow("DirectX Project of mine", "MY project",
WS_OVERLAPPEDWINDOW, 50, 50, 500, 500,
GetDesktopWindow(), NULL, wc.hInstance, NULL);

// Initialize Direct3D
if(SUCCEEDED(InitialiseD3D(hWnd)))
{
// Show window
ShowWindow(hWnd, SW_SHOWDEFAULT);
UpdateWindow(hWnd);

//Start game running: Enter the game loop
MainLoop();
}

CleanUp();

UnregisterClass("DirectX Project", wc.hInstance);

return 0;
}


Anyone have an idea what the issue could be, besides DirectX's interference?

Also, it's not the fact that I'm not using <windows.h>. DirectX's <d3d9.h> includes it itself, so it's not that problem.
Advertisement

I linked winMM, it compiles, but it doesn't play the target file.

I included a .wav file to the project, made a function declaration for the filename and such, plus flags, included mmsystem.h and used a wParam switch statement under WM_KEYUP case label with a VK_ESCAPE function so when you press escape it will call on the PlaySound function but it just makes an error noise when you play it and fails.

Here's the exact code I'm using.....


#include <d3d9.h>
#include <mmsystem.h>
BOOL PlaySound(LPCSTR FILE, HMODULE FLAG, DWORD OTHER);
LPDIRECT3D9 g_pD3D = NULL;
LPDIRECT3DDEVICE9 g_pD3DDevice = NULL;
HRESULT InitialiseD3D(HWND hWnd)
{
// First of all, create the main D3D object. If it is created successfully
// we should get a pointer to an IDirect3D8 interface.
g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);

if(g_pD3D == NULL)
{
return E_FAIL;
}

//Get the current display mode
D3DDISPLAYMODE d3ddm;
if(FAILED(g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm)))
{
return E_FAIL;
}

// Create a structure to hold the settings for our device
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));

// Fill the structure: Program shall be windowed,
// back buffer format matches current display mode
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = d3ddm.Format;

//Create a Direct3D device.
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pD3DDevice)))
{
return E_FAIL;
}

return S_OK;
}

void Render()
{
if(g_pD3DDevice == NULL)
{
return;
}

// Clear the backbuffer to blue
g_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET,
D3DCOLOR_XRGB(0, 0, 255), 1.0f, 0);

// Begin the scene
g_pD3DDevice->BeginScene();

// Fill in here the rendering of other objects

// End the scene
g_pD3DDevice->EndScene();

// Fill back and front buffers so that back buffer will be visible on screen
g_pD3DDevice->Present(NULL, NULL, NULL, NULL);
}

void CleanUp()
{
if(g_pD3DDevice != NULL)
{
g_pD3DDevice->Release();
g_pD3DDevice = NULL;
}

if(g_pD3D != NULL)
{
g_pD3D->Release();
g_pD3D = NULL;
}
}

void MainLoop()
{
// Enter the main loop
MSG msg;
BOOL bMessage;

PeekMessage(&msg, NULL, 0U, 0U, PM_NOREMOVE);

while(msg.message != WM_QUIT)
{
bMessage = PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE);

if(bMessage)
{
// Process message
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
Render(); // No message to process -> render the scene
}
}// while
}

// The windows message handler
LRESULT WINAPI WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
break;

case WM_KEYUP:
switch (wParam)
{
case VK_ESCAPE:
// Escape key pressed -> PlaySound should return true.
PlaySound("blah.wav", NULL, SND_FILENAME);
break;
}
break;
}// switch

return DefWindowProc(hWnd, msg, wParam, lParam);
}

// Application main entry point
INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, INT)
{
//Register the window class
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WinProc, 0L, 0L,
GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
"DirectX Project", NULL };
RegisterClassEx(&wc);

// Create the application's main window
HWND hWnd = CreateWindow("DirectX Project of mine", "MY project",
WS_OVERLAPPEDWINDOW, 50, 50, 500, 500,
GetDesktopWindow(), NULL, wc.hInstance, NULL);

// Initialize Direct3D
if(SUCCEEDED(InitialiseD3D(hWnd)))
{
// Show window
ShowWindow(hWnd, SW_SHOWDEFAULT);
UpdateWindow(hWnd);

//Start game running: Enter the game loop
MainLoop();
}

CleanUp();

UnregisterClass("DirectX Project", wc.hInstance);

return 0;
}


Anyone have an idea what the issue could be, besides DirectX's interference?

Also, it's not the fact that I'm not using <windows.h>. DirectX's <d3d9.h> includes it itself, so it's not that problem.


Also, does anyone know the easiest way of playing sounds using DirectX? I chose Windows API with its own libraries because it seems 10x easier than with the confusion of DirectX.
if you want a GOOD FREE OpenSource library to play mp3/wav/ogg/flac then try CAudio here
it already have all dlls and libs, so u don't need to compile any sources
it's based on popular crossplatform OpenAL and have no problem working with dx,
it also has tutorials and memory manager
aside from that it can also record sounds from mic, use special effects[reverb, echo, underwater] and stream audio.

now about your problem:
PlaySound("blah.wav", NULL, SND_FILENAME);
this functions returns true if it can play sound, you need check for that first
possible reasons for not playing:
application seeks that file in debug foler, while it's located somehwere else, try "../blah.wav"
it's wrong wav file[since that api can play only spiecific wav files] try different wav file, for example the file that goes with windows
Crazy dude smoking D3D11, AngelScript, PhysX, 3D Sound, Network, DB, FBX, and some other weird things, doing that on Visual Studio 2010 + Visual Assist X on Overclocked CPU
If i am not wrong WM_KEYUP triggers the event when you relese the button( in this case Escape ).
You can try to switch to WM_KEYDOWN, which will trigger the events when you press the button.
All DirectX APIs for playing sound are deprecated, except XACT, which too is kinda hardcore, so you can switch to what e3d_ALiVE proposed - CAudio
or use FMOD , which is superb, but if you are planning to sell your game you have to pay for license.
I tried different .wav files, changed the filename, used WM_KEYDOWN and it still doesn't work.

What could be the problem??
By the way did you take this source code from tutorial or something?
Because playing sound with DirectSound is a lot more complicated:
tut

Also in your code you never initialize any sound system, which is like to wanna play dvd, but without dvd player :D
Also why do you declare at top PlaySound? Isnt this function declared in mmsystem.h already?
Also i guarantee that with fmod you will play background sound in less then 1 hour.
Also i got source code for this if need help with fmod.
Zomg too much also.
[color="#1C2837"][color="#666600"][font="CourierNew, monospace"] [/font]
Try providing the absolute path to the .wav file. The current working directory might not be where you think it is (esp. when running from IDE)

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>


Try providing the absolute path to the .wav file. The current working directory might not be where you think it is (esp. when running from IDE)


I did provide the absolute path, put it in a search directory, changed the declaration around, everything. A tutorial claimed that you only need to declare a prototype function and then just call on the function and it plays a sound. That's it...But it doesn't work.

I tried everything I can think of. It compiles, everything works fine, but the sound won't play.

Also, I tried those other sound libraries....They were a pain. All they did was cause the compiler to endlessly complain about missing .dll files and it was just torture.
Does the function fail? If so, try checking the result of GetLastError().

Another cause might be a invalid wav file. Just because one player can play it doesn't mean it's a proper file. Check if other players have no problem with the file as well. Sometimes just opening the wave in an audio editor and saving again fixes problems.

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

CAudio requres you to put only 2 dlls into your folder, caudio and mp3plugin, + you need to link it with lib file, like that


#pragma comment(lib,"caudio.lib")
and add that line #include <cAudio.h>


put caudio include files into your search paths or put lib file and caudio files into your source directory


after that it's just

cAudio::IAudioManager* manager;
cAudio::IAudioSource *jumpS;
manager = cAudio::createAudioManager(true);
jumpS=manager->create("test1","Res/Audio/jump.wav",true);

that's it
Crazy dude smoking D3D11, AngelScript, PhysX, 3D Sound, Network, DB, FBX, and some other weird things, doing that on Visual Studio 2010 + Visual Assist X on Overclocked CPU

This topic is closed to new replies.

Advertisement