KISA 2 - Controlling the audio player with play, pause, and stop



In addition to displaying information about the file being played, a PJS sketch can control several audio operations. We will start with the most obvious: play, pause, and stop.

To accomplish this we need a way for the user to interact with the sketch. A very simple (remember the meaning of KISA) circular button class will be used (CircleButton.pde). In addition to a constructor, it has methods to detect if the mouse is over the button's circle and a draw method.

In order to use the CircleButton.pde, it must be included in the <canvas ..> tag in the "data-processing-sources" attribute:

 10     <canvas id="KISA" data-processing-sources="KISA2.pde CircleButton.pde"></canvas>

The required buttons are declared globally in line 20 of the .pde file, created in lines 32-34, and drawn in lines 52-54:

 20  CircleButton playBtn, pauseBtn, stopBtn;
...
 32    playBtn = new CircleButton(130, 145,"Play");
 33    pauseBtn = new CircleButton(230, 145, "Pause");
 34    stopBtn = new CircleButton(330, 145, "Stop");
...
 52    playBtn.draw();
 53    pauseBtn.draw();
 54    stopBtn.draw();

What is left is to add a mouseClicked function in lines 107 - 117:

107  void mouseClicked() {
108    // Mouse clicked event processing
109    var v, t;
110    if (playBtn.isOver()) {
111      audio.play();
112    } else if (pauseBtn.isOver()) {
113      audio.pause();
114    } else if (stopBtn.isOver()) {
115      stop();
116    }
117  }

If the mouse is clicked when the it over the "Play" or "Pause" buttons, the audio player is told to play or pause. When the "Stop", is clicked, the stop function (lines 68 - 74) is called:

107  void mouseClicked() {
108    // Mouse clicked event processing
109    var v, t;
110    if (playBtn.isOver()) {
111      audio.play();
112    } else if (pauseBtn.isOver()) {
113      audio.pause();
114    } else if (stopBtn.isOver()) {
115      stop();
116    }
117  }

A function was used for the stop operation because it is somewhat more complicated. Recall that the KISA 1 tutorial mentioned that the way to stop the audio player playback is to pause it and set the current time to 0. The variable audioStatus is also set. The status gets set automatically when the play and pause events occur.

 68  void stop() {
 69    // Called stop playing the file by pausing it and setting the
 70    // time back to 0;
 71    audio.pause();
 72    audio.currentTime = 0;
 73    audioStatus = "Stopped";
 74  }

Setting the current time to 0 in the stop function stops playback but does not necessarily stop downloading the file. Some sources recommend replacing line 72 by:

         audio.setAttribute("src", "");

Clearing the source file will stop the download if it has not already been completed.

When you run the player, notice that whether you start the sounds from the sketch or the HTML 5 control, the values in the sketch and the control are the same. (Well almost, the sketch rounds numerical values while the control probably truncates them.)

In the next tutorial, setting the volume and position in the file will be discussed along with showing how to change the audio file being played. Then we will have full featured (even if simple minded) audio player.

< Previous     Next >

[+/-] The KISA2.html file

  1  <!DOCTYPE html>  
  2  <html>
  3  <head>
  4    <title>KISA 2 (Keep It Simple Audio)</title>
  5    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  6    <script type="text/javascript" src="processing.min.js"></script>
  7  </head>
  8  <body>
  9     <h1>Keep It Simple Audio 2</h1>
 10     <canvas id="KISA" data-processing-sources="KISA2.pde CircleButton.pde"></canvas>
 11     <br />
 12     <audio  id="audiotag"  preload="auto" controls="controls" >
 13       Your browser does not support HTML 5 audio.  You may want to update your
 14       browser to a current version. 
 15    </audio>  
 16  </body>
 17  </html>
    

[+/-] The KISA2.pde file

  1  // KISA 
  2  // Keep It Simple Audio version 2
  3  // James Brink  brinkje@plu.edu
  4  // 3/7/12 4/12/12
  5  
  6  // The constants can be modified.
  7  int width = 500;  // Width of canvas
  8  int height = 290; // Height of canvas
  9  // It is assumed that both .ogg and .mp3 versions of the files are available
 10  // in the same folder.  The file names must be complete URLs except for the
 11  // ending .ogg or .mp3 which must be omitted. It will be added as needed for
 12  // the browser.  Use the prefix "file:///" or "http:// as appropriate.
 13  String file1 = "http://brinkje.com/KISA_Sounds/groove";
 14  
 15  // Global variables
 16  Audio audio = document.getElementById("audiotag");
 17  
 18  int time;
 19  String audioStatus;
 20  CircleButton playBtn, pauseBtn, stopBtn;
 21  void setup() {
 22    // Setup the sketch
 23    size(width, height);
 24    smooth();
 25    frameRate(20);
 26    audio.addEventListener("loadstart", loadStart, false);
 27    audio.addEventListener("playing", playing, false);
 28    audio.addEventListener("pause", pause, false);
 29    audio.addEventListener("ended", ended, false);
 30    audio.addEventListener("error", error, false);
 31  
 32    playBtn = new CircleButton(130, 145,"Play");
 33    pauseBtn = new CircleButton(230, 145, "Pause");
 34    stopBtn = new CircleButton(330, 145, "Stop");
 35    audioStatus = "";
 36    setSource(file1);
 37  } // setup
 38  
 39  void draw() {
 40    // Draws the sketch on the canvas
 41    background(#FFFFAA);
 42  
 43    fill(#000000);
 44    textAlign(CENTER);
 45    text("KISA 2", width/2, 30);
 46    text("Source file: " + audio.src, width/2, 60);
 47    text("Status: " + audioStatus, width/2, 75);
 48    text("Current time: " + round(audio.currentTime)
 49         + " sec.   Length: " + round(audio.duration)+ " sec.", width/2, 90);        
 50    text("Volume (0 to 1): " + round(10 * audio.volume)/10, width/2, 105);
 51  
 52    playBtn.draw();
 53    pauseBtn.draw();
 54    stopBtn.draw();
 55  }
 56  
 57  void setSource(String url ) {
 58    // Called to set the source file.  Do not include the file extension
 59    // in the url.  It will be added here.
 60    if (audio.canPlayType && audio.canPlayType("audio/mpeg")) {
 61      audio.setAttribute("src", url + ".mp3");
 62    } else {
 63      audio.setAttribute("src", url + ".ogg");
 64    }
 65    audioStatus = "File selected";
 66  }
 67  
 68  void stop() {
 69    // Called stop playing the file by pausing it and setting the
 70    // time back to 0;
 71    audio.pause();
 72    audio.currentTime = 0;
 73    audioStatus = "Stopped";
 74  }
 75  
 76  void loadStart() {
 77    // LoadStart event processing
 78    audioStatus = "Loading";
 79  }
 80  
 81  void playing() {
 82    // Playing event processing
 83    audioStatus = "Playing";
 84  }
 85  
 86  void pause() {
 87    // Pause event processing.
 88    // There is no stop event but a "stop" causes a pause.  This
 89    // method checks to see if the current time = 0. If so it assumes
 90    // stopped
 91    if (audio.currentTime == 0)
 92      audioStatus = "Stopped";
 93    else
 94      audioStatus = "Paused";
 95  }
 96  
 97  void ended() {
 98    // Ending event processing
 99    audioStatus = "Finished playing";
100  }
101  
102  void error() {
103    // error event processing
104    audioStatus = "Error";
105  }
106  
107  void mouseClicked() {
108    // Mouse clicked event processing
109    var v, t;
110    if (playBtn.isOver()) {
111      audio.play();
112    } else if (pauseBtn.isOver()) {
113      audio.pause();
114    } else if (stopBtn.isOver()) {
115      stop();
116    }
117  }
    

[+/-] The CircleButton.pde file

  1  class CircleButton {
  2    // Used to draw labeled button
  3    int centerX, centerY;
  4    String label;
  5    int radius = 9;
  6    int diameter;
  7    color col = #0000FF;
  8    CircleButton(int centerXX, int centerYY, String labelL) {
  9      // Constructor (centerXX, centerYY) is the center of the circle.
 10      // labelL is the button's label shown on its right.
 11      centerX = centerXX;
 12      centerY = centerYY;
 13      label = labelL
 14      ellipseMode(CENTER);
 15      diameter = 2 * radius;
 16    }
 17  
 18    boolean isOver() {
 19      // Determines the mouse is over the circle.
 20      return sq(mouseX - centerX) + sq(mouseY - centerY) <= sq(radius);
 21    }
 22  
 23    void draw() {
 24      // Draws the circle button with its labelon the right
 25      fill(col);
 26      ellipse(centerX, centerY, diameter, diameter);
 27      fill(0);
 28      textAlign(CORNER);
 29      text(label, centerX + radius + 5, centerY + 5);
 30    }
 31  
 32    void setLabel(String s) {
 33      label = s;
 34    }
 35  
 36  }  // end of CircleButton class
    

Updated 11/6/14