Artekit PropBoard: Audio API


Audio on the PropBoard

Audio on the PropBoard is very easy to use and is accessed through a series of classes that we document here. From now on, we refer to these classes as the Audio module.

The PropBoard Audio module currently supports playing WAV and RAW (PCM) files at several sampling frequencies and 16-bit bit depth. Many different sound files can played at the same time (quantity depends on audio format and processor load) and they are automatically mixed in real time.

Basically the Audio module is managed through the Audio object and is initialized by calling Audio.begin(). This is the only function you need to call to enable audio output.

The class dedicated to playing WAV files is the WavPlayer class. A series of advanced classes and methods can also be found in the PropBoard API: Advanced Audio document.

About audio formats

At the current version, the PropBoard software supports playing samples at 22050Hz, 32000Hz, 44100Hz, 48000Hz and 96000Hz sampling frequencies and 16-bit bit depth. The audio format is specified when initializing the Audio module through the Audio.begin() function.

The current Audio module implementation does not have a sampling rate or bit depth converter, so any attempt to play an audio file that has not the same sampling frequency and bit depth as specified to the Audio.begin() function will fail. The quantity of channels (mono/stereo) is not important.

This means that you can play (and mix) a mono, 16-bit, 22050fs WAV together with a stereo 16-bit, 22050fs WAV, but you can’t play a mono, 16-bit, 22050fs WAV together with a stereo 16-bit, 48000fs WAV.

As a rule of thumb, check that your audio files have the same sampling frequency and the same sample bit depth.

Audio object

class PropAudio;
PropAudio Audio;

The Audio object is responsible for audio initialization, mixing, output, and volume control. The object is already instantiated when the program begins.

Audio.begin

Call the Audio.begin() function to initialize audio. This is the sole function you need to call before playing any sound file.

Syntax

bool begin(uint32_t fs = 22050, uint8_t bps = 16);

Parameters

The fs parameter is the sampling frequency (for example 22050) and bps is the bit depth or bits-per-sample (for example 16).

The possible values for the fs parameter are:

  • 22050
  • 32000
  • 44100
  • 48000
  • 96000

The possible value for the bps parameter is:

  • 16

If the function is called without parameters it will initialize audio with a 22050Hz sampling frequency and 16-bit bit depth.

Returns

The function returns true if Audio was successfully initialized, false otherwise.

Examples

void setup()
{
    Audio.begin(); // 22050Hz sampling frequency and 16-bit bit depth
}

The following code will initialize the audio for a 48000Hz sampling frequency and 16-bit bit depth:

void setup()
{
    Audio.begin(48000, 16); // 48000Hz sampling frequency and 16-bit bit depth
}

Notes

Remember that from the moment Audio.begin() is called, all the audio files and/or samples must respect the sampling frequency and bit depth that was passed to the Audio.begin() function. The Audio module does not do any distinction regarding quantity of channels (mono/stereo).

Audio.end

Call Audio.end() to de-initialize the Audio module. Audio output is terminated and to play audio the Audio.begin() function must be called again.

Syntax

void end();

Parameters

None.

Returns

None.

Audio.setVolume

Call the Audio.setVolume() function to set the audio output volume. The volume is directly managed by the I2S codec, so audio volume does not have any impact in regards of computing power.

Syntax

bool setVolume(float decibels = 0);

Parameters

The decibels parameters is the volume in decibels. You can increase the volume up to a maximum 12db or decrease the volume down to a minimum of -100db.

Returns

The function returns true on success, false otherwise.

Notes

By default, the Audio module is initialized at 0db when the Audio.begin() function is called.

Audio.mute / Audio.unmute

Use the Audio.mute() function to mute the audio output and Audio.unmute() to restore it.

Syntax

bool mute();
bool unmute();

Parameters

None.

Returns

The functions return true on success, false otherwise.

WavPlayer Class

class WavPlayer : public RawPlayer

The WavPlayer class is used to play a WAV file from the microSD card. You can create a WavPlayer object by simply calling:

WavPlayer myWavPlayer; // Create a WavPlayer object

void setup()
{
    // My program goes here

You can create several WavPlayer objects. It is wise to create them accordingly on how many WAV files you need to play at the same time. If you are not playing overlapping WAV files you can re-utilize the same WavPlayer object to play different WAV files at different moments.

Plan ahead in a way that you can save resources by re-utilizing the same WavPlayer objects.

For example, let’s imagine a lightsaber prop that needs to mix a background hum sound together with another overlapping sound (swing, hit, blaster). For example:

WavPlayer myHumSound; // To play a background hum sound
WavPlayer myFxSound; // To play any other sound on top of the hum sound

void setup()
{
    // Initialize Audio
    Audio.begin();

    // Use myHumSound to play a background hum in loop mode
    myHumSound.play("hum.wav", PlayModeLoop);
}

void loop()
{
    // Detect hit condition
    if (on_hit)
    {
        // Play hit.wav
        myFxSound.play("hit.wav");
    } else if (on_swing)
    {
        // Swing detected. Play swing.wav
        myFxSound.play("swing.wav");
    }
}

In above case we create and use myHumSound to play the background hum sound and reuse the myFxSound object to play any other WAV file that overlaps with the hum sound but does not overlap with each other.

WavPlayer::play

Call WavPlayer::play to play a WAV file from the microSD card.

Syntax

bool play(const char* filename, PlayMode mode = PlayModeNormal);

Parameters

The filename parameter is a string that indicates the WAV file to play.

The mode parameter indicates the playback mode and can be one of the following values:

  • PlayModeNormal: the WAV file is played once
  • PlayModeLoop: the WAV file is played in loop mode. Once it finishes, it will start playing again
  • PlayModeBlocking: the WAV file is played once and the function returns after the WAV file is done playing

If the mode parameter is omitted, it is defaulted to PlayModeNormal.

Returns

The function returns true on success, false otherwise.

Notes

Playing a WAV file happens asynchronously (unless PlayModeBlocking is specified). This means that the function returns immediately and your program keeps running.

If the WavPlayer object was already playing a WAV file when WavPlayer::play is called, the previous WAV file playback is stopped.

Example

WavPlayer mySound;
WavPlayer myOtherSound;

void setup()
{
    Audio.begin();

    // Play music in loop mode
    mySound.play("music.wav", PlayModeLoop);

    // Play boom.wav (that's inside the folder 'sounds') in blocking mode
    myOtherSound.play("sounds/boom.wav", PlayModeBlocking);

    // After boom.wav is done playing, play roar.wav
    myOtherSound.play("roar.wav"); // Normal mode

    // Program continues ...

WavPlayer::playRandom

Call WavPlayer::playRandom to play a random WAV file from the microSD. This function randomly chooses a file that has the format nameX.WAV where the name part is the filename parameter and the X part is a random number between the min and max parameters.

When this function is called, a random number between min and max is chosen and it is appended to filename.

Syntax

bool playRandom(const char* filename, uint32_t min, uint32_t max, PlayMode mode = PlayModeNormal);

Parameters

The filename parameter is a string that indicates the WAV file to play without extension.

The min parameter is the minimum possible number that will be appended to the filename parameter, for example 0.

The max parameter is the maximum possible number that will be appended to the filename parameter, for example 10.

The mode parameter indicates the mode and can be one of the following values:

  • PlayModeNormal: the WAV file is played once
  • PlayModeLoop: the WAV file is played in loop mode. Once it finishes, it will start playing again
  • PlayModeBlocking: the WAV file is played once and the function returns after the WAV file is done playing

If the mode parameter is omitted, it is defaulted to PlayModeNormal.

Returns

The function returns true on success, false otherwise.

Notes

Playing a WAV file happens asynchronously (unless PlayModeBlocking is specified). This means that the function returns immediately and your program keeps running.

If the WavPlayer object was already playing a WAV file when WavPlayer::playRandom is called, the previous WAV file playback is stopped.

Example

Let’s say you have a group of WAV files that are named from sound0.WAV to sound20.WAV and you want to pick a random file among them. In that case you can use:

WavPlayer mySound;

void setup()
{
    Audio.begin();

    // Play a random sound between sound0.WAV and sound20.WAV
    // Note that the code here below doesn't specify the .WAV extension
    mySound.playRandom("sound", 0, 20); 
    
    // Program continues

Now let’s imagine that the WAV files are located inside a folder named font1. In that case the code would be:

WavPlayer mySound;

void setup()
{
    Audio.begin();

    // Play a random sound between sound0.WAV and sound20.WAV
    // Note that the code here below doesn't specify the .WAV extension
    mySound.playRandom("font1/sound", 0, 20);

    // Program continues

WavPlayer::stop

Use the WavPlayer::stop function to stop playing a WAV file. The corresponding WAV file is closed and. To play the same file (or other file) you need to call the WavPlayer::play function again.

Syntax

bool stop();

Parameters

None.

Returns

The function returns true on success, false otherwise.

Example

WavPlayer myHumSound; // To play a background hum sound

void setup()
{
    // Initialize Audio
    Audio.begin();

    // Use myHumSound to play a background hum in loop mode
    myHumSound.play("hum.wav", PlayModeLoop);
}

void loop()
{
    // Detect power off condition
    if (do_power_off)
    {
        // Stop playing the hum sound
        myFxSound.stop();

        do_power_off = false;
    }
}

WavPlayer::pause

Call the WavPlayer::pause function to pause the playback of an audio file. Call WavPlayer::resume to resume playback.

Syntax

bool pause();

Parameters

None.

Returns

The function returns true on success. If the playback is already paused or stopped the function returns false.

Example

WavPlayer myHumSound; // To play a background hum sound

void setup()
{
    // Initialize Audio
    Audio.begin();

    // Use myHumSound to play a background hum in loop mode
    myHumSound.play("hum.wav", PlayModeLoop);

    // Wait 1 second
    delay(1000);

    // Pause playback
    myHumSound.pause();

    // Pause 1 second
    delay(1000);

    // Resume playback
    myHumSound.resume();
}

WavPlayer::resume

The WavPlayer::resume function resumes the playback of a WAV file previously paused with WavPlayer::pause.

Syntax

void resume();

Parameters

None.

Returns

The function returns true on success. If the playback is already playing or stopped the function returns false.

Example

See the example for WavPlayer::pause.