C and ALSA

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.