Hear a song, play a song

Programs to help me learn to play piano, by ear.

Public Chat
Similar projects worth following
Like many people, I suffered through piano lessons as a kid.
Also like many people, I always have some song playing in my head.

As an adult I've tried to go back and learn piano several times, only to lose interest. Reading notes is tedious and boring, and you often can't find sheet music for songs you like, and the sheet music you *do* find is often times simplified or a different arrangement or just too complicated to read or memorize.

It occurred to me that learning to read music isn't what I'm really after. What I'd *like* to do is to hear a song in my head and be able to play it on the piano.

So I've decided to build some programs to help me bridge the gap between playing a song in my head and playing it on the piano.

Basically, programs to help me learn to play by ear.

The project logs contain the details.

Files and programs are available on GitHub, there's a link on theleft-hand side of this page under "external links" (the one with a cat icon).

  • Hear a note, play a note

    Peter Walsh08/18/2018 at 20:54 0 comments

    Okay, initial thoughts.

    As a first cut I want a program that will play a random piano note, so that I can try to find that note on the piano.

    Basically, I'm tuning my ear to be able to recognize piano notes by pitch. I frequently can "hear" notes in my head, but have no idea which notes on the piano these are.

    Note distribution and project data

    A naive implementation would draw randomly from the 88-key span of a piano and play a note at random, but this is sub-optimal for learning. Most songs don't encompass the entire piano range, so it doesn't make sense to learn the very high or very low notes at the same rate as the more often played notes.

    A second naive implementation would draw from a normal distribution centered on middle "C" of the piano, since that's where most of the songs will be.

    A more nuanced implementation would draw from the distribution of actual notes found in actual songs.

    Step 1: Get songs

    So my first step is to grab a large dataset of songs in MIDI format, and extract the note information. It shouldn't matter the songs, so long as they are piano pieces and there are a enough of them to get a good statistical average.

    So I wrote a program (available in the GitHub project) "" that downloads all the .midi files for all songs listed as piano pieces.

    Piano/Songs:  perl ../bin/
              :                 :
    Done! 782 files downloaded

    Voila! A nice dataset of over 700 songs.

    Step 2: Get notes from one song

    Second step is to grab the note information from a single song, so I wrote a program "MidiDump" to do just that:

    Piano/Songs:  ../bin/ leslanciers.mid 
                  :                      :
            ['note_off', 192, 1, 48, 64],
            ['note_on', 0, 1, 55, 127],
            ['note_off', 192, 1, 55, 64],
            ['note_on', 0, 1, 52, 127],
            ['note_off', 192, 1, 52, 64],
            ['note_on', 0, 1, 55, 127],
            ['note_off', 192, 1, 55, 64],
            ['note_on', 0, 1, 48, 127],
            ['note_off', 768, 1, 48, 64],

    A long series of MIDI "note_on" and "note_off" commands, plus some extra information.

    Step 3: Histogram all song notes

    I deleted the file "Erlkoenig_alt.mid", as it appears to call out notes outside of the range of a piano.

    Also, I'm making the tacit assumption that all tracks of all MIDI files refer to a piano instrument. That may not be correct; if so, I'll have to revisit this process later.

    The program to histogram all notes from all MIDI files in a directory is called "":

    Piano/Songs: perl ../bin/ >../Data/NoteHist.txt

    And this generates a quite respectable piano note distribution:

    The MIDI range of notes for a piano is 21 through 108, so this looks good.

    Also, certain notes are much more popular than others, which is to be expected.

    A program to generate random notes can draw from this distribution directly, so that the notes most likely to be used in a piano song will be the ones most likely to be used.

    Epilogue: Further uses for the data

    Having a database of piano songs and the ability to extract notes and other MIDI information might be useful in other ways.

    For example, once I have learned all the single notes it might be useful to generate a distribution of all the *pairs* of notes (simple chords of two notes), and later on a distribution of chord triplets.

    More on that later.

View project log

Enjoy this project?



Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates