Learning 12: Audio library and control

This page describes the Perlenspiel audio library, together with the commands for loading, playing, pausing and stopping sounds.

 

Audio library

Perlenspiel includes a built-in audio library containing nearly 400 sounds, including a full range of piano, harpsichord and xylophone notes, dozens of percussion instruments, and sound effects ranging from simple to silly.

A complete list of all library sounds is available here.

Each sound is identified by a unique lower-case string. For example, the string "fx_click" identifies a simple click effect. These strings are used in the filename parameter of the PS.audioLoad() and PS.audioLoad() commands (explained below) to specify which sound should be played.

 

PS.audioLoad ( filename, options )

The sounds in the Perlenspiel audio library are stored on an Internet server, and can take a few moments to load if there's a lot of network traffic. The PS.audioLoad() command lets you preload an audio file from the server, making it available for immediate playback later, when you need it.

The filename parameter should be a case-sensitive string matching the filename of the audio to be played, without a path specifier or file extension (example: "fx_click"). By default, the file is assumed to reside in the Perlenspiel Audio Library. Note that library filenames are all lower-case.

SAMPLE CALL:

PS.audioLoad( "fx_click" );

The options parameter provides additional capabilities that will be explained in the Advanced audio section.

Usage notes

1. If you know your project will use a particular sound frequently, calling PS.audioLoad() in your PS.init() function will help to insure that the sound is available on demand.

Demonstration

See PS.audioStop() below for a demonstration that uses PS.audioLoad() to preload sounds.

Return value

PS.audioLoad() returns a string uniquely identifying the channel assigned to the sound. This identifier can be used for subsequent calls to PS.audioPause() and PS.audioStop().

PS.ERROR is returned if an error occurs.

 

PS.audioPlay ( filename, options )

The PS.audioPlay() command begins playback of a specified sound.

The filename parameter should be a case-sensitive string matching the filename of the audio to be played, without a path specifier or file extension (example: "fx_click"). By default, the file is assumed to reside in the Perlenspiel Audio Library. Note that library filenames are all lower-case.

SAMPLE CALL:

PS.audioPlay( "fx_click" );

The options parameter provides additional capabilities that will be explained in the Advanced audio section.

Demonstration

See PS.audioStop() below for a demonstration that uses PS.audioPlay() to play sounds.

Return value

PS.audioPlay() returns a string uniquely identifying the channel assigned to the sound. This identifier can be used for subsequent calls to PS.audioPause() and PS.audioStop().

PS.ERROR is returned if an error occurs.

 

PS.audioPause( channel )

The PS.audioPause() command lets you pause and restart sounds that were previously started with a call PS.audioPlay().

The channel parameter should be a channel identifier previously returned by a call to PS.audioPlay() or PS.audioPause().

If channel is playing, it will pause immediately. If channel is already paused as a result of a previous call to PS.audioPause(), it resumes playing at the point from which it was paused.

If channel is not playing, paused, stopped or invalid, nothing happens.

SAMPLE CALL:

var channel;

channel = PS.audioPlay( "fx_click" ); // start playback

// After playback has started

channel = PS.audioPause( channel ); // pause it

// After sound is paused

channel = PS.audioPause( channel ); // restart it

Demonstration

See PS.audioStop() below for a demonstration that uses PS.audioPause() to pause and unpause sounds.

Return value

PS.audioPause() returns a string uniquely identifying the channel that was paused. This identifier can be used for subsequent calls to PS.audioPause() and PS.audioStop().

Important!

The channel identifier returned by PS.audioPause() may not be the same as the one passed in its channel parameter! Be sure to save this identifier for subsequent audio calls, as the original channel may no longer be valid.

PS.ERROR is returned if an error occurs.

 

PS.audioStop ( channel )

The channel parameter should be a channel identifier previously returned by a call to PS.audioPlay() or PS.audioPause().

If channel is playing, it stops immediately.

If channel is not playing, paused, already stopped or invalid, nothing happens.

SAMPLE CALL:

var channel;

channel = PS.audioPlay( "fx_click" ); // start playback

// After playback has started

channel = PS.audioStop( channel ); // stop it

Demonstration

This demo creates an 8x3 grid representing one octave of piano notes. The top beads play a note, the middle beads pause/unpause a note in progress, and the bottom beads stop playback.

[Run Demo]

PS.init = function( system, options ) {
 var notes, letters, colors, x, n, obj;

 // Array of note names

 notes = [
 "l_piano_c4", "l_piano_d4", "l_piano_e4",
 "l_piano_f4", "l_piano_g4", "l_piano_a4",
 "l_piano_b4", "l_piano_c5"
 ];

 // Array of note letters

 letters = [ "C", "D", "E", "F", "G", "A", "B", "C" ];

 // Array of note colors

 colors = [
 PS.COLOR_RED, PS.COLOR_ORANGE,
 0xE0E000, // dark yellow
 PS.COLOR_GREEN, PS.COLOR_BLUE, PS.COLOR_INDIGO,
 PS.COLOR_VIOLET, PS.COLOR_RED
 ];

 PS.gridSize( 8, 3 ); // set up grid
 PS.borderColor( PS.ALL, PS.ALL, PS.COLOR_BLACK );
 PS.scale( PS.ALL, PS.ALL, 90 ); // scale down
 PS.radius( PS.ALL, PS.ALL, 50 ); // circle

 // Color top row of glyphs

 PS.glyphColor( PS.ALL, 0, PS.COLOR_WHITE );

 // Add pause/stop symbols to bottom rows

 PS.glyph( PS.ALL, 1, 0x20DF ); // Unicode pause
 PS.glyph( PS.ALL, 2, 0x25FC ); // Unicode stop

 // Set up note glyphs and colors,
 // preload the eight note sounds and
 // initialize note data

 for ( x = 0; x < 8; x += 1 ) {
 PS.color( x, 0, colors[ x ] ); // note color
 PS.glyph( x, 0, letters[ x ] ); // note letter

 n = notes[ x ]; // get a note name
 PS.audioLoad( n ); // preload it

 // Save an object in each bead's data
 // with note name, play/pause status
 // and channel identifier

 obj = {
 note : n, // note name
 playing : false, // play status
 paused : false, // pause status
 channel : null // channel id
 };

 PS.data( x, 0, obj ); // same object
 PS.data( x, 1, obj ); // stored in
 PS.data( x, 2, obj ); // all related beads
 }
};

PS.touch = function( x, y, data, options ) {
 // Pressed play

 if ( y === 0 ) {
 data.playing = true;
 data.paused = false;
 data.channel = PS.audioPlay( data.note );
 PS.glyphColor( x, y, PS.COLOR_GREEN );
 }

 // Pressed pause

 else if ( y === 1 ) {
 if ( data.playing ) {
 data.playing = false;
 data.paused = true;
 data.channel = PS.audioPause( data.channel );
 }
 else if ( data.paused ) {
 data.playing = true;
 data.paused = false;
 data.channel = PS.audioPause( data.channel );
 }
 PS.glyphColor( x, y, PS.COLOR_YELLOW );
 }

 // Pressed stop

 else {
 if ( data.channel ) {
 PS.audioStop( data.channel );
 }
 data.playing = false;
 data.paused = false;
 data.channel = null;
 PS.glyphColor( x, y, PS.COLOR_RED );
 }
};

PS.release = function( x, y, data, options ) {
 PS.glyphColor( x, y, PS.COLOR_WHITE );
};

PS.enter = function( x, y, data, options ) {
 if ( y > 0 ) {
 PS.color( x, y, PS.COLOR_BLACK );
 PS.glyphColor( x, y, PS.COLOR_WHITE );
 }
};

PS.exit = function( x, y, data, options ) {
 if ( y === 0 ) {
 PS.glyphColor( x, y, PS.COLOR_WHITE );
 }
 else {
 PS.color( x, y, PS.COLOR_WHITE );
 PS.glyphColor( x, y, PS.COLOR_BLACK );
 }
};

Return value

PS.audioStop() returns PS.DONE on successful completion, otherwise PS.ERROR.

 

Terms to know

Next: Coding strategies