[Note: this section of the manual pertains to the recent Beta Release of Minim and not to the version currently being distributed with Processing.]
Overview
This section of the manual is intended to get you quickly up and working with the music programming capabilities of Minim. There are a few basic concepts which are necessary to understand first, but you should be able to make notes and sounds with Minim pretty quickly.
The first idea is a UGen. This is our short name for a unit generator. A unit generator is a standard concept in music programming, so we won’t go too in depth. Put simply, it’s an object which does only one thing. It might generate a tone, or filter audio, or create an amplitude envelope for audio, but it does just one thing.
Another standard concept in sound synthesis is that of a synthesis chain. The idea is that by connecting UGens together in a chain of some sort, the sound that is heard becomes more complex. We call connecting a UGen to another UGen patching. Here’s an example of a very simple sythesis chain.
oscillator –> output
With chain you’d just hear the tone generated by the oscillator. A more complex synthesis chain might look like this:
oscillator –> filter –> delay –> output
In this case, the oscillator’s audio would go through a filter and then a delay and then to the output. This might be implemented in Minim with the following code:
oscillator.patch( filter ).patch( delay ).patch( output );
The sound that is finally heard is created by the complete synthesis algorithm. A synthesis algorithm may be made up of one or more synthesis chains which are connected together in some way. To demonstrate this, I’ll use a Summer Ugen. A Summer UGen takes anything that is patched to it and adds it to everything else that has been patched to it. Here’s an example of a slightly complex synthesis algorithm using three synthesis chains:
noise –> filter1 –> summer
oscillator –> filter2 –> summer
summer –> delay –> output
In this case, you can see that filtered noise would be added to the summer, a filtered tone from the oscillator would also be added, then the output of the summer would be delayed before sending it to the output. This might be implemented with the following code:
noise.patch( filter1 ).patch( summer ); oscillator.patch( filter2 ).patch( summer ); summer.patch( delay ).patch( output );
In order to control more aspects of the sound, UGens have inputs. For example, the Oscil UGen (the oscillator) has an amplitude, frequency, and phase input. This becomes very useful for finer control over the sound. Here’s a simple example of using inputs:
lfo –> oscillator.amplitude
oscillator –> output
Here, a low-frequency oscillator, lfo, would be controlling the amplitude of an oscillator. That same oscillator would be sending a tone to the output. This might be implemented with the following code.
lfo.patch( oscillator.amplitude ); oscillator.patch( output );
So far, all of this has been about how to make sound, but this would generally be sound that starts when the sketch is run and continues until the sketch is stopped. To be able to play notes, one must encapsulate the synthesis algorithm inside of an Instrument.
A note, for our current purposes, is considered to be a sound which has a beginning and an end. When you create an Instrument object, you must specify what happens when the Instrument’s noteOn() and noteOff() methods are called. For noteOn(), this might simply involve starting the attack section of an amplitude envelope. For noteOff(), this might be simply ending an amplitude envelope.
In order to play a note, you use the playNote() method of the AudioOutput object. There is a simple default instrument built into Minim, so the following code would make a few notes.
out.playNote( 1.0, 2.9, "C3" ); out.playNote( 2.0, 1.9, "E3" ); out.playNote( 3.0, 0.9, "G3" );
The first parameter of this version of playNote is start time, the second is duration, and the third is the pitch of the note. This will be explained in more detail later.
Writing Some Code
—————–
In using Minim at all, you must import the library. It is recommended to use the menu options Sketch > Import Library > minim, or you can simply add
import ddf.minim.*;
at the top of the sketch in order to add the base minim package.
In order to use music programming part of Minim, you’ll also need to import the ugens package, which you can do by including
import ddf.minim.ugens.*;
at the top of the sketch, too.
You’ll need a Minim object so the next line might be
Minim minim = new Minim( this );
and you’ll need an AudioOutput object so Minim knows where to send the output of the synthesis algorithm.
AudioOutput out = minim.getLineOut( Minim.MONO, 2048 );
In this example we’ll just use a single oscillator to make a tone, so we need to create an Oscil UGen object.
Oscil osc = new Oscil( 349.23, 0.8 );
Finally, we’ll need to create the one chain synthesis algorithm.
osc.patch(out);
All together, the code looks like this:
import ddf.minim.*; import ddf.minim.ugens.*; Minim minim = new Minim( this ); AudioOutput out = minim.getLineOut( Minim.MONO, 2048 ); Oscil osc = new Oscil( 349.23, 0.8 ); osc.patch( out );
And this is the code (without the helpful comments) from our included example nonInstrumentExample.
You can play a few notes using the default Instrument with the following code.
import ddf.minim.*; import ddf.minim.ugens.*; Minim minim = new Minim( this ); AudioOutput out = minim.getLineOut(); out.playNote( 1.0, 2.9, "C3" ); out.playNote( 2.0, 1.9, "E3" ); out.playNote( 3.0, 0.9, "G3" );
In the next sections we’ll move further in depth with music programming in Minim. If you feel like you’d just like to dive right in, there are plenty of examples in the minim-examples directory. Some of those are certainly much more complex than others. Here’s a suggestion of an order for exploring them.
extremely simple
——
nonInstrSimpleExample
defaultInstrumentExample
simple
——
filterExample
constantExample
delayExample
a little more complex
———————
gainExample
filePlayerExample
liveInputExample
complex with instruments
———————–
noiseExample
oscilExample
ADSRExample
dampExample
lineExample
balanceExample
waveformExample
bitCrushBeatExample
bitCrushExample
granulateRandomExample
midiFreqExample
multipleOutputsExample
panExample
pitchNameExample
realtimeControlExample
notably complex
—————
algorithmicCompExample
compositionExample
granulateSteadyExample
instrCommunicationExample
maxInstrExample
oscilEnvExample
oscilPhaseExample
waveShaperExample
Pingback: [Midterm] Drawing Machine Playtests | The Flavorful
Pingback: Lecture 6: Sound | Art 122 UCSB Spring 2013