This is another attempt to use the chord changes from Balloon Drum Music in another context. Scored this time for Bass Flute, Finger Piano, Balloon Drums, Oboe, Clarinet, French Horn and Bassoon. This is just the vamp on the verse in 16/9 otonality.
This piece is made up of 17 short pieces based on a journey through the tonality diamond. They each consist of a vamp and a bridge. The vamp is in the same key for several measures, and the bridge follows a set of rapid chord changes as shown in the list below.
otonality on 16:9 - B♭
otonality on 8:7 - D+
utonality on 3:2 - G♮
otonality on 16:15 - D♭
utonality on 4:3 - F♮
otonality on 1:1 - C♮
utonality on 7:6 - E♭
otonality on 16:9 - B♭
utonality on 5:4 - E♮
I’ve split the 16 notes in the tonality diamond scale into four tetrads (four note chords).
Tetrad otonal ratios
A 1:1 5:4 3:2 7:4
B 9:8 11:8 13:8 15:8
C 17:16 24:16 25:16 29:16
D 19:16 23:16 27:16 31:16
Tetrad utonal ratios
A 8:7 4:3 8:5 1:1
B 6:15 16:13 16:11 16:9
C 32:29 32:25 32:21 32:17
D 32:31 32:27 32:23 32:19
The piece is is based on the vamp and bridge on each of the four tetrads, one at a time. The first one is based on the four notes of the ‘A’ tetrad, 1:1, 5:4, 3:2, 7:4 relative to the root key of otonality on 16:9 – B♭. The bridge is then played on the 8 keys in the list above. The next time, I play the vamp on the ‘B’ tetrad, 9:8 11:8 13:8 15:8, and the bridge is based on the same chord changes listed above, but on the ‘B’ triads on those o/u tonalities. Then we move to the ‘C’ and ‘D’, and back to the same series for a total of 17 short pieces across the cycle of tetrads. Each piece might start with a short set of chords to introduce the tonality, and end with another to close the piece out. Or it might just start right up at a faster pace. When it has a short intro, it sets the mood for that piece, based on chords in the chosen tetrad. There is never a time when more than four notes are played at the same time, except for different octaves. Some of the pieces are as short as 17 seconds, others are as long as 90 seconds or so. They all have a different rhythmic structures based on masking and arpeggiations.
The piece is scored for different collections of instruments. Each of the 17 pieces can include a woodwind quintet, finger pianos, and balloon drums in different combinations.
Today’s work results from trying to isolate the variables that create the most interesting set of five dances based on the TonicNet Chorales. In this version the keys are F# minor, B minor, E major, A major and D major, tuned in Kellner’s Well Temperament. As before, I chose them because they have many segments where the notes are not in the root key of the chorale. There are dozens of variables in the creation of the dances from the original synthetic chorale material, but the main control points can be found by scanning the logs using grep:
egrep "mask.shape|factors|repeat_count|mask_zeros|midi_file" open_samples3-t46.log
This produces the following output, which includes the key values for important variables chosen by the algorithm from a set of ranges and probabilities:
The dances are scored for finger piano, balloon drum, and Ernie Ball Super Slinky Guitar strings on an old Gibson humbucking pickup.
This one is based on chorales in a circle of fifths: The chorales start out in F# minor and then B minor, E major, A major, and the final one in D major. It has a nice bouncy feel. I added some Balloon Drums.
I’ve been using Pandas dataframes to analyze the synthetic chorales I’ve created. I started by generating 500 of them. Then I use lots of python code to learn more about the chorales. Each chorale produced by the TonicNet GRU model consists of a variable number of time steps, each consisting of Soprano, Alto, Tenor, & Bass voices expressed in MIDI note numbers. Some of those time steps have notes that are not in the dominant root key of the chorale. These are often leading tones, or suspensions, or diminished chords, augmented, and so forth. Bach used these chords to produce tension, that was always resolved in a cadence of some sort. The TonicNet model was trained on hundreds of real Bach chorale, which are further augmented by transpositions of the existing chorales to all twelve keys, so that 1,968 chorales were used as input to the model. What is amazing to me is that the final model is only 4.9 MB in size. The Coconet model ended up as 1.6 GB in size.
I like those interesting sections where the chorale uses notes not in the root key for many time steps. I wrote some python code that builds a list of the number of voices that are not in the root key of the chorale, one value for every time step:
zero_one_q = np.array([not_in_key(time_step, root, mode) for time_step in chorale_tr])
It basically calls another python function that looks at each time step and reports the number of voices not in the root key of the chorale. Once I have that array, I can build a list of sections that have notes not in the root key. I run every chorale through that routine so that I have information about each chorale that can be used to select for certain characteristics, such as lots of steps in a row not in the root key, or many sections of notes that are not in the root key.
Today’s results used a Pandas data frame to find chorales that met these characteristics:
I did the same for A minor. The value of these measures is that it produces a final result of five preludes that in total lasts about 15 minutes. That is in contrast with an earlier version that had many more challenging steps and went on for an hour and ten minutes. I used Kellner’s Well Temperament.
The algorithm I use for most of my pieces is that first I find all the time_steps that contain notes not in the key of the chorale. Then I go about making those sections longer using a variety of elongation techniques. The code looks like this:
probability = ([0.2, 0.1, 0.6, 0.1, 0.15, 0.04, 0.05, 0.1, 0.1])
if type == 'any': type = rng.choice(['tile', 'repeat', 'tile_and_reverse', 'reverse_and_repeat',
'shuffle_and_tile', 'tile_and_roll', 'tile_and_repeat', 'repeat_and_tile',
'tile_reverse_odd'], p = probability)
I let the system choose which type of elongation. But over time, it’s certain to choose ’tile_and_reverse’ about 60% of the time. That is accomplished with this line of code:
clseg = np.flip(np.tile(clseg, factor), axis = 1)
This basically repeats a section of the piece, consisting of a certain number of voices performing over time_steps, then reverses the repeated sections. Retrograde.
All that is to say that the music is predetermined probabilistically, but not explicitly.
But if a certain chorale is dominated by ranges of the chorale that include notes not in the root key of the chorale, then there are a lot of repetitions. For this piece I chose five chorales that have that condition. So the extensions go on for a long time. In fact, in this prelude, each chorale lasts about 20 minutes, and there are five of them. You can do the math. I wouldn’t recommend this unless you like repetitive sounding music. Maybe skip around.
Tuned in Kellner’s Well Temperament.
Today’s contribution uses synthetic chorales manufactured by a TonicNet model in the keys of E♭ major and C♮ minor, which use the same notes. This one is also tuned using Kellner’s Well Temperament. Scored for finger piano. I set it up so that all the five chorales would be about the same length, and I adjusted to tempos to ensure that. TonicNet doesn’t limit itself to 32 1/16th notes the way Coconet does, so I get to vary the length as a bonus.
Each the chorales length is stated in the table below in thousands of MIDI ticks. I don’t understand MIDI, so I just puttered around until I found five that were of different numbers of MIDI ticks. That resulted in three fast and 3 slow preludes, alternating between major and minor.
# key E♭M Cm E♭M Cm E♭M
# k note 16k 12k 23k 23k 11k
# speed f s f f s
# index 231 371 222 371 234
You can see from the image below that the middle one is the most frantic. Reminds me of Glenn Gould’s 1955 Goldberg Variation 1. Speed demon, that guy,
These are based on four of the synthetic chorales that I manufactured using the TonicNet GRU deep neural network model. They are in A minor, C major, A minor, C major, and repeat the first at the end in A minor. Each uses a different arpeggiation matrix. The tempos are based on how many notes in the synthetic chorale. With more notes, the tempo is faster, with fewer notes, it’s slower. I made 500 chorales, and then selected some that were of a moderate length. I looked for those in complementary major and minor keys, settling on A minor and C major. A different selection criteria would have different results. This is referred to in the deep learning literature as “cherry picking”. But I’m sure Bach would approve.
This is one that uses five synthetic chorales manufactured by the TonicNet model, all in the key of F# minor. It’s scored for solo finger piano. There’s a short pause between each chorale. The tuning is Kellner’s Well Temperament. I took the idea from Bach’s Well Tempered Clavier Prelude #1, where he moved through a set of chords one measure per chord. That’s what I do with the synthetic chorale. First I extend it to 4 times normal length, then arpeggiate it with a matrix of 24 1/16th notes, with zeros:ones ratio of 9:4. This ensures that there are more zeros than ones, so more notes are set to zero and therefore missing. This results in some interesting arpeggiations. I also extend some of the octaves up and down a bit. It’s kind of like if Philip Glass used Bach chord progressions instead of his own unique ones.
Today’s submission is based on a chorale synthesized by TonicNet, created by Omar Reacha. His paper,
Improving Polyphonic Music Models with Feature-Rich Encoding from 26 Nov 2019 uses a type of deep neural network called the Gated Recurrent Unit to generate very nice Bach chorales. Here is the Paper and Code.
He used that network to create a database of 500 synthetic chorales in his next paper,
JS Fake Chorales: a Synthetic Dataset of Polyphonic Music with Human Annotation from 3/31/2022. Here is that paper, code, and a web page that generates a fake chorale while you wait.
I used some python code to analyze the resulting 500 MIDI files to find those that met certain criteria:
- Rather short, around 8 measures
- Rather high pitch entropy, that is they frequently contain pitches that are not in the key of the chorale
The top scores went to chorales number 35, 268, 107, and 121, in the keys of G minor, F# major, E minor, and F# major respectively.
I put them through some of my python programs that lengthen, repeat, and transform sections based on the pitch entropy of the time steps. This enables me to linger over suspensions and harmonic transitions using different manipulations of the notes.
The piece is scored for a large string orchestra of about 256 string instruments: violins, violas, cellos, and double basses. I include samples of each instrument playing without vibrato, with vibrato, martele, and pizzicato. The piece starts out with everyone playing at the same time, then moves to sections that are only one type of sample. They come back together after several sections to all play at once.
I used a tuning developed by Herbert Anton Kellner, which in the Scala repository is referred to as kellner.scl Herbert Anton Kellner’s Bach tuning. 5 1/5 Pyth. comma and 7 pure fifths. Since I didn’t know what key would end up chosen, I wanted to pick a tuning that could handle almost any key.
There is a separation between each of the four chorales. Just a brief pause.