ShowChaos: Showing phrases and parts as pseudo-notation

In an earlier demo we saw the simple DrawScore tool which displays a jMusic score as a piano roll display. Later we saw the ShowScore demo which introduced a jm music tool which displays scores in a stave view. The ShowScore tool is very similar, but displays the jMusic score on a grand stave using the piano-roll-like note bars.

To remind you, here is what the Fractal melody looked like in the ShowScore window. The ShowPhrase and ShowPart classes will look identical except they will display a phrase or a part passed to them, rather than the whole score. This can be useful if you wish to examine sections of the score, or to compare a particular phrase with another or with the whole score.



In ShowScore, ShowPart, and ShowPhrase views notes are shown as rectangles (their length proportional to their duration). The black thin lines indicate treble and bass staves, while the grey staves indicate pitches at more extreme parts of the range but can be read as treble (upper) and bass (lower) two octaves away. The ruler displays a line for each beat and larger lines in groups of four.

The horizontal scale of the score can be adjusted by dragging on the ruler bar along the top of the window.

The ShowChaos class creates a score and displays sections of it using ShowPrase, ShowPart, and ShowScore.

Click here to view source.

Lets have a closer look.

import jm.JMC;
import jm.music.data.*;
import jm.music.tools.*;
import jm.util.*;


As well as the by now familiar imports, note that the jm.music.tools.* line is necessary because ShowPhrase, ShowPart, and ShowScore are in the jMusic jm/music/tool directory.

public final class ShowChaos implements JMC{
public static void main(String[] args){
Score score = new Score("JMDemo - Show Chaos");
Part inst = new Part("Piano", PIANO, 0);
Part inst2 = new Part("Guitar", GUITAR, 1);
Part inst3 = new Part("Flute", FLUTE, 2);
Phrase phr = new Phrase(0.0);

//---------------
// Do chaotic things
//----------------

for (double i=0.0;i<Math.random()*100;i+=Math.random()*2.0+8.0) {
phr = makePhrase(i);
inst.addPhrase(phr);
}

for (double i=0.0;i<Math.random()*100;i+=Math.random()*2.0+8.0) {
phr = makePhrase(i);
inst2.addPhrase(phr);
}

for (double i=0.0;i<Math.random()*100;i+=Math.random()*2.0+8.0) {
phr = makePhrase(i);
inst3.addPhrase(phr);
}

// add the part that to a score
score.addPart(inst);
score.addPart(inst2);
score.addPart(inst3);

In section of the code the class is setup and most of the main() method is shown. First the arguments (variables) for the class are setup. There are three parts each on a different channel. The Phrase "phr" is declared and will be used again and again to create numerous phrases later on.

The section 'Do Chaotic Things' creates notes for each part in turn. It calls the makePhrase() method which we will see below to create a phrase. The random bits effect the start time opf phrases (all the chaos theory happens in the makePhrase() method).

Finally, in this section, the three parts are added to the score. This should be familiar by now.

                //use show routines	       
View.show(phr);
View.show(inst, 20, 20);
View.show(inst2, 40, 40);
View.show(inst3, 60, 60);
View.show(score, 80, 80);

Now that the sections are created we can show them with the View class method show(). Because the Phrase phr was used over and over the final Phrase only is shown (none of the others have distinct names so cannot be referenced). Each part is shown in turn, with the window position being adjusted each time (20,20 etc.) to create a layered window appearance. The score is shown in the same way.

These calls to show a section can be made anywhere in the code after the section has been created. You do not have to wait for a Part to be added to a Score before showing the Part, for example.

           	//create a MIDI file of the score	       
Write.midi(score, "Chaos.mid");
}

The last segment of the main() method exports the score as a MIDI file in the usual fashion.


   	public static Phrase makePhrase(double startTime) {
double a = Math.random()* 2.0;
double b = 0.3;
double xold = 0.0;

// initial x position
double x, y;

// temp variables

double yold = 0.0;

// initial y position
int pitch;
Phrase phrase = new Phrase(startTime);

// create a phrase of chaotically pitched quavers over a limited MIDI range.

for(short i=0;i<(int)Math.random()*10+15;i++){
x = 1 + yold - a * xold * xold;
y = b * xold;

// map the x value across a few octaves

pitch = (int)(x*24)+60;
// make black notes into white notes
if (pitch%12==1 | pitch%12==3 | pitch%12== 6 |
pitch%12==8 | pitch%12==10) pitch -= 1;

// if pitch is negative make it positive
if(pitch <0) pitch *=-1;

Note note = new Note(pitch, Q);
phrase.addNote(note);
xold = x;
yold = y;
}
return phrase;
}
}

The second method in this class is makePhrase(). Notice that the method declaration (first line) is not void (like we have mainly seen) but declares a return type of Phrase. This indicates that the method will pass an object of type Phrase when it is complete. If you look at the last line of the method you can see the 'return Phrase' command doing just that. You might remember that this method was called in main() when creating Phrases for each Part of the piece.

First it sets up the variables to be used. The variable 'a' is randomised so that each phrase is not the same. It then does the Chaos math to generate notes, just as in the previous Chaos examples. The length of phrases is set randomly between 15 and 25 notes. The pitches are scaled to between 60 and 84. The pitches are checked to see if they are on 'black' notes, and if so decremented by 1 to flatten them to 'white' notes. In this way only notes in the C major scale are produced.

The final curly bracket closes the class.

Have a go at using the View.show() method in your own jMusic classes.