I'm writing a C++ Windows Application program which needs to Play a randomly chosen song from an array and the user needs to be able to play another song on the list at the click of a button. How would you stop the sound from the first song as to play the second song?
By pressing my button which plays the first song, the audio resource is played, however my program no longer responds to any clicks and the code does not continue until the song is complete. I have attempted using CreateThread(), however to no avail as my program remains in an unresponsive state.
The Function containing PlaySound:
LPTHREAD_START_ROUTINE WINAPI PlayWavFile(int resource) {
PlaySound(MAKEINTRESOURCE(resource), hInst, SND_RESOURCE | SND_SYNC);
return 0;
}
The case in the WndProc function which determines the result of button presses:
case WM_COMMAND:
if (LOWORD(wParam) == 1) {
HANDLE hThread = CreateThread(
NULL,
0,
PlayWavFile(i),
NULL,
NULL,
NULL
);
}
else if (LOWORD(wParam) == 2) {
HANDLE hPlaySecond = CreateThread(
NULL,
0,
PlayWavFile(j),
NULL,
NULL,
NULL
);
}
else if (LOWORD(wParam) == 3) {
HANDLE hStop = CreateThread(
NULL,
0,
PlayWavFile(NULL),
NULL,
NULL,
NULL
);
}
break;
Also if if I try clicking my button which should give the wParam value of 3, the program reaches an exception which states:
Exception thrown at 0x00000000 in Audio Player.exe: 0xC0000005: Access violation executing location 0x00000000. occurred.
The end goal is that the program would just be responsive whilst the music plays in the background.
Just call PlaySound
directly with SND_ASYNC
instead of SND_SYNC
. That would cause PlaySound
to return immediately and play the sound in the background.
There's no need to mess around with threads for that.
When you do
HANDLE hThread = CreateThread(
NULL,
0,
PlayWavFile(i),
NULL,
NULL,
NULL
);
you are calling the function PlayWavFile
, and are using the value it returns as the thread function to call. And since the function is always returning 0
, which is a null pointer, it's equivalent to
HANDLE hThread = CreateThread(
NULL,
0,
nullptr,
NULL,
NULL,
NULL
);
The thread function arguments is of the type LPTHREAD_START_ROUTINE
, which is a pointer to a function which takes an LPVOID
argument, and returns a DWORD
.
You need to change your thread function accordingly, and then call CreateThread
as
HANDLE hThread = CreateThread(
NULL,
0,
&PlayWavFile, // Pass a pointer to the function
reinterpret_cast<LPVOID>(i), // The argument to pass
NULL,
NULL
);
With this the PlayWavFile
could look something like
DWORD PlayWavFile(LPVOID argument) {
int resource = reinterpret_cast<int>(argument);
PlaySound(MAKEINTRESOURCE(resource), hInst, SND_RESOURCE | SND_SYNC);
return 0;
}
User contributions licensed under CC BY-SA 3.0