Java

You are currently browsing the archive for the Java category.

I’m working on a music app that involves using Midi to trigger audio. Yesterday I wound up in a situation where after adding a new Track to my Sequence, I wasn’t receiving any of the MidiEvents that I added to the track. The problem, it turns out, is that the default Java Sequencer appears to cache all of the Tracks in a Sequence when you initially set the Sequence on the Sequencer using the setSequence method. If you modify the Sequence itself, as opposed to modifying the contents of the Tracks in the Sequence, the Sequencer won’t know about it until you call setSequence again. Just thought I’d throw this little tidbit out there, in case someone else runs into the same problem. Here’s some code to illustrate my point:

// make a sequence
Sequence s = new Sequence(Sequence.PPQ, 4);
 
// make a track in the sequence
Track t = s.createTrack();
 
// add midi events to the track
// ...
 
// make a sequencer
Sequencer seq = MidiSystem.getSequencer();
seq.open();
seq.setSequence(s);
seq.start();
 
// at this point, we can modify the Track
// and the Sequencer will pick up those new notes
// but if we do this:
Track t2 = s.createTrack();
// and then add notes to this track
// the Sequencer will NOT play these notes
// because it doesn't know about the track we just created
// we have to SET THE SEQUENCE AGAIN!
seq.setSequence(s);
// now the sequencer will play the notes in the track we just created.

Tags: , ,

Reas kicked me in the ass (via e-mail), so I updated the Minim Manual to reflect the Minim 2.0 API. I need to give a shout-out to Urban Giraffe for their Wordpress plug-in Sniplets. This enabled me to pull all of the examples in the Manual directly from the online examples. This means that any time I update the online examples, they will be immediately reflected in the Manual. Rock, rock on, says I.

I’m pretty sure that I didn’t leave anything out, but if you spot any omissions, mistakes, or poorly written explanations, please let me know! I will endeavor to fix the problem as quickly as possible.

Also worth mentioning in this post is that Processing 1.0 is out! I can’t say I contributed much to its release, but its imminent release is what got me to finally cleanup and release Minim 2.0. One exciting detail I don’t think I’ve mentioned is that Minim is now one of the libraries that comes with the Processing download. I am very honored to have my library so closely tied to such an awesome project and I hope that people find working with Minim as easy as it is to work with the core Processing API.

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.

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

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!

I’ve been wanting to make a sound-generating game for a while, I’m always inspired when I play games like Rez, Every Extend Extra, and ElectroPlankton. However, what I don’t want to do is make a Rez clone where there are already constructed songs that you just trigger new layers in and I don’t want to do a beat matching game because Harmonix already has that market cornered. So I’ve started working on a little sound-generating game/toy. It plays like a really simple shmup, but the mechanics are really just an interface to building up sound over time. You can fly a little ship around with some amoebas and they will just harmlessly bounce off of your ship. If you shoot an amoeba it will add a note to a music loop that plays throughout. This loop starts out with nothing in it, so the beginning of the game is silent. The color of each amoeba directly maps to the pitch and velocity of the note that they will create, but it is a narrow range so it is not immediately obvious what note you will get.

Play it.

There are still a few things that I want to add, both visual and aural, but the basic idea is there. I will probably also be writing my own Sequencer implementation because the one that comes with Java hiccups sometimes and doesn’t do track muting properly. Or, rather, it probably does track muting exactly how the author of the implementation intended, but that intent is not one that I agree with. If Processing didn’t make it so easy to create visuals I think I would have totally given up on audio/midi in Java by now.

Well, I accomplished one of my two goals and finished writing the Minim manual. Hopefully it is clear and will be a useful reference for people. I wasn’t able to push out a new release because of holiday parties, distractions from other projects, and so forth.

Some good news for Minim development, however, is that I finally got around to setting up my PC to dual boot Ubuntu and Windows XP, so I’ll be developing primarily in Linux and then testing things back in Windows. I have already discovered that Linux is pretty tetchy, has latency issues, and is just generally not as great for audio. I have an idea for how to solve the latency issue, but it will require pretty significant recoding. I may just release a new version of Minim within the next month to make some small API changes available and then push dealing with the latency issue into the following release. I’m going to try to be better about semi-regular releases so that when people send me bugs I deal with them quickly and then release a new version.

I’ve started working on a game for Gamma 256. It’s an idea that literally came to me at about 2am in the morning. I sent a brief design doc to Fish and Heather and incorporated some of their feedback into the design. I’ve just finished the first gameplay prototype. The basic idea is to match three or more colored tiles in a row. The catch is that there are three grids, each corresponding to a primary color (RGB), and the tile and grid have to be the same color for a match to work. In other words, red tiles are matched in the red grid and so forth. To move tiles around you position selection boxes in each of the three grids and the swap tiles between them either clockwise or counter-clockwise. If a swap results in a match in two grids, then a tile that is the mixture of the two, like red and blue making magenta, drops in the top of one of the two grids. Since magenta is red and blue mixed, magenta tiles can be matched in the red and blue grids. Anyway, describing this with words is silly, just go try out the prototype:

http://code.compartmental.net/primaries/proto1

I’m very happy to announce the release of Minim 1.1!

If you’ve been using Minim 1.0, there are some important changes you need to be aware of:

Another major change from 1.0 is the inclusion of a bunch of Interfaces that define library functionality. Essentially what I’ve done is defined how everything in the library should behave and then written an implementation of that spec. This is why createRecorder takes Recordable as the first argument and not an AudioInput or other concrete class. The use of Interfaces shouldn’t break any of your existing code because I used the existing methods of Minim as the starting point for the Interfaces.

I fixed a host of bugs relating to mp3 playback for this release. They should behave exactly like WAV and AU files now. There are many more examples now, one for each method of each Interface that defines the functionality of Minim classes. Examples are organized by Interface, rather than by concrete class, hopefully this isn’t too confusing for people.

Please let me know if you have any problems or questions!

I was recently motivated to revisit Minim when I got a note about it from Casey Reas, one of the initiators of Processing. Man oh man did I revisit it. The implementation details went through two waves of refactoring, but I think I’ve gotten it to a place that I’m happy with. I’m only incrementing the version number by .1 because I haven’t added any new features. I just changed the names of a couple public classes, made all the implementation details package private so that they don’t clog up the Javadoc, and fixed some bugs relating to mp3 playback.

Additionally, the API is now defined by several interfaces, which opens up the possibility for people to write their own implementation of a file reader, for example. I’m not sure why anybody would actually go to the trouble of doing that, but the possibility exists, nonetheless. Defining the API in terms of interfaces helped me a great deal with standardizing the methods of different public classes that can do similiar things (like applying effects to an audio stream).

I hope to do a release this coming weekend, but it depends on how quickly I can whip the examples into shape. But do keep an eye out!

« Older entries