Fixing the “Rest” Issue

by

in

We recognized that our coding of rests as zeroes presented searching errors relatively early, but we put off thinking about a solution off until we needed to finalize the database in preparation for machine learning. We had several options to solve it. The first was as follows: Construct another string of numbers that parallels each tune, one number per tuple (a pitch differential and a duration ratio). The numbers would all be zero unless the tuple contained a rest, when the number would be set at the pitch differential before and after the rest. The idea was to construct a simple list that the searching program would consult in case it came up with a match that happened to be a false match because of a rest.

To show what this would look like, recall the previous post’s example of a tune with a rest:

[72, 1] [-12, 1] [12, 1] [-72, 1] [70, 1] [-12, 1] [12, 1]

The idea would be to create a parallel list that looks like this:

0 0 0 +2 0 0 0

The list is made up of zeroes except for the fourth element, a +2, which signifies a difference of a major second interval between the note prior to the rest and the note immediately after the rest.  In the example, a “C” precedes the sixteenth note rest” and a “D” follows it.  The difference between a “C” and a “D” in MIDI is +2.

This solution works well enough for purposes of checking to see if a search match is a true match or a false one simply by examining the pitch difference before and after each rest and then making sure it matched the number in this new list.  

However, for machine learning purposes, this solution is a kludge and rather awkward.  We’re asking the machine to learn that this list is relevant only for tunes with rests in them, and to figure out that the non-zero numbers are pitch differences.  More importantly, it adds a string of data, most of which is made up of zeroes, for every tune in the database.  We would end up with having to store in memory another 80,000+ lines of data.

It would be better if we simply included the relevant information about the notes before and after a rest in the tune itself.  The second solution we considered was simply to include the word “REST” in place of the zeroes.  That would be easily spotted by humans and instantly interpretable.  However, it means mixing text in with numbers and while Python handles that situation, it does mean extra coding to make sure we know what we’re dealing with.  We decided we needed a number to represent rests.

After considering some possibilities, we settled, somewhat arbitrarily, on the following:  Code rests as -999.  The “-999” is arbitrary.  It could be any number that doesn’t confuse either humans or machines with a different interpretation.  

We selected “-999” because there’s no MIDI jump that high.  Standard MIDI numbers run from 1 to 127.  That means the largest possible pitch differential between two played notes is 126, and that suggests a number greater than 126.  We could have used 127, but that’s not easily spotted by a human.  We went with 999 because it’s easy to spot, and added the minus sign to make it even easier.  

Each -999 is then followed by the same duration ratio to complete the tuple.  However, the first element in the next tuple is the pitch differential between the note immediately before the rest and the note immediately after.  In our example above, this is a “2”.  Thus, the line of music from above would appear as follows:

[72, 1] [-12, 1] [12, 1] [-999, 1] [2, 1] [-12, 1] [12, 1]

The only difference is the [-999, 1] [2, 1] in the center of the line.  The advantage of this solution is that we have managed to include the rest information without adding any new memory requirements, as this line is exactly the same length as the original example.  

That concludes the “rest” topic.  Next time, we will look at something called “hashing” and how it helps us get prepared for understanding how to know how “close” one tune is to another tune.