Manual: AudioSample

[ javadoc | examples ]

AudioSample can be thought of like a sample in a drum machine. It is meant to be used for short sounds that simply need to be triggered and then forgotten about. An example of this might be all of the sound effects for a space shooter game. When you load an audio file using loadSample the audio will be loaded completely into memory and then triggered from there.

Code Sample (online example)

/**
  * This sketch demonstrates how to use the <code>trigger</code> method of an <code>AudioSample</code>. <br />
  * <code>AudioSample</code>s can only be triggered, not cue'd and looped
  * or anything else you might do with an <code>Playable</code> object. The advantage, however, is that 
  * an <code>AudioSample</code> can be retriggered while it is still playing, which will cause the sample to 
  * overlap with itself.
  * <p>
  * Use 'k' and 's' to trigger a kick drum sample and a snare sample, respectively. You will see their waveforms
  * drawn when they are played back.
  */
 
import ddf.minim.*;
 
Minim minim;
AudioSample kick;
AudioSample snare;
 
void setup()
{
  size(512, 200, P3D);
  minim = new Minim(this);
  // load BD.wav from the data folder
  kick = minim.loadSample("BD.mp3", 2048);
  if ( kick == null ) println("Didn't get kick!");
  // load SD.wav from the data folder
  snare = minim.loadSample("SD.wav", 2048);
  if ( snare == null ) println("Didn't get snare!");
}
 
void draw()
{
  background(0);
  stroke(255);
  // use the mix buffer to draw the waveforms.
  for (int i = 0; i < kick.bufferSize() - 1; i++)
  {
    float x1 = map(i, 0, kick.bufferSize(), 0, width);
    float x2 = map(i+1, 0, kick.bufferSize(), 0, width);
    line(x1, 50 - kick.mix.get(i)*50, x2, 50 - kick.mix.get(i+1)*50);
    line(x1, 150 - snare.mix.get(i)*50, x2, 150 - snare.mix.get(i+1)*50);
  }
}
 
void keyPressed()
{
  if ( key == 's' ) snare.trigger();
  if ( key == 'k' ) kick.trigger();
}
 
void stop()
{
  // always close Minim audio classes when you are done with them
  kick.close();
  snare.close();
  minim.stop();
 
  super.stop();
}

Sample Access

AudioSample is similar to AudioSnippet because all of the audio is loaded into memory. However, unlike AudioSnippet the audio is stored in memory as normalized floats so that the samples can be made available to the user. You can get a channel of audio from an AudioSample as a float array by using getChannel and passing in BufferedAudio.LEFT or BufferedAudio.RIGHT. This method will give you the actual samples used for playback, so you can modify the samples, as shown in the example below. The change will be heard the next time you trigger the sample. One current limitation is that you can’t change the length of the array, however support for that will probably be provided in a future release.

Code Sample (online example)

/**
  * This sketch demonstrates how to get a channel of audio from an AudioSample and then manipulate it to change the AudioSample after it
  * has been loaded. 
  */
 
import ddf.minim.*;
 
Minim minim;
AudioSample jingle;
 
void setup()
{
  size(512, 200, P3D);
 
  minim = new Minim(this);
 
  jingle = minim.loadSample("jingle.mp3", 2048);
  // get the left channel of the audio as a float array
  // getChannel is defined in the interface BuffereAudio, 
  // which also defines two constants to use as an argument
  // BufferedAudio.LEFT and BufferedAudio.RIGHT
  float[] leftChannel = jingle.getChannel(BufferedAudio.LEFT);
  // now we are just going to reverse the left channel
  float[] reversed = reverse(leftChannel);
  arraycopy(reversed, 0, leftChannel, 0, leftChannel.length);
}
 
void draw()
{
  background(0);
  stroke(255);
  for(int i = 0; i < jingle.bufferSize() - 1; i++)
  {
    line(i, 50 - jingle.left.get(i)*50, i+1, 50 - jingle.left.get(i+1)*50);
    line(i, 150 - jingle.right.get(i)*50, i+1, 150 - jingle.right.get(i+1)*50);
  }
}
 
void keyPressed()
{
  jingle.trigger();
}
 
void stop()
{
  // always close Minim audio classes when you finish with them
  jingle.close();
  minim.stop();
 
  super.stop();
}

Sample Info

You can find out how long an AudioSample is in milliseconds by calling length(). However, AudioSample also allows you to get an AudioMetaData by calling getMetaData(), which will also allow you to access the length of the sample.

Other Controls

AudioSample derives from AudioSource, this is where it gets its Recordable and Effectable interfaces from. AudioSource derives from Controller and as such AudioSample has all of its methods available, which are described in the section about Controller.

9 thoughts on “Manual: AudioSample

  1. Is there a way to load more than 32 audio samples? It seems as though the trigger method fails if you have more than 32 samples loaded into memory. The first set of 32 samples work fine; the second set of 32 samples will not play. Older versions of Processing would allow for this… but I can’t seem to make it work using a newer version of Processing.

  2. You should be able to, but I’m not surprised you’re finding strange behavior with that many. Behind the scenes, each AudioSample has its own output that is running in its own thread. The was the most straightforward thing to implement, so it’s what I went with. However, having large number of threads running in your app can become problematic, so it wasn’t really the best implementation choice. I will probably rework it so that AudioSamples that have the same AudioFormat and buffer size will share an output, but don’t expect to see that any time soon. In the meantime, if you don’t absolutely need the trigger() functionality, you could load your files into FilePlayer objects and patch them all to the same AudioOutput. Then you’d have only one audio processing thread running and you shouldn’t find yourself with the same 32 sample limitation.

    Here’s an example of how you load a file into a FilePlayer and patch it to an AudioOutput (you’ll need to use the current beta build to be able to do this):

    Minim minim;
    AudioOutput mainOut;
    
    FilePlayer player;
    
    void setup()
    {
      minim = new Minim(this);
      mainOut = minim.getLineOut();
      
      // 1024 is a buffer size.
      // true means that the file will be loaded into memory,
      // which is what you want if you're going to be constantly playing it from the beginning
      player = new FilePlayer( minim.loadFileStream( "your_sample.wav", 1024, true )  );
      player.patch( mainOut );
    }
    
    void triggerPlayer()
    {
      // starts player playing back from the beginning
      // you'd use this in place of the trigger() method from AudioSample
      player.play(0);
    }
    
  3. Thank you very much! This worked perfectly. I really appreciate all of your help – I needed to get this working for a piece that’s currently being exhibited in an art gallery. Thanks again!

  4. Hi there, I am quite new to processing. I was just wondering if there is a way to generate random Audio Sample using a mousePressed? e.g. I have 9 different Audio Samples and a mousePressed function, and would like to use the random function as well so that each time the mouse is pressed 1 out of 9 of the Audio Sample would play randomly.

    Would be lovely to hear some feedback.

  5. This is a great question for the Processing forum: http://forum.processing.org/

    But, what you’ve described is relatively simple, so try this: create an array of 9 AudioSample objects. Load a different sample into each one. When the mouse is pressed, use the random function to generate a number between 0 and 8 (remember that arrays are 0 based) and use the int function to turn that generated number into an int that you can index into the array with. Your code might look something like this:

    void mousePressed()
    {
      int index = int( random(0,8) );
      sampleArray[index].trigger();
    }
    

    Good luck!

  6. cheerio,

    I need to set my sample back to 0. something like player.play(0) or rewind or something….jsut for audioSample.

    Need to use audioSample since audioPlayer has a pretty bad latency if you’re trying to synchronize samples.

    is there something like loop(), rewind(), or play(0)?

    thanks in advance

  7. @jbonez No, AudioSample is not designed to work that way. It is meant to be a fire-and-forget method of playing a short sound. Calling trigger() is essentially the same as calling play(0) on an AudioPlayer, but as I’m sure you’re aware, it won’t halt the playback of previous trigger calls.

  8. Pingback: Minim Sound abspielen « processing – tutorial

Comments are closed.