{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\"FMP\"\n", "\"AudioLabs\"\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\"C5\"\n", "

Musical Scales and Circle of Fifths

\n", "
\n", "\n", "
\n", "\n", "

\n", "Following Section 5.1.2 of [Müller, FMP, Springer 2015], we introduce in this notebook some basic facts on musical scales and the circle of fifths.\n", " \n", "

" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Introduction\n", "\n", "Besides intervals and chords, we now consider another important musical construct that is referred to as a **musical scale**. Again, adopting a rather simplistic view, a scale can be regarded as a set of notes, where the elements are typically ordered by ascending pitch. While a **chord** may be thought of as a **vertical structure**, a **scale** is usually associated to **horizontal structures**. Assuming the principle of octave equivalence, scales typically span a single octave, with higher or lower octaves simply repeating the pattern. In this way, a musical scale can be regarded as a division of the octave space into a certain number of **scale steps**, where each scale step is an interval between two successive notes." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Chromatic Scale\n", "\n", "As first example, we consider the [twelve-tone equal-tempered scale](../C1/C1S1_MusicalNotesPitches.html), where an octave is subdivided into twelve scale steps. This scale is also referred to as **chromatic scale**. In this case, all scale steps correspond to the same interval having a size of one semitone (or $100$ [cents](../C1/C1S3_FrequencyPitch.html)). Due to enharmonic equivalence, there are various spellings and score notations to represent a chromatic scale. Two of them are shown in the following figure. Furthermore, we provide a piano recording as well as a synthesized version of the chromatic scale (generated in the next code cell).\n", "\n", "\"FMP_C5_F08\"\n", "
\n", "" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "execution": { "iopub.execute_input": "2024-02-15T08:58:16.141472Z", "iopub.status.busy": "2024-02-15T08:58:16.141115Z", "iopub.status.idle": "2024-02-15T08:58:16.982634Z", "shell.execute_reply": "2024-02-15T08:58:16.982138Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Chromatic scale\n" ] }, { "data": { "text/html": [ "\n", " \n", " " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import numpy as np\n", "import IPython.display as ipd\n", "\n", "def generate_sinusoid_scale(pitches=[69], duration=0.5, Fs=4000, amplitude_max=0.5):\n", " \"\"\"Generate synthetic sound of scale using sinusoids\n", "\n", " Notebook: C5/C5S1_Scales_CircleFifth.ipynb\n", "\n", " Args:\n", " pitches (list): List of pitchs (MIDI note numbers) (Default value = [69])\n", " duration (float): Duration (seconds) (Default value = 0.5)\n", " Fs (scalar): Sampling rate (Default value = 4000)\n", " amplitude_max (float): Amplitude (Default value = 0.5)\n", "\n", " Returns:\n", " x (np.ndarray): Synthesized signal\n", " \"\"\"\n", " N = int(duration * Fs)\n", " t = np.arange(0, N) / Fs\n", " x = []\n", " for p in pitches:\n", " omega = 2 ** ((p - 69) / 12) * 440\n", " x = np.append(x, np.sin(2 * np.pi * omega * t))\n", " x = amplitude_max * x / np.max(x)\n", " return x\n", "\n", "duration = 0.25\n", "Fs = 4000\n", "pitches = [60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72]\n", "x = generate_sinusoid_scale(pitches=pitches, duration=duration, Fs=Fs)\n", "print('Chromatic scale', flush=True)\n", "ipd.display(ipd.Audio(data=x, rate=Fs))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Major and Minor Scale\n", "\n", "In the following, we only consider scales that are subsets of the chromatic scale, where the scale steps can be specified in semitones. In the context of scales, the minor second (one semitone) is also referred to as a **half step** and the major second (two semitones) as a **whole step**. As with chords, there are two scale types that are of particular importance in Western music theory. The first scale type is known as a **major scale**, which is made up of seven notes and a repeated octave. The first note of a major scale is \n", "called the **key note** of the scale. Starting with the key note, the sequence of intervals between the successive notes of a major scale is as follows (using C4 as key note): \n", "\n", "\"FMP_C5_F09a\"\n", "
\n", "\n", "\n", "The chroma name of the key note also determines the name of the scale. For example, the major scale starting with a $\\mathrm{C}$ is called the $\\mathrm{C}$-major scale. Sometimes, the bold character $\\mathbf{C}$ (as used for [chords](../C5/C5S1_Chords.html)) is also used as an abbreviation to refer to the scale. The other major scales are then obtained by cyclically shifting the $\\mathrm{C}$-major scale. The notes of a major scale are given names, also known as **scale degrees**, to specify their positions relative to the key note. The key note is also called the **tonic**, which is the main note of the scale. The fourth note of the scale is called the **subdominant** and the fifth note the **dominant**. The remaining names are indicated in the following figure:\n", "\n", "\"FMP_C5_F09b\"\n", "
\n", "\n", "The second scale type we consider is known as the (natural) **minor scale**. Similar to a major scale, a minor scale consists of seven notes and a repeated octave. This time, however, the sequence of intervals between the notes is as follows (using C4 as key note):\n", "\n", "\"FMP_C5_F09a\"\n", "
\n", "\n", "\n", "Again, there are twelve minor scales with naming conventions similar to those of the [minor chords](../C5/C5S1_Chords.html). Both major and minor scales can be subsumed under the general term **diatonic scale**, which is (by definition) a seven-pitch scale with five whole steps and two half steps for each octave, where the two half steps are separated from each other by either two or three whole steps.\n", "\n", "In the following code cell, we generate a synthesized version of the $\\mathrm{C}$-major scale and $\\mathrm{C}$-minor scale, respectively. " ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "execution": { "iopub.execute_input": "2024-02-15T08:58:17.006605Z", "iopub.status.busy": "2024-02-15T08:58:17.006319Z", "iopub.status.idle": "2024-02-15T08:58:17.022049Z", "shell.execute_reply": "2024-02-15T08:58:17.021435Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "C-major scale\n" ] }, { "data": { "text/html": [ "\n", " \n", " " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "C-minor scale (natural)\n" ] }, { "data": { "text/html": [ "\n", " \n", " " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "duration = 0.5\n", "\n", "x_maj = generate_sinusoid_scale(pitches=[60, 62, 64, 65, 67, 69, 71, 72], duration=duration, Fs=Fs)\n", "x_min = generate_sinusoid_scale(pitches=[60, 62, 63, 65, 67, 68, 70, 72], duration=duration, Fs=Fs)\n", "\n", "print('C-major scale', flush=True)\n", "ipd.display(ipd.Audio(data=x_maj, rate=Fs))\n", "print('C-minor scale (natural)', flush=True)\n", "ipd.display(ipd.Audio(data=x_min, rate=Fs))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Further Scales\n", "\n", "There are many more scales used in Western music and beyond. For example, besides the minor scale introduced above (also referred to as the **natural minor** scale), there are other types of minor scales called the **harmonic minor** and **melodic minor** scale. The notes of the harmonic minor scale are the same as the natural minor except that the seventh degree is raised by one semitone, resulting in an [augmented second](../C5/C5S1_Intervals.html) between the sixth and seventh degrees. We have already mentioned the chromatic scale, which involves twelve pitches. There are other scales such as the **pentatonic scale** consisting of five pitches, the **whole tone scale** consisting of six pitches, or the **octatonic scale** (diminished scale) consisting of eight pitches. In the following code cell, we generate synthesized versions of these scales. \n", "\n", "\n", "Harmonic minor scale (7 pitches + octave):\n", "
\n", "\"FMP_C5_F06\"\n", "
\n", "\n", "
\n", "\n", "Pentatonic scale (5 pitches + octave):\n", "
\n", "\"FMP_C5_F06\"\n", "
\n", "\n", "
\n", "\n", "Whole tone scale (6 pitches + octave):\n", "
\n", "\"FMP_C5_F06\"\n", "
\n", "\n", "
\n", "\n", "Octatonic scale (8 pitches + octave):\n", "
\n", "\"FMP_C5_F06\"\n", "
\n", " " ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "execution": { "iopub.execute_input": "2024-02-15T08:58:17.024536Z", "iopub.status.busy": "2024-02-15T08:58:17.024349Z", "iopub.status.idle": "2024-02-15T08:58:17.047908Z", "shell.execute_reply": "2024-02-15T08:58:17.047473Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Harmonic minor scale (7 pitches + octave)\n" ] }, { "data": { "text/html": [ "\n", " \n", " " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "Pentatonic scale (5 pitches + octave)\n" ] }, { "data": { "text/html": [ "\n", " \n", " " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "Whole tone scale (6 pitches + octave)\n" ] }, { "data": { "text/html": [ "\n", " \n", " " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "Octatonic scale (8 pitches + octave)\n" ] }, { "data": { "text/html": [ "\n", " \n", " " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "duration = 0.5\n", "\n", "x_mh = generate_sinusoid_scale(pitches=[60, 62, 63, 65, 67, 68, 71, 72], duration=duration, Fs=Fs)\n", "x_p = generate_sinusoid_scale(pitches=[60, 62, 64, 67, 69, 72], duration=duration, Fs=Fs)\n", "x_w = generate_sinusoid_scale(pitches=[60, 62, 64, 66, 68, 70, 72], duration=duration, Fs=Fs)\n", "x_o = generate_sinusoid_scale(pitches=[60, 61, 63, 64, 66, 67, 69, 70, 72], duration=duration, Fs=Fs)\n", "\n", "print('Harmonic minor scale (7 pitches + octave)', flush=True)\n", "ipd.display(ipd.Audio(data=x_mh, rate=Fs))\n", "print('Pentatonic scale (5 pitches + octave)', flush=True)\n", "ipd.display(ipd.Audio(data=x_p, rate=Fs))\n", "print('Whole tone scale (6 pitches + octave)', flush=True)\n", "ipd.display(ipd.Audio(data=x_w, rate=Fs))\n", "print('Octatonic scale (8 pitches + octave)', flush=True)\n", "ipd.display(ipd.Audio(data=x_o, rate=Fs))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Circle of Fifths\n", "\n", "One characteristic property of diatonic scales is that they can be obtained from a chain of six successive perfect fifth intervals. For example, the $\\mathrm{C}$-major scale is obtained from an ascending chain of six perfect fifths starting with $\\mathrm{F}$:\n", "\n", "\\begin{equation}\n", " \\mathrm{F}-\\mathrm{C}-\\mathrm{G}-\\mathrm{D}-\\mathrm{A}-\\mathrm{E}-\\mathrm{B}.\n", "\\end{equation}\n", "\n", "\n", "\n", "Being the most consonant non-octave interval, the fifth interval plays a particularly important role when relating notes, chords, and scales. All notes being related by fifths gives a diatonic scale a degree of coherence and balance. Furthermore, these fifth relationships also make it possible to relate entire musical scales. This leads us to the famous **circle of fifths**, which is a visual representation of the relationships among the twelve tones of the chromatic scale and the associated major and minor scales. Intuitively, the circle of fifths reflects the degree of \"musical\" similarity between different scales—the closer two scales are located on the circle, the more they share in terms of tonal material. \n", "\n", "\"FMP_C5_F10\"\n", "\n", "In the following recording, the tonic (key note) of each scale is played going around the circle of fifths in a clockwise fashion:\n", "\n", "\\begin{equation} \\mathrm{C}-\\mathrm{G}-\\mathrm{D}-\\mathrm{A}-\\mathrm{E}-\\mathrm{B}-\\mathrm{G}^\\flat-\\mathrm{D}^\\flat-\\mathrm{A}^\\flat-\\mathrm{E}^\\flat-\\mathrm{B}^\\flat-\\mathrm{F}\n", "\\end{equation}\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Musical Keys\n", "\n", "More formally, the circle of fifths represents the relations between musical **keys**—a concept that is closely connected to major and minor scales. While a scale is an ordered set of notes typically used in a key, the key is the center of gravity, established by particular chord progressions. At the top of the circle of fifths, there is the $\\mathrm{C}$-major key. The notes of the corresponding $\\mathrm{C}$-major scale, which correspond to the white keys of a piano keyboard, do not require any **accidental** ($\\sharp$, $\\flat$) when encoded in Western music notation. As a result, the key signature of $\\mathrm{C}$ major has no flats or sharps. The $\\mathrm{A}$-minor key, whose corresponding scale consists of the same seven notes, shares the same key signature with $\\mathrm{C}$-major. In general, for each major key there is a minor key whose corresponding scales share the same notes. This relationship is referred to as a **relative relationship**. In the circle of fifths shown above, the major keys are noted outside the circle, whereas the corresponding relative minor keys are noted inside the circle.\n", "\n", "Starting with the $\\mathrm{C}$-major key at the top of the circle, one obtains the other keys proceeding in a **clockwise fashion** by **ascending fifths**. The next key is the $\\mathrm{G}$-major key, whose corresponding scale shares six notes with the $\\mathrm{C}$-major scale; only the $\\mathrm{F}$ in $\\mathrm{C}$ major becomes an $\\mathrm{F}^\\sharp$ in $\\mathrm{G}$ major. This introduces a sharp in the key signature for $\\mathrm{G}$ major. The same kind of relations hold between any two subsequent keys or scales along the circle of fifths. Proceeding one fifth upwards changes one note of the scale and introduces one additional sharp in the key signature. Repeating this process twelve times in the equal-tempered case, one returns to the original $\\mathrm{C}$-major, thus closing the circle (when assuming enharmonic equivalence).\n", "\n", "Similarly, one can travel along the circle in a **counterclockwise fashion** by descending fifths, which corresponds to **ascending fourths**. Proceeding in a **circle of fourths** introduces an additional flat in the resulting key signature.\n", "\n", "In the following table, we provide a synthesized version of all $24$ major and minor scales ordered along the circle of fifth. " ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "execution": { "iopub.execute_input": "2024-02-15T08:58:17.050474Z", "iopub.status.busy": "2024-02-15T08:58:17.050284Z", "iopub.status.idle": "2024-02-15T08:58:17.372348Z", "shell.execute_reply": "2024-02-15T08:58:17.371783Z" } }, "outputs": [ { "data": { "text/html": [ "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
MajorMinor
0CAm
1GEm
2DBm
3AF$^\\sharp$m
4EC$^\\sharp$m
5BG$^\\sharp$m
6F$^\\sharp$D$^\\sharp$m
7D$^\\flat$B$^\\flat$m
8A$^\\flat$Fm
9E$^\\flat$Cm
10B$^\\flat$Gm
11FDm
12CAm
" ], "text/plain": [ "" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import pandas as pd\n", "from collections import OrderedDict\n", "\n", "duration = 0.25\n", "\n", "scale_major = np.array([60, 62, 64, 65, 67, 69, 71, 72])\n", "scale_minor = np.array([57, 59, 60, 62, 64, 65, 67, 69])\n", "scale_major_name = ['C','G','D','A','E','B','F$^\\sharp$',\n", " 'D$^\\\\flat$','A$^\\\\flat$','E$^\\\\flat$','B$^\\\\flat$','F','C',]\n", "scale_minor_name = ['Am','Em','Bm','F$^\\sharp$m','C$^\\sharp$m','G$^\\sharp$m','D$^\\sharp$m',\n", " 'B$^\\\\flat$m','Fm','Cm','Gm','Dm','Am',]\n", "\n", "scale_major_list = []\n", "for i in range(13):\n", " x = generate_sinusoid_scale(pitches=scale_major, duration=duration, Fs=Fs)\n", " scale_major_list.append(x)\n", " scale_major += 7\n", " if scale_major[-1] > 80:\n", " scale_major -= 12\n", " \n", "scale_minor_list = []\n", "for i in range(13):\n", " x = generate_sinusoid_scale(pitches=scale_minor, duration=duration, Fs=Fs)\n", " scale_minor_list.append(x)\n", " scale_minor += 7\n", " if scale_minor[-1] > 80:\n", " scale_minor -= 12\n", " \n", " \n", "audio_tag_html_list_major = []\n", "for i in range(13):\n", " audio_tag = ipd.Audio(scale_major_list[i], rate=Fs)\n", " audio_tag_html = audio_tag._repr_html_().replace('\\n', '').strip()\n", " audio_tag_html = audio_tag_html.replace('