Monthly Archives: October 2008

Bug Fix: Minim 2.0.1

While writing the example that I just posted, I discovered a couple nasty bugs that would have made a lot of people unhappy. For the curious, they were that the getChannel method was not returning the correct channel when using BufferedAudio.LEFT and BufferedAudio.RIGHT, and that stereo AudioSamples were only playing the left channel. All my tests thus far have used mono files, so that one just slipped past me. I’ve packed up a new release and updated the download page.

HOWTO: Manipulate an AudioSample in Minim 2.0

Kyle says, “Like what if I want to load up a sound and remove certain portions that fit some criteria or rearrange it (i.e., non-real-time processing)?”

What you want to do is currently possible to a certain degree using AudioSample. It now has a method called getChannel(int), which comes from the BufferedAudio interface. This method returns in a float array the actual samples being used by the object when you trigger it. You can then manipulate those values and hear the change when you trigger it.

Example (view online)

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();
}

Minim 2.0 Released!

Egged on by the Processing 1.0 team, I spent today putting together a new release of Minim, which had been languishing on my computer. The lion’s share of the work was simply updating the examples and then uploading them. I really need to automate that process, it’s a big pain. Still not done: updating the manual.

A very important change to be aware of if you are upgrading, is that the Minim class is now instantiable. All of the load and get methods have been changed to regular old member functions, rather than static on the class. The static start(PApplet) method has been removed, you must now pass your sketch into the constructor, like so:

Minim minim = new Minim(this);
AudioPlayer player = minim.loadFile("blah.wav");

A very cool addition is getMetaData() for AudioPlayer, AudioSnippet, and AudioSample. The ability to read the ID3 tags from mp3 files was always there in the package I use for playing those, but I didn’t hook it up initially. Now all the tags you probably care about get stuffed into an AudioMetaData object when you load a file. Check out the online example.

An interesting implementation change is that I’ve broken out the Javasound specific code from the generic audio abstraction layer code. This means that there is now a package called ddf.minim.spi, which defines a bunch of interfaces that Minim uses to load files and acquire inputs and outputs. The key interface is MinimServiceProvider, which looks a lot like a slimmed down version of Minim’s interface. It is now possible for you implement MinimServiceProvider and then pass an instance of your implementation into the Minim constructor. Minim will use your implementation for all audio resource acquisition. This means that the default implementation, which uses Javasound, does exactly that and lives in jsminim.jar, which is included with the distro. One of the reasons that I did this was so that I could easily write an implementation of Minim that uses an FModEx Java binding. Work has begun on that, but it is not yet finished. Still, something to look forward to!