Musical Scale Modes

Mathematician and educator John Baez has been putting out an excellent series of posts about music theory on his blog. The most recent, the seventh, is about how you can generate scales by picking out piano notes in intervals of fifths. What’s interesting is that you can generate all seven major scale modes in each of the twelve keys (a total of 84 scales).

It’s very cool (and new to me how this works out), and John asked if any of his readers would be interested in creating a table of all 84 rows. That’s exactly the sort of little project that often catches my eye.

A new and different problem to solve!

Anyway, as a simple way to present the output of my little code project, I thought I’d put it all in this post. The code generates four types of output: listing to the console, writing a text file, writing an HTML file, and writing a PNG image file.

This won’t make much sense without reading John’s post(s), so here they are:

You’ll definitely need to read the last one to understand what the stuff below means. All of them comprise a really good introduction to music theory with the bonus of lots of included YouTube links to music theory channels. Highly recommended for anyone interested in the topic.

The short version is that if you start at a given note (for instance, C) and make a chain of seven notes separated by fifths and make your given note (in this case C) one of those notes, then you get seven scales in the seven major modes: Lydian, Ionian, Mixolydian, Dorian, Aeolian, Phrygian, and Locrian. If you repeat this for all twelve notes, you get those scales in all keys (84 total).

§

First, here’s the table in HTML:

Musical Modes (all 84 rows)

Lydian C D E F♯ G A B
Ionian C D E F G A B
Mixolydian C D E F G A B♭
Dorian C D E♭ F G A B♭
Aeolian C D E♭ F G A♭ B♭
Phrygian C D♭ E♭ F G A♭ B♭
Locrian C D♭ E♭ F G♭ A♭ B♭
Lydian B C♯ D♯ E♯ F♯ G♯ A♯
Ionian B C♯ D♯ E F♯ G♯ A♯
Mixolydian B C♯ D♯ E F♯ G♯ A
Dorian B C♯ D E F♯ G♯ A
Aeolian B C♯ D E F♯ G A
Phrygian B C D E F♯ G A
Locrian B C D E F G A
Lydian B♭ C D E F G A
Ionian B♭ C D E♭ F G A
Mixolydian B♭ C D E♭ F G A♭
Dorian B♭ C D♭ E♭ F G A♭
Aeolian B♭ C D♭ E♭ F G♭ A♭
Phrygian B♭ C♭ D♭ E♭ F G♭ A♭
Locrian B♭ C♭ D♭ E♭ F♭ G♭ A♭
Lydian A B C♯ D♯ E F♯ G♯
Ionian A B C♯ D E F♯ G♯
Mixolydian A B C♯ D E F♯ G
Dorian A B C D E F♯ G
Aeolian A B C D E F G
Phrygian A B♭ C D E F G
Locrian A B♭ C D E♭ F G
Lydian G♯ A♯ B♯ C♯♯ D♯ E♯ F♯♯
Ionian G♯ A♯ B♯ C♯ D♯ E♯ F♯♯
Mixolydian G♯ A♯ B♯ C♯ D♯ E♯ F♯
Dorian G♯ A♯ B C♯ D♯ E♯ F♯
Aeolian G♯ A♯ B C♯ D♯ E F♯
Phrygian G♯ A B C♯ D♯ E F♯
Locrian G♯ A B C♯ D E F♯
Lydian G A B C♯ D E F♯
Ionian G A B C D E F♯
Mixolydian G A B C D E F
Dorian G A B♭ C D E F
Aeolian G A B♭ C D E♭ F
Phrygian G A♭ B♭ C D E♭ F
Locrian G A♭ B♭ C D♭ E♭ F
Lydian F♯ G♯ A♯ B♯ C♯ D♯ E♯
Ionian F♯ G♯ A♯ B C♯ D♯ E♯
Mixolydian F♯ G♯ A♯ B C♯ D♯ E
Dorian F♯ G♯ A B C♯ D♯ E
Aeolian F♯ G♯ A B C♯ D E
Phrygian F♯ G A B C♯ D E
Locrian F♯ G A B C D E
Lydian F G A B C D E
Ionian F G A B♭ C D E
Mixolydian F G A B♭ C D E♭
Dorian F G A♭ B♭ C D E♭
Aeolian F G A♭ B♭ C D♭ E♭
Phrygian F G♭ A♭ B♭ C D♭ E♭
Locrian F G♭ A♭ B♭ C♭ D♭ E♭
Lydian E F♯ G♯ A♯ B C♯ D♯
Ionian E F♯ G♯ A B C♯ D♯
Mixolydian E F♯ G♯ A B C♯ D
Dorian E F♯ G A B C♯ D
Aeolian E F♯ G A B C D
Phrygian E F G A B C D
Locrian E F G A B♭ C D
Lydian E♭ F G A B♭ C D
Ionian E♭ F G A♭ B♭ C D
Mixolydian E♭ F G A♭ B♭ C D♭
Dorian E♭ F G♭ A♭ B♭ C D♭
Aeolian E♭ F G♭ A♭ B♭ C♭ D♭
Phrygian E♭ F♭ G♭ A♭ B♭ C♭ D♭
Locrian E♭ F♭ G♭ A♭ B♭♭ C♭ D♭
Lydian D E F♯ G♯ A B C♯
Ionian D E F♯ G A B C♯
Mixolydian D E F♯ G A B C
Dorian D E F G A B C
Aeolian D E F G A B♭ C
Phrygian D E♭ F G A B♭ C
Locrian D E♭ F G A♭ B♭ C
Lydian C♯ D♯ E♯ F♯♯ G♯ A♯ B♯
Ionian C♯ D♯ E♯ F♯ G♯ A♯ B♯
Mixolydian C♯ D♯ E♯ F♯ G♯ A♯ B
Dorian C♯ D♯ E F♯ G♯ A♯ B
Aeolian C♯ D♯ E F♯ G♯ A B
Phrygian C♯ D E F♯ G♯ A B
Locrian C♯ D E F♯ G A B

It uses the three-color scheme John introduced in his post. One of his readers, Owen Lynch, made a circular version with a four-color scheme (twelve breaks nicely into both three and four). Here’s the same table with that four-color scheme:

Musical Modes (all 84 rows)

Lydian C D E F♯ G A B
Ionian C D E F G A B
Mixolydian C D E F G A B♭
Dorian C D E♭ F G A B♭
Aeolian C D E♭ F G A♭ B♭
Phrygian C D♭ E♭ F G A♭ B♭
Locrian C D♭ E♭ F G♭ A♭ B♭
Lydian B C♯ D♯ E♯ F♯ G♯ A♯
Ionian B C♯ D♯ E F♯ G♯ A♯
Mixolydian B C♯ D♯ E F♯ G♯ A
Dorian B C♯ D E F♯ G♯ A
Aeolian B C♯ D E F♯ G A
Phrygian B C D E F♯ G A
Locrian B C D E F G A
Lydian B♭ C D E F G A
Ionian B♭ C D E♭ F G A
Mixolydian B♭ C D E♭ F G A♭
Dorian B♭ C D♭ E♭ F G A♭
Aeolian B♭ C D♭ E♭ F G♭ A♭
Phrygian B♭ C♭ D♭ E♭ F G♭ A♭
Locrian B♭ C♭ D♭ E♭ F♭ G♭ A♭
Lydian A B C♯ D♯ E F♯ G♯
Ionian A B C♯ D E F♯ G♯
Mixolydian A B C♯ D E F♯ G
Dorian A B C D E F♯ G
Aeolian A B C D E F G
Phrygian A B♭ C D E F G
Locrian A B♭ C D E♭ F G
Lydian G♯ A♯ B♯ C♯♯ D♯ E♯ F♯♯
Ionian G♯ A♯ B♯ C♯ D♯ E♯ F♯♯
Mixolydian G♯ A♯ B♯ C♯ D♯ E♯ F♯
Dorian G♯ A♯ B C♯ D♯ E♯ F♯
Aeolian G♯ A♯ B C♯ D♯ E F♯
Phrygian G♯ A B C♯ D♯ E F♯
Locrian G♯ A B C♯ D E F♯
Lydian G A B C♯ D E F♯
Ionian G A B C D E F♯
Mixolydian G A B C D E F
Dorian G A B♭ C D E F
Aeolian G A B♭ C D E♭ F
Phrygian G A♭ B♭ C D E♭ F
Locrian G A♭ B♭ C D♭ E♭ F
Lydian F♯ G♯ A♯ B♯ C♯ D♯ E♯
Ionian F♯ G♯ A♯ B C♯ D♯ E♯
Mixolydian F♯ G♯ A♯ B C♯ D♯ E
Dorian F♯ G♯ A B C♯ D♯ E
Aeolian F♯ G♯ A B C♯ D E
Phrygian F♯ G A B C♯ D E
Locrian F♯ G A B C D E
Lydian F G A B C D E
Ionian F G A B♭ C D E
Mixolydian F G A B♭ C D E♭
Dorian F G A♭ B♭ C D E♭
Aeolian F G A♭ B♭ C D♭ E♭
Phrygian F G♭ A♭ B♭ C D♭ E♭
Locrian F G♭ A♭ B♭ C♭ D♭ E♭
Lydian E F♯ G♯ A♯ B C♯ D♯
Ionian E F♯ G♯ A B C♯ D♯
Mixolydian E F♯ G♯ A B C♯ D
Dorian E F♯ G A B C♯ D
Aeolian E F♯ G A B C D
Phrygian E F G A B C D
Locrian E F G A B♭ C D
Lydian E♭ F G A B♭ C D
Ionian E♭ F G A♭ B♭ C D
Mixolydian E♭ F G A♭ B♭ C D♭
Dorian E♭ F G♭ A♭ B♭ C D♭
Aeolian E♭ F G♭ A♭ B♭ C♭ D♭
Phrygian E♭ F♭ G♭ A♭ B♭ C♭ D♭
Locrian E♭ F♭ G♭ A♭ B♭♭ C♭ D♭
Lydian D E F♯ G♯ A B C♯
Ionian D E F♯ G A B C♯
Mixolydian D E F♯ G A B C
Dorian D E F G A B C
Aeolian D E F G A B♭ C
Phrygian D E♭ F G A B♭ C
Locrian D E♭ F G A♭ B♭ C
Lydian C♯ D♯ E♯ F♯♯ G♯ A♯ B♯
Ionian C♯ D♯ E♯ F♯ G♯ A♯ B♯
Mixolydian C♯ D♯ E♯ F♯ G♯ A♯ B
Dorian C♯ D♯ E F♯ G♯ A♯ B
Aeolian C♯ D♯ E F♯ G♯ A B
Phrygian C♯ D E F♯ G♯ A B
Locrian C♯ D E F♯ G A B

These turned out fine. Unfortunately, my image-generation software was fine with the musical sharp sign (♯) but doesn’t seem to know about the musical flat sign (♭). Which is weird because the two characters are nearly adjacent in Unicode (only the musical natural sign is between them). I tried using the letter “b”, but it didn’t look anywhere close to right.

So, this didn’t turn out as well as I’d hoped (the little square boxes are supposed to be musical flat symbols). Click the images for a full-sized (710×3500) version:

Of course, changing the color scheme doesn’t change the problem:

Which makes these fails until I can understand what’s happening and how, if possible, to fix it. For what it’s worth, I’m using the Pillow fork of the Python Imaging Library.

§ §

So, sorry John, I didn’t quite pull it off. Yet. I’ll see what I can do about it. Maybe you can use the HTML version? Happy to provide the HTML files. Or the Python program if anyone is interested.

Stay musical, my friends! Go forth and spread beauty and light.

About Wyrd Smythe

The canonical fool on the hill watching the sunset and the rotation of the planet and thinking what he imagines are large thoughts. View all posts by Wyrd Smythe

24 responses to “Musical Scale Modes

  • Wyrd Smythe

    If you view this post in the WP Reader, the HTML tables have all their color and spacing stripped (gee, thanks WP), so they don’t look good (the color is kind of the point of the table). As always, it’s best reading WP posts on the actual blog website.

    • Mark Edward Jabbour

      It works perfect on my iPhone with the WordPress reader. I took a screenshot but can’t post it here.
      That is a complaint I have = no pictures in the comment section.
      I have found each device is different depending on the OS and age.
      This post of yours = way beyond my purview. But, wow!

      • Wyrd Smythe

        Doesn’t the WP Reader strip out the color in the HTML charts? (The first two. The latter two are image files.) When I use the Reader on my desktop or phone those first two charts have no color. They show up okay (except I have turn my phone sideways) but no color.

        It’s possible to put images in comments…

        Bentley Long Toes

        …just takes a little doing. You can’t just drop them. You have to link to them, either from your own WordPress media collection (which is convenient) or from something else (like Wikipedia or some webpage).

      • Mark Edward Jabbour

        Hmmm? I’ll poke around and try and find a way. Thanks!
        On my iPhone the colors were there. Vivid.

      • Wyrd Smythe

        Just paste the URL into the comment and WP generally does the rest.

        Are you seeing four colorful versions of the table? Using the WP Reader? I’ve tried it on my desktop, iPad, and iPhone, and in the Reader they all show the first two without color.

      • Mark Edward Jabbour

        Yes, on both my phone and computer – four shades of blue. And the paragraph breaks are there, too. It seems fine.
        Still can’t figure out the picture link though. I can only grab pics from my phone to link to my wordpress posts. But, of course, I write on the computer. It’s tricky.

      • Wyrd Smythe

        Well, color me amazed, then! The WordPress Reader goes to great lengths to strip out the style information that colors the charts.

      • Mark Edward Jabbour

        Beats me. I’m too old for this.

  • Wyrd Smythe

    I upgraded Pillow from version 8.4 to version 10.0 but it didn’t help. 😟

  • John Baez

    Hi! This is great. I’m going to use one of your charts in my next post on modes, and credit you!

    I noticed one little mistake, which I fixed. In the key of G♯ Lydian, you have a C♯ that should be a C♯♯. You can probably guess how I noticed this: the double sharps and double flats are very rare, and sort of tricky.

    • Wyrd Smythe

      D’oh! Transcription error on my part. It’s correct in my notes but missed the transition to code. (I was working off the Owen Lynch version, which uses the actual double-sharp symbol. It threw me at first — working with written music is decades in my past — so my notes got messy at that point. (In fact, I put a question mark and circled it heavily. Somehow that turned into a sharp in the code. 🤷🏼‍♂️))

      Fixed the code and re-ran it. Fixed HTML tables (by hand) and re-uploaded the images (even though they’re kind of useless with those boxes instead of flat symbols — hope to fix that eventually). You said you fixed your copy, so it’s all good!

      I mentioned in my comment on your blog that, rather than using the logic you described in the post, I just reverse-engineered the pattern of the 84-row columns. It’s the same pattern, so it applies to all seven columns, but of course with different starting notes and an offset relative to the first column. I’ll post the relevant code below in case you (or anyone else) is interested.

      What fascinated me was the pattern of the columns. Twelve sequences of notes repeated seven times. In some cases, all seven occurrences are what the code calls the “primary” representation of the note (for example, “F”). In the other cases, the seven occurrences are split between two representations (such as “F” and “E#”). What I found interesting was that the pattern of primary versus dual representation matches the pattern of white and black piano keys. In the code it’s the ColumnSequencePattern list. The ones are black keys, and the zeros are white keys. (The list starts with C#.) The NotePairs table has the two note representations along with a flag indicating which is primary.

  • Wyrd Smythe

    Here’s the heart of Python code, the column generator along with the key data structures and, at the bottom, a function that generates the 84-row table:

    001| NotePairs = [
    002|     (‘B’+Music2Flat, ‘A’            , 1),   # 0 A
    003|     (‘B’+MusicFlat , ‘A’+MusicSharp , 0),   # 1 A#
    004|     (‘C’+MusicFlat , ‘B’            , 1),   # 2 B
    005|     (‘C’           , ‘B’+MusicSharp , 0),   # 3 C
    006|     (‘D’+MusicFlat , ‘C’+MusicSharp , 1),   # 4 C#
    007|     (‘D’           , ‘C’+Music2Sharp, 0),   # 5 D
    008|     (‘E’+MusicFlat , ‘D’+MusicSharp , 0),   # 6 D#
    009|     (‘F’+MusicFlat , ‘E’            , 1),   # 7 E
    010|     (‘F’           , ‘E’+MusicSharp , 0),   # 8 F
    011|     (‘G’+MusicFlat , ‘F’+MusicSharp , 1),   # 9 F#
    012|     (‘G’           , ‘F’+Music2Sharp, 0),   # 10 G
    013|     (‘A’+MusicFlat , ‘G’+MusicSharp , 1),   # 11 G#
    014| ]
    015| 
    016| ColumnSequencePattern = [1,0,1,0,0,1,0,1,0,1,0,0]
    017| ColumnStartNotes      = [3,5,7,9,10,0,2]
    018| ColumnDualNoteRatios  = [7,2,4,6,1,3,5]
    019| ColumnOffsets         = [0,2,4,6,1,3,5]
    020| 
    021| def generate_column (column_index, color_funct):
    022|     """\
    022| Generate one 84-row column for the chart.
    022| Requires a column index indicating which
    022| column to generate.
    022| """

    023|     note_index = ColumnStartNotes[column_index]
    024|     note_ratio = ColumnDualNoteRatios[column_index]
    025|     col_offset = ColumnOffsets[column_index]
    026| 
    027|     col = []
    028|     for seq,which in enumerate(ColumnSequencePattern):
    029|         bgcolor = color_funct(seq)
    030|         for row in range(7):
    031|             # Note version switching when (0<row)…
    032|             if column_index and (which==0):
    033|                 # Decide which version to use…
    034|                 a_or_b = 0 if row < note_ratio else 1
    035|                 note = NotePairs[note_index][a_or_b]
    036|                 col.append((note,bgcolor))
    037|             else:
    038|                 prim = NotePairs[note_index][2]
    039|                 note = NotePairs[note_index][prim]
    040|                 col.append((note, bgcolor))
    041|         note_index -= 1
    042|         if note_index < 0:
    043|             note_index = len(NotePairs)1
    044|     # Wrap the columns using their offsets…
    045|     for _ in range(col_offset):
    046|         col.append(col.pop(0))
    047|     return col
    048| 
    049| def create_columns (color_func):
    050|     """Create all seven columns for the table."""
    051|     cols = [generate_column(cx, color_func) for cx in range(7)]
    052|     rows = zip(*cols)
    053|     return list(rows)
    054| 
    055| 
  • Wyrd Smythe

    BTW, one can also use a two-color scheme:

    Musical Modes (all 84 rows)

    Lydian C D E F♯ G A B
    Ionian C D E F G A B
    Mixolydian C D E F G A B♭
    Dorian C D E♭ F G A B♭
    Aeolian C D E♭ F G A♭ B♭
    Phrygian C D♭ E♭ F G A♭ B♭
    Locrian C D♭ E♭ F G♭ A♭ B♭
    Lydian B C♯ D♯ E♯ F♯ G♯ A♯
    Ionian B C♯ D♯ E F♯ G♯ A♯
    Mixolydian B C♯ D♯ E F♯ G♯ A
    Dorian B C♯ D E F♯ G♯ A
    Aeolian B C♯ D E F♯ G A
    Phrygian B C D E F♯ G A
    Locrian B C D E F G A
    Lydian B♭ C D E F G A
    Ionian B♭ C D E♭ F G A
    Mixolydian B♭ C D E♭ F G A♭
    Dorian B♭ C D♭ E♭ F G A♭
    Aeolian B♭ C D♭ E♭ F G♭ A♭
    Phrygian B♭ C♭ D♭ E♭ F G♭ A♭
    Locrian B♭ C♭ D♭ E♭ F♭ G♭ A♭
    Lydian A B C♯ D♯ E F♯ G♯
    Ionian A B C♯ D E F♯ G♯
    Mixolydian A B C♯ D E F♯ G
    Dorian A B C D E F♯ G
    Aeolian A B C D E F G
    Phrygian A B♭ C D E F G
    Locrian A B♭ C D E♭ F G
    Lydian G♯ A♯ B♯ C♯♯ D♯ E♯ F♯♯
    Ionian G♯ A♯ B♯ C♯ D♯ E♯ F♯♯
    Mixolydian G♯ A♯ B♯ C♯ D♯ E♯ F♯
    Dorian G♯ A♯ B C♯ D♯ E♯ F♯
    Aeolian G♯ A♯ B C♯ D♯ E F♯
    Phrygian G♯ A B C♯ D♯ E F♯
    Locrian G♯ A B C♯ D E F♯
    Lydian G A B C♯ D E F♯
    Ionian G A B C D E F♯
    Mixolydian G A B C D E F
    Dorian G A B♭ C D E F
    Aeolian G A B♭ C D E♭ F
    Phrygian G A♭ B♭ C D E♭ F
    Locrian G A♭ B♭ C D♭ E♭ F
    Lydian F♯ G♯ A♯ B♯ C♯ D♯ E♯
    Ionian F♯ G♯ A♯ B C♯ D♯ E♯
    Mixolydian F♯ G♯ A♯ B C♯ D♯ E
    Dorian F♯ G♯ A B C♯ D♯ E
    Aeolian F♯ G♯ A B C♯ D E
    Phrygian F♯ G A B C♯ D E
    Locrian F♯ G A B C D E
    Lydian F G A B C D E
    Ionian F G A B♭ C D E
    Mixolydian F G A B♭ C D E♭
    Dorian F G A♭ B♭ C D E♭
    Aeolian F G A♭ B♭ C D♭ E♭
    Phrygian F G♭ A♭ B♭ C D♭ E♭
    Locrian F G♭ A♭ B♭ C♭ D♭ E♭
    Lydian E F♯ G♯ A♯ B C♯ D♯
    Ionian E F♯ G♯ A B C♯ D♯
    Mixolydian E F♯ G♯ A B C♯ D
    Dorian E F♯ G A B C♯ D
    Aeolian E F♯ G A B C D
    Phrygian E F G A B C D
    Locrian E F G A B♭ C D
    Lydian E♭ F G A B♭ C D
    Ionian E♭ F G A♭ B♭ C D
    Mixolydian E♭ F G A♭ B♭ C D♭
    Dorian E♭ F G♭ A♭ B♭ C D♭
    Aeolian E♭ F G♭ A♭ B♭ C♭ D♭
    Phrygian E♭ F♭ G♭ A♭ B♭ C♭ D♭
    Locrian E♭ F♭ G♭ A♭ B♭♭ C♭ D♭
    Lydian D E F♯ G♯ A B C♯
    Ionian D E F♯ G A B C♯
    Mixolydian D E F♯ G A B C
    Dorian D E F G A B C
    Aeolian D E F G A B♭ C
    Phrygian D E♭ F G A B♭ C
    Locrian D E♭ F G A♭ B♭ C
    Lydian C♯ D♯ E♯ F♯♯ G♯ A♯ B♯
    Ionian C♯ D♯ E♯ F♯ G♯ A♯ B♯
    Mixolydian C♯ D♯ E♯ F♯ G♯ A♯ B
    Dorian C♯ D♯ E F♯ G♯ A♯ B
    Aeolian C♯ D♯ E F♯ G♯ A B
    Phrygian C♯ D E F♯ G♯ A B
    Locrian C♯ D E F♯ G A B
  • Anonymole

    Humans!
    I guess, whatever keeps you busy…

    • Wyrd Smythe

      Clever monkeys!

      It’s rare that a legit problem catches my attention and engages me. One thing about retirement is the lack of interesting challenges. I’ve never liked games or puzzles, so I need some real-world challenge that makes me think, “Huh. That might be an interesting coding problem to solve!”

      • Anonymole

        If music is math, and songs are functions, then AI should be able to produce some exquisite compositions.

      • Wyrd Smythe

        I incline towards debating the two assertions, and I’m definitely dubious about the conclusion.

        Music certainly has mathematical structure but equating it with math seems overly reductive to me. For instance, these mode scales, from Lydian to Locrian, “color” the music from “brightest” to “darkest”. And if you get into the math, it actually gets a bit messy. (Readers wrote a bit about that in the comments section on John’s post.)

        Song as function is an interesting notion. Brought to mind a player piano roll — the function code for a song executed on a musical engine. But such are mechanistic and a far cry from David Gilmour’s guitar solo in “Comfortably Numb”. One needs a function as complicated as human to generate that!

        I’ve been pretty underwhelmed by AI art so far. I think it’s that new Marvel show that has a title sequence generated by AI, and I’ve seen AI trained to do Mandelbrot zooms. And I’ve seen stories written by AI. In all cases, to me it seems to come from a brain-damaged mind — there’s something weirdly chaotic about its output.

        Two stories: In college, a friend I was out with had an epileptic fit. One thing that stands out about it was looking into the eyes of someone conscious but most decidedly not home. Another time out walking my dog, we passed someone who must have been seriously tripping balls. Again, the eerie sense of something not-human. A strong sense in both cases of something wrong, something seriously off. I get the same sense from AI art.

        About the best use of AI art I’ve seen is by Corridor Crew, a company of profession visual effects artists (with a rather good YouTube channel). They’ve been using it to make an anime (called “Rock, Paper, Scissors”). But they start with original photography and voice recordings, train the AI on the animation style they want, provide the backgrounds and desired moves, and more. The first one was an interesting experiment.

        But it had that visual stutter effect because the AI didn’t retain memory of what it was drawing. Each frame was a bit different. So, they worked to smooth out the animation, and their second attempt is notable. Looks pretty good considering the source. Still flawed, though. Fingers bend the wrong way sometimes or other weird errors no human would make. The AI doesn’t know, it just imitates.

        Well, so do humans, but our neural nets are vastly superior, so we do it way better. And I do think we’re sometimes capable of a truly original thought. Not sure AI ever will be.

        Hmmmm… Sorry, went on a bit there…

  • Modes (Part 8) | Azimuth

    […] time I asked if someone could make a really long version of my chart listing all 84 modes. Wyrd Smythe rose to the challenge and produced this magnificent […]

  • Wyrd Smythe

    Trying to implement this table by generating the scales using intervals of a fifth results in technically correct scales, but with duplicate — and therefore also missing — notes. Each scale should have all seven notes: A, B, C, D, E, F, & G. They are sharped or flatted (or double sharped or double flatted) depending on the scale and starting note.

    The algorithm for the scales is simple enough but dealing with the duplicate/missing notes is a challenge that two coding sessions have failed to meet. Just to get a correct table, I made a version, which does generate rows of scales, uses a table of fixes for the 25 cases (out of 84) where the scale doesn’t use all seven notes.

    I think I’ll see if it works better if I start with the seven notes and then sharp or flat them as required by the scale.

  • Wyrd Smythe

    As “they” say, “Third time pays for all.” It finally dawned on me that treating the notes as 12 indexes invariably raises the issue of whether an indexed note (say #4 with ‘A’ as #0) is C# or Db. It’s effectively impossible to tell.

    Treating notes per their seven base names (‘A’ thru ‘G’) is the ticket. It guarantees having all seven notes in a scale. The only trick is getting the intervals right, but it’s not much of a trick.

    Here’s the (complete, runnable as-is) code:

    001| from sys import stdout
    002| 
    003| ModeNames = [
    004|     ‘Lydian’,‘Ionian’,‘Mixolydian’,‘Dorian’,
    005|     ‘Aeolian’,‘Phrygian’,‘Locrian’
    006| ]
    007| 
    008| ModeIntervals = [
    009|     [1, 2, 2, 2, 1, 2, 2, 1],   # Lydian
    010|     [1, 2, 2, 1, 2, 2, 2, 1],   # Ionian
    011|     [2, 2, 2, 1, 2, 2, 1, 2],   # Mixolydian
    012|     [2, 2, 1, 2, 2, 2, 1, 2],   # Dorian
    013|     [2, 2, 1, 2, 2, 1, 2, 2],   # Aeolian
    014|     [2, 1, 2, 2, 2, 1, 2, 2],   # Phrygian
    015|     [2, 1, 2, 2, 1, 2, 2, 2],   # Locrian
    016| ]
    017| 
    018| Flat  = ‘\u266d’
    019| Sharp = ‘\u266f’
    020| Flat2  = ‘\u266d\u266d’
    021| Sharp2 = ‘\u266f\u266f’ #’\U0001D12a’
    022| 
    023| BaseNotes = [
    024|     ‘A’,‘B’+Flat,‘B’,‘C’,‘C’+Sharp,‘D’,
    025|     ‘E’+Flat,‘E’,‘F’,‘F’+Sharp,‘G’,‘G’+Sharp
    026| ]
    027| 
    028| NoteTable = {
    029|     ‘A’:(‘A’+Flat2,‘A’+Flat,‘A’,‘A’+Sharp,‘A’+Sharp2),
    030|     ‘B’:(‘B’+Flat2,‘B’+Flat,‘B’,‘B’+Sharp,‘B’+Sharp2),
    031|     ‘C’:(‘C’+Flat2,‘C’+Flat,‘C’,‘C’+Sharp,‘C’+Sharp2),
    032|     ‘D’:(‘D’+Flat2,‘D’+Flat,‘D’,‘D’+Sharp,‘D’+Sharp2),
    033|     ‘E’:(‘E’+Flat2,‘E’+Flat,‘E’,‘E’+Sharp,‘E’+Sharp2),
    034|     ‘F’:(‘F’+Flat2,‘F’+Flat,‘F’,‘F’+Sharp,‘F’+Sharp2),
    035|     ‘G’:(‘G’+Flat2,‘G’+Flat,‘G’,‘G’+Sharp,‘G’+Sharp2),
    036| }
    037| def Note2Str (t):
    038|     base = t[0]
    039|     more = 2 + t[1]
    040|     return NoteTable[base][more]
    041| 
    042| def Str2Note (nt):
    043|     base = nt[0]
    044|     more = nt[1:2]
    045|     if more == Sharp: return (base, +1)
    046|     if more == Flat: return (base, 1)
    047|     return (base, 0)
    048| 
    049| def NoteAbove (nt):
    050|     if nt == ‘G’: return ‘A’
    051|     return chr(ord(nt)+1)
    052| 
    053| def generate_scale (first_note=(‘C’,0), mode_index=0):
    054|     mode = ModeIntervals[mode_index]
    055|     mode_name = ModeNames[mode_index]
    056| 
    057|     def next_note (nt, d):
    058|         nxnt = NoteAbove(nt[0])
    059|         if nt[0] in [‘B’, ‘E’]:
    060|             flag = nt[1]+(d1)
    061|         else:
    062|             flag = nt[1](2d)
    063|         return (nxnt, flag)
    064| 
    065|     scale = [first_note]
    066|     for dist in mode[1:7]:
    067|         note = next_note(scale[1], dist)
    068|         scale.append(note)
    069|     return (mode_name, [Note2Str(n) for n in scale])
    070| 
    071| def generate_section (first_note=(‘C’,0)):
    072|     scales = []
    073|     for mode in range(7):
    074|         notes = generate_scale(first_note, mode)
    075|         scales.append(notes)
    076|     return scales
    077| 
    078| def generate_table ():
    079|     table = []
    080|     for key in [3,2,1,0,11,10,9,8,7,6,5,4]:
    081|         note = Str2Note(BaseNotes[key])
    082|         sect = generate_section(note)
    083|         table.append(sect)
    084|     return table
    085| 
    086| fmt = ‘%-11s| %-3s %-3s %-3s %-3s %-3s %-3s %-3s|’
    087| 
    088| def display_table (table, stream=stdout):
    089|     for section in table:
    090|         for mode,scale in section:
    091|             print(fmt % (mode,*scale), file=stream)
    092|         print(file=stream)
    093|     print(file=stream)
    094| 
    095| table = generate_table()
    096| display_table(table)
    097| 
  • Musical Scale Modes Table | The Hard-Core Coder

    […] any of his readers would be interested in creating that table of all 84 rows. It sounded like — and turned out to be — a fun exercise. This post explores in detail the Python solution I came up […]

  • George Birbilis

    there is a part 8 too at https://johncarlosbaez.wordpress.com/2023/08/21/modes-part-8/ (though his links point currently to https://johncarlosbaez.wordpress.com/2023/08/24/modes-part-8/ which is broken). Mentioning both links in case he changes the canonical url instead of fixing the Part 8 link at the end of each of the 1-7 articles

And what do you think?