How To Use PlaySound in C?


Are you looking to play a Sound in C just by using the PlaySound function Windows provides? Here I’ll show you how to use it properly.

Using the PlaySound(…) function in Windows from the WindowsAPI is very straightforward. You just include the <windows.h> Header file and call the PlaySound(…) Function with appropriate parameters:

#include <windows.h>
...
{
   PlaySound(LPCSTR FileName, HMODULE hmod, DWORD parameter);
}
...

You will get a small example, a link to an more sophisticated example and some alternatives for playing a sound on your PC in the rest of this article.

PlaySound in C Example

Now we provide a short example that shows how to use the function corretcly and explain what is going on. For a detailed description of all possible parameters, etc. you can visit the official Documentation from Microsoft at their MSDN Page for PlaySound functionOpens in a new tab..

We won’t need much sourcecode to get this working, we start with including the windows header file.

In our main function we declare a const for the filename. I do this for convenience, you could also write “test.wav” directly as the first argument of the PlaySound(…) function. This is the first parameter that we have to provide.

The second parameter is NULL most of the time, unless you specified a resource in the first parameter. Then you will have to specify the reference to the resource here and also provide the SND_RESOURCE flag in the third parameter. For more information please look up the MSDNOpens in a new tab..

The third parameter contains flags that specify how to interpret the first two parameters and also defines how the sound should be played. For a complete overview look up the documentation. In our example we use SND_ASYNC, SND_LOOP and SND_FILENAME.

SND_SYNC is optional because it is the default behaviour that PlaySound(…) plays synchronously. For playing the sound asynchronously you wold have to use SND_ASYNC, as we do here in our example.

SND_LOOP makes the sound play again repeatedly until either PlaySound() is called again with NULL as the first parameter or the program ends.

SND_FILENAME tells the function that the first parameter is a filename. If the file in the given name is not found, a default sound is played, unless you set the SND_NODEFAULT flag.

The Sleep(1000) makes our test.wav play for one second.

#include <windows.h>

int main(int argc, char** argv)
{
    const LPCSTR filename = "test.wav";
    PlaySound(filename, NULL, SND_ASYNC | SND_LOOP | SND_FILENAME);
    Sleep(1000);
    return 0;
}

TIP: If you provide NULL as the first argument of PlaySound(…) then all currently playing sounds will be stopped immediatly.

Make sure that you either have a WAVE File called test.wav in the same folder where your main.c is located, or exchange the test.wav with the filename you can provide. Make sure you also provide the Path if the file is located anywhere else.

If you compile the example above (in my case with the GCC Compiler), you will get a linker error.

# Example with GCC Compiler
gcc main.c -o PlaySound

The linker error may look like this, the important part of this message is: undefined reference to `__imp_PlaySoundA’. This means that we are missing a library where the implementation of PlaySound(…) is located.

C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\1136LI~1\AppData\Local\Temp\ccF7tbq9.o:main.c:(.text+0x34): undefined reference to `__imp_PlaySoundA'
collect2.exe: error: ld returned 1 exit status

In order to make it work you have to link against the WinMM library. In GCC you can easily do this by appending -lwinmm to your compiler command.

# Example with GCC Compiler
gcc main.c -o PlaySound -lwinmm

Now everything compiles and links just fine and when you run the PlaySound.exe you should hear the sound of the wave file that you provided under filename.

Extended PlaySound Function in C

You may noticed that the Linker Error Message said that it cannot find the definition for the function PlaySoundA(…). This is the default where the string for the filename is given as an ANSI String.

The alternative is to pass an UNICODE String with the PlaySoundW(…) function. Then you would have to provide a LPCWSTR instead of a LPCSTR and our small example would look like this:

#include <windows.h>

int main(int argc, char** argv)
{
    LPCWSTR filename = L"test.wav";
    PlaySoundW(filename, NULL, SND_ASYNC | SND_LOOP | SND_FILENAME);
    
    Sleep(1000);

    return 0;
}

What about Sound Libraries in C?

If you don’t want to use the WindowsAPI or just have more complex tasks for your sound operations, like in a Game, you may want to use an external library that helps you with playing, pausing, stopping or even recording.

You also cannot play MP3files with PlaySound so this could also be a task of such an external library. I covered three sound libraries that you can use in an article on how to play Wave Files (.WAV) in C.

The libraries I covered there are PortAudio, OpenAL and SDL (Simple DirectMedia Layer) on which I also made an article with example for each:

If you also want a graphical example for the SDL you may look here:

The Old School Beep() in C

If you came here to literally just play a sound without providing a wave file in any format, you might be interested in the plain old Beep() function. Despite being a relic from the pre-Soundblaster era, you can still use this feature today – with a catch. Modern PCs may not have the hardware or the Sound Scheme is not configured to actually play the sound.

So without a guarantee that you will actually hear something, here is the code to make your Computer beep…

First we will include the windows header, but lean_and_mean which means that we will exclude excludes APIs such as Cryptography, DDE, RPC, Shell, and Windows Sockets which we won’t need anyways.

The Beep(…) function takes two arguments, the first one is the frequency of the sound in Hz and the second is the duration in ms until the sound is on.

The Beep(..) function returns 0 if it does not produce a sound or a non-zero value if the sound was produced successfully. Please note that Beep(..) is synchronous, so the printf() or any other code will only be executed after the sound has finished.

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>

int main(int argc, char** argv)
{
    Beep(800,900); /* 800 Hz, 0.9 ms */
    printf("Sound Return Value: %d", success);

    return 0;
}

If you compile and start the program and actually hear a sound then congratulations. The Console Output then should be:

Sound Return Value: 1

If you then want to have some fun with the Beep(…) you can visit GeeksForGeeksOpens in a new tab. and type the code from Program 2. Running this will give you a Beep Beep Version of Jingle Bells.

Summary

We covered how to play a sound with PlaySound(…) as well as the extended PlaySoundW(…) and the old school Beep(…) functions. We also learned that there are external sound libraries that can help with more complex tasks if needed. Now go ahead and make your own sound applications!

Marco Lieblang

Professional Programmer since 2003, passionate Programmer since the mid 90's. Developing in many languages from C/C++ to Java, C#, Python and some more. And I also may know a bit about Assembly Languages and Retro Systems.

Recent Posts