Introduction
Hey everyone! Thanks to those who still have subscriptions to my newsletter and thanks to those who have been reading them. Please take the time (seconds) to subscribe if you haven’t done so already. It’s free and you’ll receive new articles as I publish them automatically in your email. Welcome to any new readers!
This is my fourth post. The first three posts were about music composition, that is, “creating” music. The first article described my approach to creating music by first starting with lyrics and using these lyrics to create a rhythm, melody and harmony. The second article described my approach to starting with a drum part and using this to create a melody. The last article described my approach to taking a music composition without a drum track and then creating a drum track that “matched” the music composition or captured the “feel or essence” of the musical composition. In this fourth article and the subsequent series of articles, I will present approaches to creating a melody. The first article presented my approach for creating a melody from lyrics. In these articles I will focus on creating a melody from scratch. In my previous compositions, melody creation was essentially a trial-and-error approach subject to certain restrictions or requirements. For example, in one composition I used only whole tone intervals and chords based off that mode. In another composition, I wanted to have several whole-step bends followed by a slide and finally a vibrato. In both of these examples, the process was to try things until the desired effect was achieved. In these upcoming articles, I want to show you how to create melodies (also: riffs, licks, or solos) using music theory, statistics, mathematics, basic AI techniques (e.g., Genetic Algorithms), and the Python programming language.
I chose the phrase “Music Discovery” for this process because I see this as an activity where you start with an initial (random) melody and apply incremental changes until an acceptable melody is obtained. Essentially, you are searching for that great melody that is nearby your initial melody. Define nearby as requiring only minor tweeks to the initial melody to transform it into the good or great melody. It’s a discovery process. I searched the Internet for “Music Discovery” and this is what I found:
The Ugly Truth about Music Discovery
There, I found phrases similar to “finding and/or hearing an artist for the first time”, “linking artists to an audience”, or “linking the audience to new artists”.
This is not the definition I intended for this article. This is more of a marketing of music definition. It’s always wise for someone my age, prior to using a word, to first google it and then consult the Urban Dictionary for potentially embarrassing definitions! My definition of Music Discovery is as follows:
The process whereby an original, previously unknown melody, harmony, or rhythm is revealed to a music composer. The extraction of a melody, a harmony, or a rhythm from the Ether or the Heavens. The detecting, the finding, or the stumbling upon a melody, harmony, or rhythm that was previously unknown to mankind.
In this definition, I assume that all known and unknown music has always existed in some infinite repository in the Ether or the Heavens. Furthermore, only a very small portion of this music has been revealed to mankind. I don’t think of this as big metaphysical library in the sky. Instead, I think of this library as an abstract, mathematical space whose multi-dimensional points correspond to melodies, harmonies and rhythms. My assumption is that the vast majority of these points correspond to gibberish or mediocre melodies, harmonies, and rhythms. I also assume there exists points somewhat randomly located in the multi-dimensional space that correspond to good or even great melodies. Every possible melody, harmony or rhythm that one could compose (i.e., the good, the bad, and the ugly) is a point in this space. Finally, I assume that there exists a finite sequence of melodies (or harmonies, or rhythms) of incremental note changes (i.e., in pitch and in duration) that converge into a much better melody, hopefully a good one or ideally a great melody. The objective of this approach is to first find a reasonable starting point and second to search for a nearby point that corresponds to a good or great point. So, you see, this is a search or optimization problem where you make the appropriate incremental changes to your initial point (melody, rhythm, harmony) to achieve the optimal point (good or great melody).
What’s important here is obtaining initial point close to an optimal point and having the knowledge to search the space for the optimal point. In essence, you’re exploring the space for hidden gems and the closer you start your search to a gem, the more likely you will find or discover it. Finding a starting point in the neighborhood of the gem is just luck, divine inspiration, or a lucky catch on your part. Conducting the search (incremental tuning to eventually converge upon the optimal) is dependent upon the composer’s experience and understanding of music theory. That’s what this article and the following series of articles will be about …. creating an initial melody, harmony, and/or rhythm (MHR) and then creating a sequence of incrementally changed MHRs that converge into a good or great MHR.
In this first article of the series, an algorithm will be entered into a computer program using the Python language. The algorithm will use probability/statistics and some music theory to generate a two-bar random sample of notes and rests. The program will be run five times, producing five two-bar samples. These samples will be entered into a score in the music notation and playback software MuseScore. The samples will be played. Those two-bar samples that don’t sound good will be tweeked just enough to make them ok. Also, some tweeking at the interface between adjacent two-bar samples will be done to make a smooth transition. In subsequent articles, the search method will be refined to produce hopefully better results. Also, other restrictions will be introduced for the search to get more musically pleasing initial results.
Music Discovery Preliminaries and Algorithm
Refer to the figure below. This is the algorithm written in the Python language. This is how this program works:
As shown in line 6, only 1/64, 1/32, 1/16, 1/8, 1/4, and 1/2 note durations will be considered in this program.
As shown in line 8, both notes and rests will be considered in the program.
As shown in line 9, the key of C will be used and all notes in this key from A3 to A5 will be considered.
As shown in line 14, for every possible musical symbol there will be an 80% chance of it being a musical note and a 20% chance of it being a rest.
As shown in lines 9 and 10, each of the different pitches (letters A - G) has an assigned weight or probability of being assigned to a musical note. The actual probability of a pitch being assigned to a note is the ratio of the relative weight shown in line 10 divided by the sum of all the relative weights (150). The probability of C4 being assigned to a note is 20/150 or 0.1333 or 13.33 % chance.
The assumed time signature is 4/4. So, for two bars, there will be a total 8 quarter (1/4 duration) beats. The sum of all the durations (notes and rests) will therefore add to 8 x 1/4 = 2 for the generated two-bar sample. As the durations are assigned to the notes and the rests, the cumulative sum of these durations is checked to ensure that it does not exceed 2. If it does, then an adjustment is made to make the last note or rest produce a total of 2.
Hence, this algorithm randomly generates a note or rest with a random duration and a random pitch. It continues this until the cumulative duration of the generated notes/rests equals 2, which corresponds to two bars with a 4/4 time signature. The notes used are from the key of C. The creation of each note/rest is independent of the value of the previous notes/rests.
For the future articles in this series, the following enhancements are being considered:
Allow for notes outside the key (e.g., the sharps and flats for the key of C)’
Allow for bends, slides, vibratos and tremelos.
Make the value for a note/rest somewhat dependent upon the previous note/rest. This relationship is not present in the algorithm used in this article.
Define a measure for the goodness or greatness of a given two-bar sample so that samples with poor values of goodness can be rejected without human contact. The present algorithm generates the two-bar sample and then the goodness is evaluated by a human listening to it. If it doesn’t sound good, it is tweeked or discarded. By having the algorithm select nearly good as possible samples, less tweeking will be required by the human listening to the sample. Ideally, I could tell it to make the sample sound like Joe Walsh, Zeppelin, Floyd or Spirit. Hey, anything is possible! Image that … an algorithm that measures how similar it is to Joe Walsh tunes and rejects all those that don’t!
Applying the Music Discovery Algorithm
Ok, I ran the Python program (algorithm) five times and got 5 two-bar samples. I put them into a musical score with MuseScore. I copied this sequence of 5 samples and pasted a little later in the score. I then tweeked on those samples that didn’t sound too good to me. I also made changes at the interface between two samples to make them match or sound smoother.
Refer to the figure below. You can see each the original samples labeled. After the bar with the label “modified”, you will see the slightly modified versions of these samples. All I did was reduce large intervals, break up repetitions, and make smoother transitions between adjacent samples. I also discarded to beginning of a couple of the samples. If I were to spend more time, I would rearrange the samples for a better fit and spend some more time making the samples “chord worthy”. That is, raise or lower the pitch of some notes to make it easier to match to a chord.
Here is how it sounds!
Hope you liked this article! Stay tuned for the next in this series of Music Discovery!