Generative Music Patterns
by Jean-Michel Rolland

Generative Music Patterns is a project for the web residencies program by Akademie Schloss Solitude, Stuttgart & ZKM | Center for Art and Media, Karlsruhe on the topic FRACTAL HORSES, curated by Claudia Maté.
Generative music always obeys patterns defined by the coder. Under these patterns, lines of code use mathematical or random algorithms to make the music sound somehow melodious. During the month of July 2017, I will create as many different patterns as possible, using mathematical formulas to develop algorithms that will make the music sound different. In all cases, the machine will be the composer, but it will have to create music within the limits I have established. Visualizations will evolve constantly with the patterns created. The work in progress will be updated as often as possible on this website with my creative process explained and will be available as a free app for Android on Google Play.

#1  #2  #3  #4  #5  #6  #7  #8  #9  #10 



Generative Music Patterns #1
Click to play and stop


I’m launching an experiment in which I will study different patterns to create generative music with the simplest features possible. I’m working with Processing, free software that enables artists to create generative art with a simplified Java language. The code will be adapted so it can be embedded into a web page.

I first create 60 mp3 piano samples that go from C0 (32.70 Hertz) to B4 (987.77 Hertz) that will be preloaded by the browser to be ready for playback when they’re called, thanks to this line, repeated 60 times:
<audio id="1" src="gmpfiles/note1.mp3" preload="auto"></audio>
<audio id="2" src="gmpfiles/note2.mp3" preload="auto"></audio> etc.
Then I use a JavaScript to create ten audio channels to enable the browser to play the notes smoothly.
Note that Google Chrome, Safari and Mozilla Firefox work well, but Internet Explorer has difficulties playing the sounds.

Then comes the Processing code itself. The first thing to do is to declare the variables, then give a few first orders gathered in the void setup().
These orders will be executed only once when the page loads. For example, they set the size and the background color of the animation.

Then comes the part that will be executed 60 times per second, the group of orders gathered in the void draw().

In this very first work, the notes will be chosen completely randomly. Here’s the line of code that determines which note will be played every 500 milliseconds:
note = int(random(1, 61));

I also made the visualization as simple as possible; a white line that starts from the position of the previous note and ends at the position of the current note:
line(prevPointx, prevPointy, pointx, pointy);

And last, I included another group of orders, void mouseReleased(), to enable the user to start and stop the animation with a mouse click.





-------------------------------------------------



Generative Music Patterns #2
Click to play and stop


In this second version, I decided to use a sin() function to determine which notes to play, in a circular motion.
The sin() function returns the sine of a number. As the sine will always be a number between -1 and 1, I scale it between 1 and 60 (the number of possible notes) with the map() function:
note = int(map(sin(note*TWO_PI/60), -1, 1, 1, 60));
To fully understand how sine works, please check this page: http://bit.ly/sine_cosine
If a G0 (eighth note) or a D#4 (52nd note) is played, we enter a two-note loop because:
int(map(sin(8*TWO_PI/60), -1, 1, 1, 60)) = 52 and int(map(sin(52*TWO_PI/60), -1, 1, 1, 60)) = 8.
If an F2 is played (30th note), we enter a one-note loop because:
int(map(sin(30*TWO_PI/60), -1, 1, 1, 60)) = 30!
But most of the time, we enter a looping pattern of ten notes: G#1, F4, C1, A#4, D2, D3, F0, A#3, C0 and G#2.



-------------------------------------------------



Generative Music Patterns #3
Click to play and stop


In this third version, which is very similar to V2, I exchange the sin() function for a cos() function. The notes are chosen depending on the cosine of the previous note :
note = int(map(cos(note*TWO_PI/60), -1, 1, 1, 60));
I don’t like the result, because too many times, int(map(cos(note*TWO_PI/60), -1, 1, 1, 60)) = note, which leads to repeat the same note forever... So I’m deciding to change the algorithm this way :
note = int(map(cos(note), -1, 1, 1, 60));
It’s a simplification because I no longer scale the previous note to the circle, but the result is better because it leads to three new patterns, each one consisting of four notes : D#3, A4, A2 and E0; A3, E1, A1 and C0; F#0, D#4, C2 and A#4.
When notes 45 (G#3) or 57 (G#4) are triggered, we enter both times in a one note-loop because int(map(cos(45), -1, 1, 1, 60)) = 45 and int(map(cos(57), -1, 1, 1, 60)) = 57.



-------------------------------------------------



Generative Music Patterns #4


I now want to use a Perlin noise to generate the notes. This algorithm was created to generate complex visuals but I use it here for sound design. It looks random, but it isn’t.
On Processing website, we can read : “Perlin noise is a random sequence generator producing a more natural, harmonic succession of numbers than that of the standard random() function. It was developed by Ken Perlin in the 1980s and has been used in graphical applications to generate procedural textures, shapes, terrains, and other seemingly organic forms.”
But I now have to explain why there isn’t any animation here but a video, screen capture of my computer. To embed Processing sketches on a website, I use Processing.js, which is powerful and quite easy to handle, but it alas manages the Perlin noise quite badly.
Here’s the new line of code that determines which note is to be played :
note = round(noise(prevNote)*60);
The function noise() returns values between 0 and 1, so I have to multiply them by 60 to cover my 60 notes. I create a new variable that I call prevNote to be able to compare the new note to the previous one :
if (note==prevNote) noiseSeed(int(random(10000)));
That means that if there’s a note repetition, it won’t occur more than once because I change the parameters of the Perlin noise with the function noiseSeed(). I also use this function each time the drawing goes back to the starting point at the left to generate a new pattern.



-------------------------------------------------



Generative Music Patterns #5
Click to play and stop - drag your mouse to change pattern


In this fifth episode, I work with the sin() function again (see episode two for more explanations on this function), but this time, I add some interactivity.
The line of code was previously :
note = int(map(sin(note*TWO_PI/60), -1, 1, 1, 60));
and now becomes :
int divider = int(1+mouseX/10.0);
note = int(map(sin(note*TWO_PI/divider), -1, 1, 1, 60));

In fact, I create a new variable that I call divider. This variable changes according to the horizontal position of your mouse and is displayed at the window's left bottom corner. It enables you to change the position of the notes on the imaginary circle, which calculates their sine. Thus, each time you move your mouse, you’re changing the algorithm and melody patterns. This actually enables you to create your own patterns.



-------------------------------------------------



Generative Music Patterns #6
Click to play and stop


After having worked on random, noise, sine and cosine, I think it’s time to create personal mathematical operations and make the visuals evolve, even if I want to keep them simple.
I first want to perform a simple operation : average the two previous notes played. But if I only do this, I will quickly have the same note played over and over :
note = round((prevNote + antePrevNote)/2);
So I have to add a new element to the equation. I decide to randomly add one or two octaves to low notes and subtract randomly one or two octaves to high notes :
if (note>30) {
     note-=12 * int(random(1, 3));
} else {
    note+=12 * int(random(1, 3));
}

note-=12 * int(random(1, 3));
means “note equals note less 12 multiplied by either 1 or 2”.
Moreover, until episode five, the delay between two notes was always 500 milliseconds. I decide to change this. Now, the delay can be either 300 or 400 milliseconds depending on the pitch.
I decide to create a less mathematical visual to build a kind of misty mountain that appears little by little. It’s made with low opacity white quadrilaterals. I hope you’ll like it!



-------------------------------------------------



Generative Music Patterns #7
Click to play and stop


In this new version, I decide to perform a very simple operation : I just add three or four to the previous note and change its octave in the same random proportions used in the previous episode :
note = prevNote + int(random(3, 5));
if (note>30) {
     note-=12 * int(random(1, 3));
} else {
    note+=12 * int(random(1, 3));
}


This leads the pattern to play either the minor or major third of the previous note, and change its octave. This leads to a short-term musicality, in the way that neighboring notes match together, but the global composition is rather strange!
I also change the delay between two notes. It’s now either 400 or 200 milliseconds.
This new musical pattern inspires me to create some new visuals that look like a growing city.



-------------------------------------------------



Generative Music Patterns #8
Click to play and stop


I take the former version of my generative music patterns and complicate it a bit in order to make it more interesting.
Depending on the pitch of the former note, I increase it by 4, 7 or 10. So, the new note is the major third, the fifth, or the minor seventh of the previous one, in a different octave. The delay between two notes is now either 300, 200, or 100 milliseconds :
if (note>40) {
     note = note+4;
     note-=12 * int(random(1, 3));
} else if (note<15) {
     note = note+10;
     note+=12 * int(random(1, 3));
} else {
     note = note+7;
     int sens = frameCount%2==0?1:-1;
     note+=12 * sens;
}


Let me explain this line : int sens = frameCount%2==0?1:-1;
It’s what coders call the “ternary operator”. If the rest of the division of the frameCount (counter that begins at zero and is increased by one unit sixty times per second) by two equals zero, the variable (int is for integer number) I named sens will be 1. If not, it will be -1.
As an artist, when I learned to code in Java, it was a great challenge. It was a bit like learning a weird foreign language. What I appreciate in those kinds of expressions like the ternary operator is its apparent complexity but its efficiency : with very few symbols, you can write something very complicated ! Haven’t you ever heard computer nerds talking about the beauty of code? I must confess I understand them...



-------------------------------------------------



Generative Music Patterns #9
Click to play and stop


For this episode, I was inspired by Béla Bartók’s music and adapted the octatonic scale to use only one note out of two : the fundamental, the minor third, the diminished fifth and the sixth. The previous note is randomly increased or decreased by three notes, and this value is multiplied by two or three depending on the parity of the previous note :
int sens = int(random(1,3))%2==0?-3:3;
int jump = note%2==0?2:3;
note+=sens*jump;


Then, I change the octave of the resulting note :
if (note<13) {
     note+=24;
} else if (note>12 && note<25) {
     note+=36;
} else if (note>24 && note<37) {
     note+=12;
} else if (note>23 && note<49) {
     note-=24;
} else {
     note-=48;
}


The delay between two notes is decided at random and can be 75, 150, 225 or 300 milliseconds :
ecart = int(random(1, 5)) * 75;

For the visuals, I use the former episode’s same triangles, but I introduce different colors that depend on the notes' pitch. It results in an abstract tableau which, in my opinion, matches the music.





-------------------------------------------------



Generative Music Patterns #10
For this last episode, here is a trilogy I built in July 2017. It’s based on the noise() function and, as I explained in episode #4, this function doesn’t work properly with processing.js (Processing for Internet).
For this reason, I’ve recorded five minutes of each to show them on the Internet, but keep in mind that they can be displayed in real time on any PC or Mac with Processing installed.
For these pieces, I’ve chosen three different pools of notes and created visuals inspired by the resulting melodies. This is a very personal translation of sound into image, and I hope you like it.
Feel free to contact me at jimrolland13@gmail.com for any questions about this webresidency that’s been possible thanks to Akademie Schloss Solitude, ZKM, and Claudia Maté, to whom I’m very grateful.

IN THE FOREST (in C minor)


IN THE CITY (in C octatonic)


IN THE NEBULA (in C major)