19. Example: A Sound Effects Board

In these notes you will learn:

  • How to create a simple app that plays sound effects.

19.1. Planning the Program

As usual, it is wise to think about how we want a program to work before doing any coding. For the sake of concreteness, let’s agree to have nine different sound effects that can be played. On the screen, we’ll list the names of the effects beside a number. When the user presses the number on the keyboard, the corresponding sound effect is played.

Thinking more about the program, it soon becomes clear that we will need to:

  • Import and setup Minim for the sound effect files. Since sound effects are usually short (as compared to songs), we will load them as Minim AudioPlayer objects.
  • Create and display text. We will first need to create a font with the Processing IDE font tool, and then load it and set it within our program.

We’ve seen these things before, so here our focus is to combine them into a single program.

19.2. Getting Sound Effects

We need nine different sound effect files. Generally speaking, there are two ways to get such files: either borrow them (for example from the web), or make your own.

If you search the web for “sound effects”, you will find many websites that provide free sound effect files of varying quality. Be careful not to download files that play for too long - they take up to much memory when loaded into the program.

In you have a computer with a microphone, then it’s not too hard to create your own sound effect files. For instance, a few of the sound files in this note were recorded on a laptop. Some simple edits were made (e.g. removing leading and trailing silence) using a program called Audacity, an open-source sound editing program.

For this program, we will use a selection of borrowed WAV files. To use these in your program, download this ZIP file and unzip it into your source folder.

19.3. Creating the Program: Initializing Sound and Text

Our first step is to write the code that loads all of the sound effects files and to use keyPressed() to play the snippets.

// use Minim
import ddf.minim.*;

// setup the sound variables
Minim minim;

AudioSnippet effect1;
AudioSnippet effect2;
AudioSnippet effect3;
AudioSnippet effect4;
AudioSnippet effect5;
AudioSnippet effect6;
AudioSnippet effect7;
AudioSnippet effect8;
AudioSnippet effect9;

void setup() {
    size(500, 500);
    // load the sound effect files
    print("Loading sound effects ...");
    minim = new Minim(this);

    effect1 = minim.loadSnippet("burp.wav");
    effect2 = minim.loadSnippet("cough.wav");
    effect3 = minim.loadSnippet("explosion.wav");
    effect4 = minim.loadSnippet("elephant.wav");
    effect5 = minim.loadSnippet("kaboom.wav");
    effect6 = minim.loadSnippet("pew.wav");
    effect7 = minim.loadSnippet("gunshot.wav");
    effect8 = minim.loadSnippet("quack.wav");
    effect9 = minim.loadSnippet("squeeze-toy.wav");
    println("done");

    // ...
}

void draw() {
    // ... later
}

void keyPressed() {
    if (key == '1') {
        effect1.play(0);
        println("burp");
    } else if (key == '2') {
        effect2.play(0);
        println("cough");
    } else if (key == '3') {
        effect3.play(0);
        println("explosion");
    } else if (key == '4') {
        effect4.play(0);
        println("elephant");
    } else if (key == '5') {
        effect5.play(0);
        println("kaboom");
    } else if (key == '6') {
        effect6.play(0);
        println("pew");
    } else if (key == '7') {
        effect7.play(0);
        println("gunshot");
    } else if (key == '8') {
        effect8.play(0);
        println("quack");
    } else if (key == '9') {
        effect9.play(0);
        println("squeeze toy");
    }
}

Notice that we use println to write the name of sound effect to the console. This is useful if for some reason the sound on your computer isn’t working: it gives visual feedback about which effect has been played.

Note

There is another way to write the long if-else-if statement inside keyPressed(), which is a little simpler. This is known as a switch statement:

switch(key) {
case '1':
    effect1.play(0);
    println("burp");
    break;
case '2':
    effect2.play(0);
    println("cough");
    break;
case '3':
    effect3.play(0);
    println("explosion");
    break;
case '4':
    effect4.play(0);
    println("elephant");
    break;
case '5':
    effect5.play(0);
    println("kaboom");
    break;
case '6':
    effect6.play(0);
    println("pew");
    break;
case '7':
    effect7.play(0);
    println("gunshot");
    break;
case '8':
    effect8.play(0);
    println("quack");
    break;
case '9':
    effect9.play(0);
    println("squeeze toy");
    break;
}

Some programmers find switch statements to be more readable than the equivalent if-statements and so you will occasionally see them in Processing (and Java) programs.

However, switch does not work quite like other Processing statements, and this can lead to confusion. For instance, notice that switch does not use code blocks to group the different cases. Instead it uses a special break statement. Further switches are desinged to work with primitive types only, so their usefulness is limited.

Because of this, we won’t be using switch statements in any of the programs for this course.

The next step is to create an interface on the screen for the sound board. Creating good interfaces is quite challenging, and so we will aim for simplicity and just display a list of options with the number beside them:

// .. other globals
PFont font;

void setup() {

    // .. earlier code
    // setup font.
    font = loadFont("JCHEadA-48.vlw");
    textFont(font);
}

void draw() {
    background(255);
    // draw effect names on the screen
    fill(0);
    float textY = 5 + textAscent();
    text("1. burp", 10, textY);
    text("2. cough", 10, 2*textY);
    text("3. explosion", 10, 3*textY);
    text("4. elephant", 10, 4*textY);
    text("5. kaboom", 10, 5*textY);
    text("6. pew", 10, 6*textY);
    text("7. gunshot", 10, 7*textY);
    text("8. quack", 10, 8*textY);
    text("9. squeeze toy", 10, 9*textY);
}

Note

Good interfaces are difficult to create in part because different sorts of interfaces are better suited for different sorts of problems, and different users have different personal preferences. So it is usually hard, or even impossible, to create an interface that works perfectly for all users in all situations. Of course, this doesn’t mean we shouldn’t try!

19.4. Programming Questions

  1. Modify the program in the notes so that whenever the user presses a sound effect number, the corresponding on-screen text changes its colour. The colour change should be just a brief flash, but clearly noticeable.