Bazza Nava Devlog #2 - Impro Machine


Back to business! Due to several events, progress has been slow. Nevertheless, I've been able to do some improvements to the music generation. This post is a continuation of the previous one. I recommend to read it before this one.

Better sheet

Last time I was complaining that writing a song's sheet was too fastidious. I had to write every measures chord and properties, number them… It was difficult to write, read, and edit. I've fix this with two major improvements.

First one, I no longer have to number sections to position them in the score! I just give them a length with two parameters: "measure", and "beats". This way a section can last one or several measure, or just 2 beats, or even one measure and 2 beats. This allows me to copy-paste them easily!

Second, the sheet is divided in two parts : sections and score. The first one describe which sections will be used in the track, providing them chords, or modes. It looks like this:

Sheet's sections
You might notice that some sections also have a "modifiers" property. We'll come to that later.

Then there is the "score", which use sections defined above and organize them in the song, with their respective length. Like so:

Sheet's score
"section" refers to the section's position in the array. Not pretty I know, I should use a proper ID, but for what I want it does the job.

In a way, it works like "A", "B", "C", etc parts of a song. There's usually a lot of repeated sections in a music, and it is unnecessary to redefine them every time. Here, the score becomes much more readable, I can edit it edit it easily, and make quick adjustments on a section that will have an impact everywhere!

Roll the dice

Next major improvement: the way the instrument players select their note! Previously, I had to attribute a probability between 0 and 1 to each of the six notes in a scale. Well, not exactly each note, more like a group of note. I had then an algorithm that selected a random float between 0 and 1, then iterated my probabilities and increased a value until the result was above the "dice roll". The probabilities definition looked like that:

var probabilities: Array = [ 
  { 
    "keys": [0, 7], 
    "value": 0.3 
  }, 
  { 
    "keys": [2], 
    "value": 0.2 
  }, 
  { 
    "keys": [4], 
    "value": 0.2 
  }, 
  { 
    "keys": [1,5,6], 
    "value": 0.2 
  }, 
  { 
    "keys": [3], 
    "value": 1 
  } 
] 

This was messy… If you have a hard time understanding it, don't worry: I struggled too! Every time I wanted to edit this, I had to do the math so that the values adds up to 1, and the last should be the difference between 1 and the sum of every others… Urgh, it was not intuitive, and even the algorithm to read that was unnecessarily complex! On top of that, I intended to edit those probabilities during the song to give emphasis to some notes. Oh god, this will quickly get insane… Surely there should be a better way to select a random number between 0 and 6, with different probabilities for each one?

The solution was pretty simple: use scores. What if instead of thinking with percentage, I just give scores to notes, and the ones with the highest have more chance to be selected? Easy to write, edit, and implement! All I have to do to select a random one is calculate the sum of all the scores, select a random value below that, then see which note is picked by iterating on them! And I don't need to make groups anymore! I mean, there's only six notes to score, come on. So the gigantic ugly array above transformed into this:

var default_probabilities: Array = [4,2,5,2,4,3,1]

Alright, again, I'm cheating: instead of associating values with keys, I'm using array position. But come on, look at how easy it is now! If I want the root to be have more importance, I just have to increase the value of the first item. And if I want the 3rd to appear less? It's just directly the third item! This is way more practical to perform tests and tweaks the values.

And you may have connected the dots already: section can alter this probabilities pretty easily too! A section in the sheet can have a "modifiers" property, which is an array that add a value the a note's score. If I have a chord with 7, I can add 3 to the seventh note to add some emphasis on it. Inversely, I noticed that the base wasn't really interesting to hear on the first section, so I decreased its value.

This system allows me to quickly write sections and experiment! But to have interesting melodies, there are still some adjustments to make…

Creating melodies

Selecting random notes with different probabilities sure create harmonious sounds, but hardly what we could call a melody. It can also becomes too chaotic, and a bit unpleasant. So we need to add some rules to improve the quality of the outcome.

First: let's avoid repetition. It's note really fun to hear the same note consecutively too many times. Twice is okay, thrice is a bit pushing the limit, but more?… It feels a bit broken. So we can write this simple rule: after 3 times the same note, the player has to select another one!

Then, too have a consistent melody, we may want to select notes close to each other. At least within a certain interval: if a note is hit less than 0.5 seconds after the previous one, it is considered part of a sentence. Otherwise, it's free to be anything. To select the closest note, we have to possibility: either it is close, so we keep the same octave, either they are far apart, so we either select the next or the previous octave (depending of which note is the highest) to reduce their distance. (Spoiler alert: this is not functional yet! I've implemented it, but just realize that I wasn't comparing the correct values!)

There are some caveats to these rules. First, while it prevents the repetition of a single note, it doesn't prevent the repetition of a succession of note. Meaning that two notes can repeat for a long while. Second, just because notes are close doesn't necessarily creates the feeling of a melody. In fact it can be interesting sometimes to do big jumps! Writing music is much more complex than that, and would require to select more carefully the notes. But that would kinda remove the random aspect of the game. For the better or the worse, the melodies will remain a bit chaotic. But hopefully not so much that they will prevent the listener to enjoy them.


So, how about a demo? Here it comes!

https://t.co/jFDzjFpSW5?amp=1

Notices how when the music jump from A Dorian to C# Minor, the melody remain pretty consistent! It's still a bit weird sometimes, but overall I feel it gives pleasant results. The main issue I have here is the sound balance and the low quality of the pitch shift, which I hope I will be able to fix later.

But for the next step, I want to move on something completely different! So far I've worked on the audio part of the game, but it still need visuals. I have already something in mind, and I'm a bit excited to try it out. So in the next two weeks, I will work on that, and hopefully these devlogs will give you some nice gifs!

Get Bazza Nava

Leave a comment

Log in with itch.io to leave a comment.