|
import jm.JMC; |
We import the usual suspects for the jMusic data, and the audio classes for the simple synthesis we have as output, and the util class for MIDI and AU file writing.
public class AutomataMusic implements JMC{ |
To specify the size of the cellular matrix (how many cells) a two dimensional array (an array of array - i.e, a matrix) called 'cells' is declared. The size of the matrix is 10 cells by 10 cells, 100 in all.
All the elements for a jMusic piece are declared, score, parts and phrases.
The last two lines declare an audio instrument that is a raw triangle waveform.
public static void main(String[] args){ |
This simple main() method should be familiar by now to you. It creates a new instance of this class.
public AutomataMusic() { |
The constructor has most of the hard-work code in it. An instance of the CellularAutomata class called CA is decalared. This class is one of the three used in this program. having it separate keeps the details of the cellular automata code out of the way so we can focus on music, and also means that we can use it in a number of pieces without having to rewite it or cut and paste code each time.
Two instances of the DrawCA class are declared. We use two simply to show that the class is flexible enough to draw a cellular matrix display at any specified size. Notice that the second declaration passes additional arguments to sepcify a non-default size.
for(int i=0;i<maxNotes;i++) { |
In this code block (above) most of the important work is sepcified. A loop is set up to repeat for the maximum number of notes we want in our score.
The CA object has it's evolve() method called, which applies the rules to the matrix one time.
The next loop goes through each cell and checks it's state (on or off, true or false) and keeps a tally in the liveCellCounter variable.
The tally of live notes is mapped to pitch, via the variable called noteNumber. So that we don't get very low notes the pitch is offset. In this case with the maximum possible on-cells = 100 and knowing we can we can allow the top pitch to be 127, the pitch offset needs to be 27. The maths might look a bit complicated, but that is to allow for a wide range of possible cell matrix sizes. Of course the larger the matrix the wider the probable pitch range. (Can you explaine why?)
A pause is inserted into the programs thread (100 milliseconds) so that the graphics don't go too fast. This deliberatly slows down the running of the program - the things we do to look pretty!
Having used the cellular automata matrix we get it to redraw its appearance in the last couple of lines of the code segment. Each of the DrawCA objects has its repaint() method called.
piano.addPhrase(phr1); |
After looping for a number of notes we end up with a phrase. This phrase is added to the piano part, then to the score.
The score is written out as both a MIDI file and an audio file, using the triInst. The score is also displayed.
You can clearly see here that the jMusic score data structure is what we create and that is then translated into the MIDi format the AU audio format and a piano-roll visual display.
The Cellular Automata structure, when mapped to pitch in this way, creates a results that is not much different from randomness. This is to some degree a tendency of Cellular Automata but especially a limitation of our very simplistic mapping. More sophisticated work on music derived from Cellular Automat has been done by composers, in particular check out the work of Eduardo Miranda which is detailed in his book 'Composing Music with Computers' (Focus Press 2001).
|
|
|
|
|
|