Bass Mutation

This tutorial shows how a phrase can be evolved through random note substitution. It is not quite genetic because there is no fitness test, but it still works quite well from a musical perspective.

A phrase is created (based on probability), then played twice. The pitch of one note of the phrase is then replaced by a randomly selected pitch (in this case from a small set which includes rests), and played twice. This pitch alteration continues every two bars, and with that the melody evolves (mutates) over time.

This is what the result of this tutorial file sounds like:

There are two source files. The BassMutation.java file and the MakeParts.java file from the Arrange Phrases demo which is used to provide the accompanying drum pattern. Only the BassMutation source is shown here.

Click here to view BassMutation source file.. - Click here to view MakeParts source file..

Let's have a closer look.

import jm.JMC;
import jm.music.data.*;
import jm.music.tools.*;
import jm.midi.*;
import java.util.Vector;
 
/**
 * An example which generates a phrase and then mutates
 * it every second bar by randomly changing one note
 * @author Andrew Troedson and Andrew Brown
 */
 
public final class BassMutation implements JMC{
	public static void main(String[] args){
		Score s = new Score("BassMutation");
		Part p = new Part("Bass", 1, SYNTH_BASS);
		Part p2 = new Part("Drums", 9, 25);
		Phrase phr = new Phrase();
		
		int compDur = 32; //number of mutations to create (each is played twice)

In this first section all the basic jMusic setup stuff is covered. The score is created, along with the two parts - one for the bass, and one for the drums. The number of mutations which will be made is also set, and the final piece will be twice as many bars long as this (as each mutation is played twice).

		//bass
		int[] pitchSelection = {36, 40, 43, 45, 48, 52, 55, 60, REST, REST, REST};
		int pitch;
		int noteNumb  = 16; //sets the length (number of SQs) of each phrase
 
		//create the initial bass phrase
		for (int i=0;i< noteNumb ;i++) {
			pitch = pitchSelection[(int)(Math.random()*pitchSelection.length)];
			Note note = new Note(pitch, SQ, (int)(Math.random()*70 + 50));
			phr.addNote(note);
		}
		
		//the main Bass mutate loop
		for(int i=0;i<compDur;i++){
			//add the new phrase to the part (twice!)
			p.addPhrase(phr.copy());
			p.addPhrase(phr.copy());
 
			//mutate
			Note n = phr.getNote((int)(Math.random()*noteNumb));
			n.setPitch(pitchSelection[(int)(Math.random()*pitchSelection.length)]);
		}	

In this section we create our funky bass line! First of all, an initial bass phrase is created randomly from the available selection of pitches (which are established in pitchSelection[]). Then, after this phrase has been added to the part (twice!), one of the notes in it is selected at random, and replaced by a new note selected at random from pitchSelection[]. This process repeats for the length of the composition. Notice that only the pitch of the new note is altered - this means that the dynamic contour of each bar will be the same. Try adding the following line at the end of this section to randomly alter the dynamics as well:

			n.setDynamic((int)(Math.random()*70 + 50));

		//drums
		for(int i=0;i<compDur/4;i++){
			CPhrase drums = MakeParts.drumPattern();
			p2.addCPhrase(drums);	
		}
		
		s.addPart(p);
		s.addPart(p2);
		
		//write a MIDI file to disk
		Write.midi(s, "BassMutation.mid");
		
		View.show(s);
	}
}

We finish by adding an accompanying drum part courtesy of the MakeParts class. The drumPattern() method of this class returns a two bar random drum phrase. Finally, both the bass and drum parts are added to the score and the MIDI file is created.

Think about how we could enhance this class even further. Perhaps two notes (even two consecutive notes!) could be mutated each time, or the pitch selection could be changed over time...


jMusic Tutorial Index