Playing an audio file results in program not responding.

I'm trying to make a simple audio player in C++ using the Win32 API.
Everything works perfectly fine, except when I play an audio file. Playing an audio file makes the program not respond until the full audio file plays out.

If somebody could guide me to the right direction, that would be greatly appreciated. Thanks in advance!

WM_COMMAND Switch Statement (in oshyClient.cpp)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
		case WM_COMMAND:
			switch (wp) {

				case MENU_EXIT:
					PostQuitMessage(0);
					break;

				case MENU_ADDAUDIO:
					queue.addNewAudioToQueue(hWnd);
					break;

				case BUTTON_PLAY:
					char text[MAX_PATH];
					SendMessage(queue.hAudioQueue, LB_GETTEXT, 0, 
                                        (LPARAM)text);
					audio.playAudio(text);
					break;

			}
			break;


Audio player (in oshyClientAudioPlayer.cpp)
1
2
3
4
5
6
7
8
9
10
11
12
#include "oshyClientAudioPlayer.h"
#include "oshyClient.h"
#include <iostream>

void AudioPlayer::displayAudioControls(HWND hWnd) {
 	CreateWindow(L"Button", L"▶", WS_VISIBLE | WS_CHILD, 35, 5, 25, 25, hWnd, (HMENU)BUTTON_PLAY, NULL, NULL);
    CreateWindow(L"Button", L"■", WS_VISIBLE | WS_CHILD, 5, 5, 25, 25, hWnd, NULL, NULL, NULL);
}

void AudioPlayer::playAudio(const char* audioLocation) {
    PlaySound((LPCWSTR)audioLocation, NULL, SND_FILENAME);
}


Audio Queue (in oshyClientAudioQueue.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include "oshyClientAudioQueue.h"
#include "oshyClient.h"

void AudioQueue::displayAudioQueue(HWND hWnd) {

	hAudioQueue = CreateWindowEx(WS_EX_CLIENTEDGE, L"listbox", L"", WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_AUTOVSCROLL | 0, 4, 92, 474, 250, hWnd, (HMENU)ID_LISTBOX, 0, 0);

}

void AudioQueue::addNewAudioToQueue(HWND hWnd) {

    OPENFILENAMEA file;
    char fileName[100];

    ZeroMemory(&file, sizeof(OPENFILENAMEA));

    file.lStructSize = sizeof(OPENFILENAMEA);
    file.hwndOwner = hWnd;
    file.lpstrFile = fileName;
    file.lpstrFile[0] = '\0';
    file.nMaxFile = 100;
    file.lpstrFilter = "All Files\0*.*\0";
    file.nFilterIndex = 1;

    if (GetOpenFileNameA(&file)) {
        SendMessageA(hAudioQueue, LB_ADDSTRING, 0, (LPARAM)file.lpstrFile);
    }

}
Last edited on
The default behaviour of the PlaySound function, as you are finding out, is to play the sound synchronously. That effectively halts the program until the sound finishes playing and the PlaySound function returns. You should play the sound asynchronously. That starts the sound playing and then the function immediately returns.

A reminder of the flags you can use in PlaySound:
https://docs.microsoft.com/en-us/previous-versions//dd743680(v=vs.85)
Turning it to play asynchronously certainly did the job, thank you George!
PlaySound() is mostly intended to play short sounds, like windows "ding" sound.

An "audio player" application probably should be using MCI instead:
https://docs.microsoft.com/en-us/windows/win32/multimedia/playing-a-waveform-audio-file

This will allow you, e.g., to pause/resume the playback or to seek (jump) to a specific position in the file.

Also, MCI provides you with window messages that tell you when playback is completed:
https://docs.microsoft.com/en-us/windows/win32/multimedia/the-notify-flag

Note: The function mciSendCommand() does not block the caller, unless the MCI_WAIT flag is used.
Last edited on
Hello. May I suggest to you to take a look at a single header file in order to play a wav file?
It could be useful for you - and more efficient than the mciSendCommand way ++
https://github.com/adamstark/AudioFile/blob/master/AudioFile.h
The OP stated they are using the Win32 API, so MCI is appropriate instead of a 3rd party library.
Registered users can post here. Sign in or register to post.