Set up audio and additional components

Now let's set up the audio components that we need to play a .wav file in your app. We use main() as the calling function. The PlayWav sample app also handles navigator and dialog events, but in this tutorial, we focus on the libasound audio components.

Audio variables and macros

There are several variables and macros that we need to define, both in the global scope and local scope of our app.

Global scope

Let's begin by declaring variables that we use in the global scope of the app. Declare constant character arrays for RIFF and WAVE identifiers. After you declare these variables, you can reference the strings, "RIFF" and "WAVE", by using riff_id and wave_id, respectively. Next, declare a macro for the relative path of the .wav file. The PlayWav sample app uses sample.wav, but you can change that to match the name of the .wav file that you want to use in your app.

/* 
 * Buffer to store messages that we will display in the dialog
 */
#define MSG_SIZE 1024
static char msg[MSG_SIZE];

const char *riff_id = "RIFF";
const char *wave_id = "WAVE";

#define WAV_RELATIVE_PATH "app/native/<your_sample>.wav"

#define SUCCESS  0
#define FAILURE -1

Because each chunk begins with a tag and size, you can create a corresponding structure to handle tags.

typedef struct
{
    char    tag[4]; 
    long    length; 
}
riff_tag;

To handle the .riff header, you can use a typedef structure.

typedef struct
{
    char    Riff[4]; 
    long    Size;    
    char    Wave[4]; 
}
riff_hdr;

To handle the format chunk, we use a typedef structure.

typedef struct
{
    short   format_tag;
    short   channels;
    long    samples_per_sec;
    long    avg_bytes_per_sec;
    short   block_align;
    short   bits_per_sample;
}
wave_hdr;

Declare an integer variable for the sound card number and initialize it to -1. Then declare the PCM handle structure and a structure that describes the PCM capabilities.

int card = -1;

snd_pcm_t *pcm_handle;
snd_pcm_info_t info;

Declare a structure that describes the parameters of a PCM capture or playback channel, a structure that describes the current configuration of a PCM channel, and a structure that describes PCM channel information. Next, declare a mixer handle structure and a control structure for a mixer group.

snd_pcm_channel_params_t pp;
snd_pcm_channel_setup_t setup;
snd_pcm_channel_info_t pi;

snd_mixer_t *mixer_handle;
snd_mixer_group_t group;

Now that we defined the structure for the format chunk, we should declare an instance of the structure in the global scope.

wave_hdr wav_header;

Last, declare integer variables for the sample rate, number of channels for sample data, and number of bits per sample.

int sample_rate;
int sample_channels;
int sample_bits;

int
err(char *message)
{
    snprintf(msg, MSG_SIZE, "%s\n%s", message, strerror(errno));
    show_dialog_message (msg);
    return -1;
}

Last modified: 2015-03-31



Got questions about leaving a comment? Get answers from our Disqus FAQ.

comments powered by Disqus