Have you ever tried to play sounds from within your C Program? Playing a .wav file is a common use case, may it be as a sound effect or background music for your game and/or application.
There are the OpenAL, PortAudio and Simple DirectMedia Layer (SDL) libraries for playing wave files. These three libraries are really well tested and written in C. They differ in their approach and their licensing.
We will examine this three ways of playing a .wav file in C in the rest of this article, so keep reading.
How To Play a .WAV File in the C Language
You have several possibilities to simply play a .wav File with the C language. In most cases you will have the audio files saved on your hard disk and would want to load them into memory in order to play them with your primary sound system.
The sound system itself is nothing more than an output buffer where formatted date is read into. The task is to get the data from the stored file into the output buffer in the correct format. This is where you can use already existing libraries which will provide assistance to you.
Depending on the type of application you write you should choose from one of the following three libraries.
|Wave Loader needed?
|Proprietary / LGPL (OpenAL Soft)
|Simple DirectMedia Layer (SDL)
The all differ in the approach how they load and play audio files and in their licensing. There are good licensing options for any of them so this should not be a problem but something you have to keep in mind when you are going to program a commercial application or game.
Until not long ago I would have included xaudio2 from the Windows API / DirectX libraries but on the one hand in the latest installments you are forced to use C++ and on the other hand these would be a solution for only one operating system.
Why .WAV (Wave) Files?
In the days of MP3 and AAC you may wonder why anyone would play a pure (big) .wav file. The short answer is: Because Quality. Every form of compression reduces the quality despite the fact that modern compression algorithms are very good. In today’s world of unlimited disk space capacity you can go for the better quality and use .wav files for your games and programs.
Wave files are also easy to read and the specification is readily available online. It is an application of the Resource Interchange File Format (RIFF) which stores data in chunks which have a specific format themselves.
Loading a Wave File in C
While the libraries presented in this article are good for playing wav files, some of them lack the possibility of loading wave files.
Playing a wave file is literally putting float data into an output buffer which happens to be an audio device. Loading a wave file means that you read the data which is stored in a specific format (the wav format) and “translate” it into the data that the output buffer can handle.
You could write such a wave loader yourself (and it may be a good programming practice), but there are libraries out there written in C and doing it for us. The ones I use in the examples are TinyWav and sndfile. Read more about them in the corresponding articles where I use them.
The Three Most Basic Ways to Play a .WAV File in C
The following sections give a brief overview of the libraries for playing wave files in C. In each section there is a link to an article which contains an example of how to use each library in order to play a wave file. They can thus be considered as Hello World examples.
OpenAL (Open Audio Library) is an API (Application Programming Interface) with the goal of efficiently rendering multichannel three-dimensional positional audio, usually in games. It is cross-platform and has a proprietary license, but you can use the OpenAL Soft implementation which is licensed under the LGPL.
Based on the idea of OpenGL (Open Graphics Library) it has the same workflow. You have to provide the data in buffers at the appropriate places in the sound pipeline.
The library itself needs a separate wave loader to get these files into the buffer. If you are interested in an example of how to use OpenAL (and a wave loader) you can read my article on this topic.
The approach here is the so called callback paradigm which is also used by JACK and ASIO. Playing happens with a stream of data which constantly calls a callback function where you as the programmer are able to manipulate the wave date or just simply read it to the output buffer.
PortAudio also needs a separate wave loader and in Audacity the sndfile library is used for that. I also use it in my example of how to start programming PortAudio in C.
SDL (Simple DirectMedia Layer)
The Simple DirectMedia Layer Library (SDL) is a cross platform multimedia library that is made with a game programmer in mind. One part of the library is for playing music and sound. It is licensed under the zlib license.
While you can still use the 1.x versions of the library you should rather use SDL2 which was introduced in 2013 and is not backwards compatible to the older versions. If you want a general overview of the SDL and its usage in C I have written an in depth article about that here.
The SDL is able to load a wave file itself so you don’t need another library for that. If you want to know how to play a wave file with the SDL you can read my article which is provided here.