A Fractal Melody

This demo will show how to use the mathematics of fractals to generate music. Fractals are based on a set of probabilistic mathematical systems which have some interesting properties. The output is 'noisy' but features aspects of self similarity, that is, patterns reoccur at different levels of detail which provides a sense of coherence not found in other probabilistic processes. Fractals are often represented visually, most famously in the 'bug-like' picture of the Mandelbrot set.

For an overview of Fractals and their musical uses read The Computer Music Tutorial (Roads 1996) from p.880. Also read Computer Music (Dodge & Jerse 1997) from p.370.

To hear the result play the MIDI file below.

View source

Lets have a closer look. 
 2     import jm.JMC;
 3     import jm.music.data.*;
 5     import jm.util.*;

These lines import useful packages that we need to use in the program. The first import statement gets a standard Java class used for error messages. The rest of the statements import the jMusic classes (take another look at the package documentation to work out what gets imported from where -> PACKAGES).

 13     public final class Fractal implements JMC {
 14             public static void main(String[] args){
 15                     Score score = new Score("JMDemo - Fractal");
 16                     Part inst = new Part("Piano", PIANO);
 17                     Phrase phr = new Phrase();
 18                     float sum;
 19                     float[] rg = new float[16];
 20                     int k, kg, ng, threshold;
 21                     int np = 1;
 22                     int nbits = 1;
 23                     int npts = 48; //number of notes
 24                     float nr = (float)(npts);
 25                     
 26                     nr = nr/2;

All the work is done in the main method started here. This section of the method sets up the attributes to be used. First the usual suspects of Score, Part, and Phrase. Then a number of variables which will be used by the fractal algorithm are set up. The details of the algorithm will not be discussed here - refer to the references above (or others) for details on the math.

 28                     // create a phrase of fractal pitches quavers 
// over the full MIDI range.
 29     
                System.out.println("Calculating fractal melody. . .");  30                                       31                     while (nr > 1) {  32                             nbits++;  33                             np = 2 * np;  34                             nr = nr/2;  35                     }  36                       37                     for(kg=0; kg<nbits; kg++) {  38                             rg[kg] = (float)(Math.random());  39                     }  40                       41                     for(k=0; k<npts; k++) {  42                             threshold = np;  43                             ng = nbits;  44                             while(k%threshold != 0) {  45                                     ng--;  46                                     threshold = threshold / 2;  47                             }  48                             sum = 0;  49                             for(kg=0; kg<nbits; kg++) {  50                                     if(kg<ng) {rg[kg]=(float)(Math.random());}  51                                     sum += rg[kg];  52                             }  53                             Note note = new Note((int)(sum/nbits*127), Q);  54                             phr.addNote(note);  55                     }

After printing a reassuring comment to the screen this part of the code does the hard work of the Fractal math. The many FOR loops indicate that the algorithm is highly iterative, that is, the output of once cycle affects the next. Previous results affect future events. Like all probabilistic processes the random function is used to generate ever-changing values within certain constraints. At the end of this section of code the result of the each fractal calculation becomes the pitch of a new note which is added to the phrase. The fractal calculation produces a two dimensional output (x and Y), but only the one (x) dimension is used by the program. All notes are Quavers [eighth notes] in this example. One possible extension would be to use the Y dimension as the rhythmic value, but the musical result would be less 'organised' than a steady pulsed melody.

 57                     // add the phrase to an instrument and that to a score
 58                     inst.addPhrase(phr);
 59                     score.addPart(inst);
 60     
 61                     // create a MIDI file of the score
 62                     Write.midi(score, "fractal.mid");
 63             }
 64     }

The singles phrase created in the previous section is then added to a Part called 'inst' which in turn is added to the score. This should be a familiar jMusic process for you by now.

As with other jMusic demo files, this code creates a MIDI file from the score. Once created the fractal.mid file can be played by any MIDI file player and will sound correctly using a General MIDI sound source, such as most PC sound cards. 



jMusic Tutorial Index