Bug Fixing, Build Process.

Among all of the things that I have learned while working as a professional game dev, two very important things are 1) how to document and test bug fixes and 2) the importance of having a sane build process. I didn’t have a terribly good handle on either of these things when I first created Minim and as a result pushing out a release was a very painful process.

Bug Fixing

I’ve not always been good about keeping track of exactly which bugs I’ve fixed in a release, or which new features I’ve added. No longer! The past two days have seen verbose comments in my check-ins, which means I should be able to create a pretty exact changelog for the next release. Here’s my most recent check-in comment, to give you an idea of the kinds of things coming up:

Build Process

Creating and uploading new JAR files is not the hard part of doing a release. No, the hard part is making sure all of my online examples are up-to-date and making sure the Manual reflects any additions or changes to the API. The biggest pain with the examples is that the directory structure that I use on the website does not match the local directory structure, so it’s not just an easy drag-and-drop. I have my examples set up as a subdirectory in my Processing sketch folder, but what actually gets uploaded to the website are the contents of the applet directory that is generated for each sketch when I export it. Man, I would love to know a way to tell Processing to export an applet to a location other than the sketch folder, because then I could export to a directory structure that is the same as what’s on the web.

In any event, that’s a pain, and I need to figure that out, but I also finally got around to creating a subversion repository for all of the example source files. This will at least make it easier for me to tell at a glace which sketches need to have applets re-exported and uploaded. Maybe I can even figure out how to create an automated process for this. But, one thing I had to do before I could commit all of the examples, was delete all of the applet directories. To do that, I googled around and found this totally helpful batch file:


FOR /F "tokens=*" %%G IN ('DIR /B /AD /S *.svn*') DO RMDIR /S /Q %%G

That particular code will delete all subdirectories that match the name “*.svn*” under the directory it is executed in. All I had to do was change the name to match to “applet”. It’s all really clearly explained in this forum post and worked liked a charm.

So, that’s at least one part of my build process that’s been sanitized (by which I mean: made sane)!

Frequency Modulation Is Easy

I’m working on adding the ability to do frequency modulation in Minim. I didn’t figure it was a very complicated thing. I knew that I’d have to do it while generating each sample, so it couldn’t be done as an AudioEffect. But when I went looking online about how to do it, I found a number of articles that described the technique in words, with somewhat dense equations, but none that had easy to understand code examples. I did find this article, but the code in it is some form of Lisp, a language I am not familiar with. I thought I had it figured out a couple times, but every time I tried something new I still wasn’t achieving the correct result.

So today I asked my friend The Mysterious H how it works because he’s a smart guy and builds synths out of Atari sound chips and shit like that. He goes, “Oh it’s easy.”

Every time you want to generate a sample of the signal you are modulating (the carrier), generate a sample of your modulator and add that to the phase you use to generate your carrier sample.

Said another way: Say you’ve got a signal called f. At every time step t (which is your phase), you generate a sample s by evaluating f(t). If you want to modulate the frequency of f with a modulator called m, then at every t you will do this:

The speed of the modulation is determined by the frequency of your modulator and the amount of the modulation (how many hertz above and below the frequency of your carrier signal the audible signal will swing) is determined by the amplitude of the modulator. In my tests I found that the amplitude had to be around 0.001 to achieve what one would consider vibrato. Setting it to 0.1 made for some pretty intense alien sounds when the frequency of the modulator was up in audio signal range (20 Hz and up, say).

It’s lots of fun to play with and will be coming soon!

Minim Manual Updated.

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.

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)
[snip java]
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();
}
[/snip]

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:

[snip java]
Minim minim = new Minim(this);
AudioPlayer player = minim.loadFile(“blah.wav”);
[/snip]

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!

Minim Manual Finished

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.

A Promise I Hope To Keep

Man, been a long time. I used to be annoyed by people who release tools like Minim and then leave them undeveloped for long stretches of time with nary a peep about how things are going or when they plan to release a new version. I was even more annoyed when documentation was missing or incomplete. No longer! I have become one of those people! It makes me a bit sad but at the same time a full-time job plus a social life really eats up most of the hours in a day.

Here is a promise I hope to keep:

Before the year is out I will finish the Minim Manual and release a new version of the library, incorporating a couple fixes people have sent me and also adding a little bit of new functionality.