Skip to content

sadiela/voiceleading-rl

Repository files navigation

Project Description

This project is focused on voice leading (also called part writing) in tonal harmony. Tonal harmony has a vocabulary consisting of triads and 7th chords and a grammar consisting of the ways in which the chords are selected (harmonic progression) and connected (voice leading). The basic task in this project is to do voice leading given a harmonic progression, following the conventions and norms of tonal composers. This will require formulating the voice leading problem (rewards, state space/features) so that reinforcement strategies like value iteration can be applied. Once the problem has been properly translated, several reinforcement learning schemes can be applied and evaluated.

We implement three models each designed to accomplish a slightly different task: a voicing model, a free model, and a melody harmonization model.

Voicing Model:

  1. Harmonic progression is provided, algorithm need only provide the voicings
  2. We consider only harmonic progressions in the key of C major
  3. We restruct the range of each part

Free Model

  1. Algorithm provides the voicings as well as a chord progression
  2. We consider only harmonic progressions in the key of C major
  3. We restruct the range of each part

Melody Harmonizaton Model

  1. Algorithm is provided a melody. It picks chords (with proper voice leading) that fits the given input.

To Do:

  1. Rule-breaking functions

    a. Voice crossing

    b. Leaps --> augmented intervals, 7ths, leaps larger than an octave

    c. Parallel motion (parallel 5ths and octaves); have to check all 6 pairs!

    d. Direct 5ths: outer parts move in the same direction into a P5 or P8 with a leap in the soprano part

    e. Illegal common tones

    f. Illegal leading tone resolutions

    g. Illegal 7th approaches/resolutions

  2. Create "training set" of chord progressions and melodies

  3. Function to convert algorithm output to MIDI

All other rules (spacing, ranges) are taken care of by the state space definition

Data Structures

A triad chord is a set of three notes (chord tones). There are seven triad chords in the key of C major. Each of these chords has several legal voicings.

A "voicing" is a list of four MIDI pitches [b,t,a,s] sorted from lowest to highest. They denote the pitches taken by the bass, tenor, alto, and soprano parts. The voicing for a given chord must contain at least one copy of each note in the triad chord, as well as one additional note that is a double of one of the chord tones. Note that there are always 4 pitches, but two of them may be identical.

We define a dictionary state_indices that assigns an index to each voicing (as defined above). This allows us to use the state indices in our Q-learning algorithm.

We define a state dictionary that contains all legal states given our problem constraints. They are organized by chord number. Thus, state_dict[chord_num] contains a list of legal voicing indices for the given chord.

Algorithm

The learning agent is defined in the QLearningAgent class. The typical Q-learning update is given by:

Q(state,action) = Q(state,action) + self.alpha*(reward+gamma*max(Q(next_state, actions))- Q(state,action))

In this problem, there are no actions. Another way of looking at it is the action is just what state you transition to next.

The other main difference between this problem and those covered in class is that we have rewards associated with state pairs instead of state action pairs. A state by itself has no associated reward.

We can reformulate the problem as follows:

  • We consider our "actions" to be the next state that agent transitions to. Thus, if there are n states, there are also n actions.
  • Our Q-value table is nxn

Listening

About

RL Applied to Tonal Harmony

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published