Playing audio

How to

Play an audio file in the background of your application.

Solution

const char *ctxt_name = "testplayer";
const char *audio_out = "audio:default";
const char *input_type = "track";
char cwd[PATH_MAX];
char input_url[PATH_MAX];
int audio_oid;

mode_t mode = S_IRUSR | S_IXUSR;   // S_IRUSR indicates read permission
                                   // and S_IXUSR indicates
                                   // execute/search permission

getcwd(cwd, PATH_MAX);
snprintf(input_url, PATH_MAX, "file://%s%s", cwd,
         "/app/native/test.mp3");

mmr_connection_t *connection;
mmr_context_t *ctxt;

connection = mmr_connect(NULL);
ctxt = mmr_context_create(connection, ctxt_name, 0, mode);

audio_oid = mmr_output_attach(ctxt, audio_out, "audio");
mmr_output_parameters(ctxt, audio_oid, NULL);

mmr_input_attach(ctxt, input_url, input_type);

mmr_play(ctxt);

// Perform other application tasks here

mmr_stop(ctxt);
mmr_input_detach(ctxt);
mmr_context_destroy(ctxt);
mmr_disconnect(connection);

Build requirements

You must include the following header files:

#include <stdio.h>
#include <unistd.h>
#include <mm/renderer.h>

This solution also requires that the audio file to play is located in the /app/native/ folder on the device. In this solution, the name of the audio file is test.mp3.

Discussion

In some applications that you create, you may want to play audio in the background (for example, in a game that includes a soundtrack, or in a music player application). You can use the multimedia renderer library to play an audio file in your application, and you can perform other application tasks while the file is playing.

First, you must declare a few variables to store playback information. This information includes the name of the multimedia renderer context (to identify the multimedia renderer to your application), the audio output device (to use to play the audio file), the type of input (for example, a track, a playlist, a DVD, and so on), and the location of the audio file. You must also define the mode of the multimedia renderer context, which indicates the types of actions that you can perform on the audio file. For audio files, it's important for the application to read them and execute (play) them, and you can use the S_IRUSR and S_IXUSR constants to specify these actions.

Next, you should construct a string that specifies the location of the audio file. If you know the location of the audio file relative to the current working directory on the device, you can call getcwd() (which is included in unistd.h) to retrieve the current working directory, and then call snprintf() to create a string that represents the full path of the file. For this approach to work, you need to make sure that the current working directory is never set elsewhere in your application. The PATH_MAX constant specifies the maximum number of characters for a file name on the device.

The multimedia renderer contains two important structures. The mmr_connection_t structure represents a connection to the renderer. Your application must connect to the renderer by calling mmr_connect() before any files can be played. You can specify a name for the renderer by passing it as an argument to mmr_connect(), or you can pass NULL to use the default name. The renderer also contains the mmr_context_t structure. This structure represents a renderer context, to which you can attach an input (the audio file) and an output (the audio output device). You must create this context by calling mmr_create_context() and specifying the renderer connection, a name for the context, and the mode.

After you connect to the renderer and create the context, you can attach the output to the context by calling mmr_attach_output(), making sure to specify the type of output ("audio"). You can also set output parameters, such as initial volume and output stream selection, by calling mmr_output_parameters(). An argument of NULL indicates that no output parameters are set. You can attach the input to the context by calling mmr_attach_input(), specifying the location of the audio file and the type of input. Finally, you can play the file by calling mmr_play().

After you start playing the audio file, you can perform any other tasks that your application requires. When you're ready to stop playing the file and start cleaning up the renderer's resources, you can call a sequence of functions to stop the playback, detach the input from the context, destroy the context, and disconnect from the renderer. It's important to note that you may not need to call each function in this sequence, because calls that occur later in the sequence supersede earlier calls. For example, calling mmr_input_detach() also takes care of all of the operations that mmr_stop() performs. Similarly, calling mmr_context_destroy() also takes care of the operations that mmr_input_detach() and mmr_stop() perform, and so on.

Nice to know

After you start playing an audio file, you can use the audio mixer service in the BlackBerry Platform Services (BPS) library to control playback properties. For example, you can call audiomixer_set_output_level() to set the playback volume, and you can call audiomixer_toggle_output_mute() to mute or unmute the playback. Before you use these functions, make sure to initialize the BlackBerry Platform Services library by calling bps_initialize().

Last modified: 2013-12-21

comments powered by Disqus