In addition to using Python, we can also use the C programming language for writing audio applications that leverage ALSA.
Before we begin to write code, we need to install and compile some C programming libraries.
These are libasound2
and its development counterpart libasound2-dev
. Install them using the following command:
sudo apt-get install gcc libasound2 libasound2-dev
The libasound2
library contains the shared library for the ALSA application. The next library, libasound-dev
, is the libasound
library's development file counterpart. You will often see –dev
versions of packages in Linux, as they contain the headers related to a library's interface.
We are now ready to write our C application. This will check which version of ALSA is installed. The idea behind this program is to introduce you to how to import the necessary library into your program. Once you understand this, you can then implement the example C programs from the ALSA website.
Navigate to the c_programs
directory and create a new file called eighth_c_prog.c
.
To this file, add the following code:
#include <stdio.h> #include <alsa/asoundlib.h> #include <alsa/pcm.h> int main(void) { int i =0; printf("Checking Audio information...\n"); printf("Version of ALSA installed: %s\n", SND_LIB_VERSION_STR); printf("\nPCM stream types:\n"); for (i; i <= SND_PCM_STREAM_LAST; i++) { printf("%s\n", snd_pcm_stream_name((snd_pcm_stream_t)i)); } return 0; }
Let's now take a look at what is happening.
First, we import a number of libraries:
#include <stdio.h> #include <alsa/asoundlib.h> #include <alsa/pcm.h>
The first include
statement brings in the standard I/O library so we can print information to the screen.
Following this, we include the asoundlib.h
header file, which we will use to check the ALSA version installed.
Finally, we include the pcm.h
header, which we will use to display the Pulse Code Modulation (PCM) stream types available to us.
You can read more about PCM on the ALSA website at http://www.alsa-project.org/alsa-doc/alsa-lib/pcm.html.
Next is the main()
function. The int
variable is used later in the program in a for
loop. The printf
statement is responsible for outputting text to the screen.
The middle one of the three printf
statements is particularly interesting. Here we check the version of ALSA installed:
printf("Version of ALSA installed: %s\n", SND_LIB_VERSION_STR);
This information is defined in the version.h
file, and in fact this file is imported via the asoundlib.h
file at the top of our program. The location of version.h
is:
/usr/include/alsa/version.h
You can open this file directly in your text editor and examine its contents:
vim /usr/include/alsa/version.h
You should see something similar to this:
/* * version.h */ #define SND_LIB_MAJOR 1 /**< major number of library version */ #define SND_LIB_MINOR 0 /**< minor number of library version */ #define SND_LIB_SUBMINOR 25 /**< subminor number of library version */ #define SND_LIB_EXTRAVER 1000000 /**< extra version number, used mainly for betas */ /** library version */ #define SND_LIB_VERSION ((SND_LIB_MAJOR<<16)|\ (SND_LIB_MINOR<<8)|\ SND_LIB_SUBMINOR) /** library version (string) */ #define SND_LIB_VERSION_STR "1.0.25"
The SND_LIB_VERSION_STR
is the value we output in our program via the printf
statement. When you run the application shortly, you should see these values match.
Following this, we can see a for
loop in our program:
for (i; i <= SND_PCM_STREAM_LAST; i++) { printf("%s\n", snd_pcm_stream_name((snd_pcm_stream_t)i)); }
This loops through the available PCM streams and outputs a list to the terminal. You should expect to see PLAYBACK
and CAPTURE
displayed. PLAYBACK
corresponds to outgoing samples and CAPTURE
to incoming samples.
Let's now compile and test the program and see these values displayed. From the command line, run the following:
gcc eighth_c_prog.c -o eighth_c_prog -lasound
Once compiled, you can run the new program with this:
./eighth_c_prog
This will output something similar to the following:
Checking Audio information... Version of ALSA installed: 1.0.25 PCM stream types: PLAYBACK CAPTURE
Here, we can see the version of ALSA installed and the PCM stream types available, which we discussed briefly previously.
So we have the basics working. Let's take a look at some of the advanced concepts from the ALSA website written in C.
There are a number of programs you can now run on your Raspberry Pi 2 that come from the ALSA website. These can be found at http://www.alsa-project.org/alsa-doc/alsa-lib/examples.html.
We are going to take a look at the program available at http://www.alsa-project.org/alsa-doc/alsa-lib/_2test_2pcm_min_8c-example.html.
Copy the code from the preceding URL and add it to your c_program
directory.
Before you can run this, you will however need to open it up and make a change. If you try to compile it as pasted from the website, you should expect to see the following error:
pcm_min.c:4:34: fatal error: ../include/asoundlib.h: No such file or directory compilation terminated.
The include
statement for the asoundlib.h
library at the top of the program needs to be modified from this:
#include "../include/asoundlib.h"
It should be changed to the following:
#include <alsa/asoundlib.h>
Once you have made this modification, save the file and exit.
It can be compiled as follows; in this instance the program has been named pcm_min.c
, but if you named it something different, then update the compilation command to reflect this:
gcc pcm_min.c -o pcm_min -lasound
This should now compile without an error.
You can run the program via the following command:
./pcm_min
With your speakers or headphones plugged in, you should hear some random samples.
There are a number of examples on the ALSA website that are interesting to experiment with and provide a base for writing your own audio application.
Before we conclude this chapter, we are going to look at one more audio technology for the Raspberry Pi, called Sonic Pi.