Guess Scale or Chord from Notes

The music theory encoded in OMusic allows for some interesting applications. For example, omusic.guesser.guess takes a set of notes, then guesses which scale of chords the notes may be from.

[11]:
import random
random.seed(44313)
from omusic.guesser import guess, tabulate_guess
from omusic.guesser import TEST_SCALES, TEST_SCALES_STANDARD

Note that guess takes two arguments: (a) a set of note names and (b) scales and chords to test against.

The module comes with several options for the latter:

Option

Included

TEST_SCALES_STANDARD

Major and minor

TEST_SCALES_MINORS

Natural, harmonic, and melodic minors

TEST_SCALES_EXPANDED

Augmented, diminished, pentatonic, and blues

TEST_SCALES_EXPANDED

Augmented, diminished, pentatonic, and blues

TEST_SCALES_MODES

From Ionian to Locrian

TEST_CHORDS

The (1, 3, 5) triad and sevenths

TEST_SCALES

Every scale. Probably has perfect matches for everything.

Try not to use scales and TEST_CHORDS together: because scales are larger, the default sorting criteria will prioritise them. Consider using sort_key=matched_percent instead.

Suppose we are transcribe a song with “G”, “E”, and “C#”. Call guess, then tabulate the result:

[12]:
tabulate_guess(guess({"G", "E", "C#"},
                     TEST_SCALES)[:10],
               tablefmt="html")
[12]:
Base Mode Matched Unused Unmatched
C diminished, half whole{'C#', 'G', 'E'}{'A#', 'D#', 'F#', 'C', 'A'}set()
C# diminished, whole half{'C#', 'G', 'E'}{'A#', 'D#', 'F#', 'C', 'A'}set()
C# diminished, half whole{'C#', 'G', 'E'}{'A#', 'B', 'D', 'F', 'G#'} set()
C# blues minor {'C#', 'G', 'E'}{'G#', 'B', 'F#'} set()
C# locrian {'C#', 'G', 'E'}{'D', 'A', 'B', 'F#'} set()
D major {'C#', 'G', 'E'}{'D', 'A', 'B', 'F#'} set()
D harmonic minor {'C#', 'G', 'E'}{'D', 'A', 'F', 'A#'} set()
D melodic minor {'C#', 'G', 'E'}{'D', 'A', 'F', 'B'} set()
D diminished, whole half{'C#', 'G', 'E'}{'A#', 'B', 'D', 'F', 'G#'} set()
D ionian {'C#', 'G', 'E'}{'D', 'A', 'B', 'F#'} set()

There are several good matches; half whole diminished C is unlikely to be the answer. Time to use your discretion: if the song sounds like a major, try to match for major and minor scales only:

[13]:
tabulate_guess(guess({"G", "E", "C#"},
                     TEST_SCALES_STANDARD)[:10],
               tablefmt="html")
[13]:
Base Mode Matched Unused Unmatched
D major {'C#', 'G', 'E'}{'D', 'A', 'B', 'F#'} set()
B minor {'C#', 'G', 'E'}{'D', 'A', 'B', 'F#'} set()
C major {'G', 'E'} {'B', 'D', 'F', 'C', 'A'} {'C#'}
C# minor {'C#', 'E'} {'D#', 'B', 'F#', 'G#', 'A'}{'G'}
D minor {'G', 'E'} {'A#', 'D', 'F', 'C', 'A'} {'C#'}
E major {'C#', 'E'} {'D#', 'B', 'F#', 'G#', 'A'}{'G'}
E minor {'G', 'E'} {'B', 'F#', 'D', 'C', 'A'} {'C#'}
F major {'G', 'E'} {'A#', 'D', 'F', 'C', 'A'} {'C#'}
F minor {'C#', 'G'} {'A#', 'D#', 'F', 'C', 'G#'}{'E'}
F# minor {'C#', 'E'} {'B', 'F#', 'D', 'G#', 'A'} {'G'}

Looks like D is the answer!