{
"cells": [
{
"cell_type": "markdown",
"id": "466074e1",
"metadata": {},
"source": [
"# Guess Scale or Chord from Notes\n",
"\n",
"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."
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "0354aadb",
"metadata": {},
"outputs": [],
"source": [
"import random\n",
"random.seed(44313)\n",
"from omusic.guesser import guess, tabulate_guess\n",
"from omusic.guesser import TEST_SCALES, TEST_SCALES_STANDARD"
]
},
{
"cell_type": "markdown",
"id": "e0795076",
"metadata": {},
"source": [
"Note that `guess` takes two arguments: (a) a set of note names and (b) scales and chords to test against.\n",
"\n",
"The module comes with several options for the latter:\n",
"\n",
"| Option | Included |\n",
"| - | - |\n",
"| `TEST_SCALES_STANDARD` | Major and minor |\n",
"| `TEST_SCALES_MINORS` | Natural, harmonic, and melodic minors |\n",
"| `TEST_SCALES_EXPANDED` | Augmented, diminished, pentatonic, and blues |\n",
"| `TEST_SCALES_EXPANDED` | Augmented, diminished, pentatonic, and blues |\n",
"| `TEST_SCALES_MODES` | From Ionian to Locrian |\n",
"| `TEST_CHORDS` | The (1, 3, 5) triad and sevenths |\n",
"| `TEST_SCALES` | Every scale. Probably has perfect matches for everything. |\n",
"\n",
"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."
]
},
{
"cell_type": "markdown",
"id": "f8a6c0ca",
"metadata": {},
"source": [
"Suppose we are transcribe a song with \"G\", \"E\", and \"C#\". Call guess, then tabulate the result:"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "eb42c1ec",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"| Base | Mode | Matched | Unused | Unmatched |
\n",
"\n",
"\n",
"| C | diminished, half whole | {'C#', 'G', 'E'} | {'A#', 'D#', 'F#', 'C', 'A'} | set() |
\n",
"| C# | diminished, whole half | {'C#', 'G', 'E'} | {'A#', 'D#', 'F#', 'C', 'A'} | set() |
\n",
"| C# | diminished, half whole | {'C#', 'G', 'E'} | {'A#', 'B', 'D', 'F', 'G#'} | set() |
\n",
"| C# | blues minor | {'C#', 'G', 'E'} | {'G#', 'B', 'F#'} | set() |
\n",
"| C# | locrian | {'C#', 'G', 'E'} | {'D', 'A', 'B', 'F#'} | set() |
\n",
"| D | major | {'C#', 'G', 'E'} | {'D', 'A', 'B', 'F#'} | set() |
\n",
"| D | harmonic minor | {'C#', 'G', 'E'} | {'D', 'A', 'F', 'A#'} | set() |
\n",
"| D | melodic minor | {'C#', 'G', 'E'} | {'D', 'A', 'F', 'B'} | set() |
\n",
"| D | diminished, whole half | {'C#', 'G', 'E'} | {'A#', 'B', 'D', 'F', 'G#'} | set() |
\n",
"| D | ionian | {'C#', 'G', 'E'} | {'D', 'A', 'B', 'F#'} | set() |
\n",
"\n",
"
"
],
"text/plain": [
"'\\n\\n| Base | Mode | Matched | Unused | Unmatched |
\\n\\n\\n| C | diminished, half whole | {'C#', 'G', 'E'} | {'A#', 'D#', 'F#', 'C', 'A'} | set() |
\\n| C# | diminished, whole half | {'C#', 'G', 'E'} | {'A#', 'D#', 'F#', 'C', 'A'} | set() |
\\n| C# | diminished, half whole | {'C#', 'G', 'E'} | {'A#', 'B', 'D', 'F', 'G#'} | set() |
\\n| C# | blues minor | {'C#', 'G', 'E'} | {'G#', 'B', 'F#'} | set() |
\\n| C# | locrian | {'C#', 'G', 'E'} | {'D', 'A', 'B', 'F#'} | set() |
\\n| D | major | {'C#', 'G', 'E'} | {'D', 'A', 'B', 'F#'} | set() |
\\n| D | harmonic minor | {'C#', 'G', 'E'} | {'D', 'A', 'F', 'A#'} | set() |
\\n| D | melodic minor | {'C#', 'G', 'E'} | {'D', 'A', 'F', 'B'} | set() |
\\n| D | diminished, whole half | {'C#', 'G', 'E'} | {'A#', 'B', 'D', 'F', 'G#'} | set() |
\\n| D | ionian | {'C#', 'G', 'E'} | {'D', 'A', 'B', 'F#'} | set() |
\\n\\n
'"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tabulate_guess(guess({\"G\", \"E\", \"C#\"},\n",
" TEST_SCALES)[:10],\n",
" tablefmt=\"html\")"
]
},
{
"cell_type": "markdown",
"id": "f33a6e38",
"metadata": {},
"source": [
"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:"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "fbd1be89",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"| Base | Mode | Matched | Unused | Unmatched |
\n",
"\n",
"\n",
"| D | major | {'C#', 'G', 'E'} | {'D', 'A', 'B', 'F#'} | set() |
\n",
"| B | minor | {'C#', 'G', 'E'} | {'D', 'A', 'B', 'F#'} | set() |
\n",
"| C | major | {'G', 'E'} | {'B', 'D', 'F', 'C', 'A'} | {'C#'} |
\n",
"| C# | minor | {'C#', 'E'} | {'D#', 'B', 'F#', 'G#', 'A'} | {'G'} |
\n",
"| D | minor | {'G', 'E'} | {'A#', 'D', 'F', 'C', 'A'} | {'C#'} |
\n",
"| E | major | {'C#', 'E'} | {'D#', 'B', 'F#', 'G#', 'A'} | {'G'} |
\n",
"| E | minor | {'G', 'E'} | {'B', 'F#', 'D', 'C', 'A'} | {'C#'} |
\n",
"| F | major | {'G', 'E'} | {'A#', 'D', 'F', 'C', 'A'} | {'C#'} |
\n",
"| F | minor | {'C#', 'G'} | {'A#', 'D#', 'F', 'C', 'G#'} | {'E'} |
\n",
"| F# | minor | {'C#', 'E'} | {'B', 'F#', 'D', 'G#', 'A'} | {'G'} |
\n",
"\n",
"
"
],
"text/plain": [
"'\\n\\n| Base | Mode | Matched | Unused | Unmatched |
\\n\\n\\n| D | major | {'C#', 'G', 'E'} | {'D', 'A', 'B', 'F#'} | set() |
\\n| B | minor | {'C#', 'G', 'E'} | {'D', 'A', 'B', 'F#'} | set() |
\\n| C | major | {'G', 'E'} | {'B', 'D', 'F', 'C', 'A'} | {'C#'} |
\\n| C# | minor | {'C#', 'E'} | {'D#', 'B', 'F#', 'G#', 'A'} | {'G'} |
\\n| D | minor | {'G', 'E'} | {'A#', 'D', 'F', 'C', 'A'} | {'C#'} |
\\n| E | major | {'C#', 'E'} | {'D#', 'B', 'F#', 'G#', 'A'} | {'G'} |
\\n| E | minor | {'G', 'E'} | {'B', 'F#', 'D', 'C', 'A'} | {'C#'} |
\\n| F | major | {'G', 'E'} | {'A#', 'D', 'F', 'C', 'A'} | {'C#'} |
\\n| F | minor | {'C#', 'G'} | {'A#', 'D#', 'F', 'C', 'G#'} | {'E'} |
\\n| F# | minor | {'C#', 'E'} | {'B', 'F#', 'D', 'G#', 'A'} | {'G'} |
\\n\\n
'"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tabulate_guess(guess({\"G\", \"E\", \"C#\"},\n",
" TEST_SCALES_STANDARD)[:10],\n",
" tablefmt=\"html\")"
]
},
{
"cell_type": "markdown",
"id": "7e385865",
"metadata": {},
"source": [
"Looks like D is the answer!"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.10"
}
},
"nbformat": 4,
"nbformat_minor": 5
}