Minim: An Audio Library for Processing
It’s here, the first release of my audio library for Processing: Minim.
Here are some of the cool features:
- Released under the GPL, source is included in the full distribution.
- AudioFileIn: Mono and Stereo playback of WAV, AIFF, AU, SND, and MP3 files.
- AudioFileOut: Mono and Stereo audio recording either buffered or direct to disk.
- AudioInput: Mono and Stereo input monitoring.
- AudioOutput: Mono and Stereo sound synthesis.
- AudioSignal: A simple interface for writing your own sound synthesis classes.
- Comes with all the standard waveforms, a pink noise generator and a white noise generator. Additionally, you can extend the Oscillator class for easy implementation of your own periodic waveform.
- AudioEffect: A simple interface for writing your own audio effects.
- Comes with low pass, high pass, band pass, and notch filters. Additionally, you can extend the IIRFilter class for easy implementation of your own IIR filters.
- Easy to attach signals and effects to AudioInputs and AudioOutputs. All the mixing and processing is taken care of for you.
- Provides an FFT class for doing spectrum analysis.
- Provides a BeatDetect class for doing beat detection.
Visit the download page, then take a look at the Quickstart Guide or dive right into the Javadocs.
April 10th, 2007 at 12:22 pm
Great library, thanks for all your hard work, just found it today and very excited to start playing with it.
April 10th, 2007 at 12:43 pm
Hey thanks. Hopefully you’ll find it easy to use. Let me know if you have any problems with it.
April 16th, 2007 at 4:50 am
Yes a great library. It seems somewhat less intimidating to me then Ess to work with for students (and mp3 playback is included…).
What i miss is a startOfBuffer method that relaties a audiobuffer with the entire stream (there is such a method in Ess). I would really like to have that available to make a player where you can visualize the wave form and the cue position.
Furthermore i have noticed that triggering a sample on linux gives rather distorted sound (and varying over time as well). The ‘drummachine’ is a nive example of that behaviour.
Rein
April 16th, 2007 at 7:36 am
The functionality you would like is already present in the AudioFileIn class. You can use
cueto position the “playhead” anywhere you like in the file.cue(0)will set the playback position to the beginning of the file. You can see how this works by taking a look at the scrubbing example.April 16th, 2007 at 8:18 am
Thanks for answering so quickly!
Maybe you could enlighten me a bit. If in a draw() function i look at the samples in (say) the left buffer (from 0 to 1023: btw on linux i can’t set a different buffersize without introducing distortion) but where in the entire stream do these samples come from?
The position method (used in the scrubbing example) points relatively to the entire file. I would like to know where the bufferstart is with respect to the entire file.
April 16th, 2007 at 8:59 am
I just took a look at the Ess docs to see what you are referencing. He’s got
bufferStartTime, which “contains the time in milliseconds that the last buffer of data was sent to the sound playback engine”, and on AudioChannel he’s gotgetCurrentPlayFrame(), which “returns the exact sample frame being played.”The first value sounds like it is totally independent of the length of the file being played or the position in the file. It is simply telling you when the last buffer was received by the playback engine, I assume counting from when the sketch was launched. But I don’t know. This isn’t a number that I make note of because it never occurred to me it might be useful information.
The second value, the current play frame, is similar to what
position()returns, though he claims much higher resolution. I’m not sure how he is achieving this, particularly because audio is sent to the system one buffer at a time, so your resolution is always limited by how large the buffer you are sending is.AudioFileInkeeps track of how many bytes it has read from the file and all thatposition()does is convert this number to milliseconds, based on the audio format of the file. This means that the start of the buffer is going to be slightly before that value, but really the amount is negligible. If you’ve got a buffer of 1024 samples and you are playing back audio recorded at 44.1 KHz, one buffer corresponds roughly to 23 milliseconds.Thanks for the comments about the Linux issues. I don’t have a Linux box to test on, but I hope to remedy that in the near future.
April 16th, 2007 at 10:34 am
Thanks again! Nice to have such direct feedback.
OK i understand that asking for which sampe is being played is too much to ask for. However knowing which frame (buffer) is being played would be nice because then in a draw() function i could check whether i have seen the actual frame before (and then i don’t need to update the display).
I imagine that in case i make an effect filter that just makes a copy of the buffer and simply counts how many frames i have ’seen’ allready i can do the counting myself (but that’s quite a lot of overhead i assume).
I’m familiar with (audio) signal processing but not that much with the way audio is implemented in the java sound system. I would be very very grateful (and i guess a lot of other potential users as well) if you could give us a few pointers on how things are done. Who is in control? Who decides it is time to send a new frame to the hardware? Who asks for a new frame from the input stream. etc etc.
Thanks again.
Rein
April 16th, 2007 at 10:58 am
Ah, here there seems to be some confusion regarding terminology. A sample frame is not the same as a sample buffer. Maybe it is the case that some people refer to a large group of samples as a frame, maybe in the context of windowing a signal before doing processing on it, but I like to keep the two terms separate. It was a major source of confusion when I first started using Ess because sometimes there was talk of samples (obviously single values) and sometimes talk of sample frames, which sounds like something else but was never really explained.
When I talk about a sample frame, I’m talking about a chunk of bytes from an audio file that contains the information for a single sample. This might be as small as 4 bytes for a mono file, but is twice as large for a stereo file because one frame has the sample for the left channel and then the sample for the right channel.
A sample buffer is just a storage space of arbitrary size that is used to read chunks of data from the file. The sending of samples read from a file to the system is handled by a
LineReaderin its own thread. The line reader asks its associatedAudioFileInfor samples as it needs them. The control flow is like this:LineReader’s thread is always running, it doesn’t stop running if you pause the pause playback of the file or if the file finishes playing, it just writes silence to the system.
For a more complete description of everything involved you should read the Java Sound Programmer Guide and then just take a look at the source code for Minim.
April 27th, 2007 at 7:46 pm
Hi ddf
Well, this is a nice sound library. I am new to all this (programming, processing, etc.) and I was wondering about this: if you want to play back an audio file, but wish to stop it before it ends, so you can start another one, how do you do it since it does not seem to have a stop() function? Ess has one, but what is the trick with Minim?
April 28th, 2007 at 5:08 am
You can stop the playback of a file by calling the
pausemethod. If you callplayafter that, it will begin playing from where you paused it, unless you’ve calledrewindorcueto reposition the playhead.If you are wondering how to load a new file into an existing
AudioFileInobject, you can’t. You simply create a new one for each file you want to play. This shouldn’t be a problem unless you are trying to load many files. In fact, this makes me think I need to set up a way to completely dispose of a file that you are finished with, including the playback thread that is created by Minim.April 29th, 2007 at 9:40 pm
Great ddf, your advice got me out of trouble.
Actually I am working on an interactive installation with motion tracking (the JMyron library), and the idea is that, depending on where the visitor stands in space he/she will start one of the three sound files I have. So now they are playing one at a time depending on one’s position in space. Great. There remains one problem though: if I use the rewind method within my draw loop (it has to be within a draw loop because I am using other functions at the same time to trigger other devices) and the visitor move a little (but remaining within the same area pertaining to the same sound file) the song, obviously, constantly rewinds (which is annoying) if I just let it play, the problem is that once it gets to the end, it does not start again for the next visitor, which is also problematic. I have tried the cue function, but because it is a function it can’t be within my draw loop -and that is not good either. Any extra suggestions?
Thanks for taking the time to read all this and trying to understand each of our own needs. great work.
April 30th, 2007 at 7:28 am
I’m sure there is a way to set up the logic so that the behaviour is what you want. I’ll drop you an e-mail about this.
May 29th, 2007 at 5:46 am
This is great, but I’m having trouble with MP3 playback:
On Mac OS X, AudioFileIn.length() returns zero, whereas length() works fine with .wav and .aiff.
What’s worse: I get a “Minim Error === AudioFileIn: error reading from file.” error when I try to play back the same mp3s on Windows. Again, .wav and .aiff work well.
Is this a limitation of JavaSound? Have you come across these problems?
June 3rd, 2007 at 6:14 pm
Carsten:
Your issues have been resolved in version 1.1
June 10th, 2007 at 10:49 pm
Great, thanks for the reply!
June 28th, 2007 at 6:09 pm
Hi,
This is a nice easy, to use sound library that can do things much easier and simpler than ESS and Sonia, at least for a novice in processing and Java. Thanks for the efforts.
Since the documentation is not quite ready yet, I couldn’t find how a can do a particular thing. I managed to link the incoming fft information to visual parameters and got some kind of sound reactive visuals. Its quite simple right now, but I want to know how I can get the spectrum divided into certain frequency bins and get seperate visuals react to seperate frequency bins. So, say, if theres a kick sound in the lower registers of the frequency spectrum, I want it to activate a certain visual parameter, and if there’s a, say, hi-hat sound in the higher registers, i want it to activate another one. I guess it sounds like a kind of music visualisation.
Which function should i use to achieve this and how can I implement it? (at least in simple terms)
Thanks again for your efforts,
Emre.
June 28th, 2007 at 6:20 pm
Well, this seems to be a kind of customized beat detection idea, so I’ll try to check out that function.
Cheers.
January 10th, 2008 at 6:34 am
Hey! It’s a very nice library indeed! I am using minim library for some of my projects.Perhaps a simple question for you: is there a function (way) to determine the sounds you listen to from which speaker you want them to be heared? I mean i want to listen the “a” sound from the left speaker and the “b” sound for the right speaker. Is that doable? I searched the manual and I din’t find an example about that.
Thanks!
January 16th, 2008 at 7:54 pm
Hi Stelios, sorry for the slow reply.
You can let the pan for a sound, so you could set the “a” sound to have a hard-left pan (-1) and the “b” sound to have a hard-right pan (1).
See: http://code.compartmental.net/tools/minim/manual-controller/