Inspiration

I love playing the guitar, and I thought it would be interesting to have a teleprompter for guitar sheet music, as it could double as a metronome and a replacement for standard paper sheet music. Guitar sheet music, or tab, is much simpler than standard sheet music: It's presented in a somewhat unstandardized text based format, with six lines of hyphens representing strings on a guitar, and integers along the lines to indicate the placement of the notes (on the guitar's frets). The horizontal position of the notes in a bar roughly indicates the note's timing, though there is no universal way to specify a note's length.

Q=120, 3/4 time

    G                   G/B                 C                   G/B
e|--------------------|-------------------|-0----------0--2---|-3-----------------|
B|--3----------0--1---|-3-----------------|------1--3---------|-------------------|
G|o------0--2---------|-------0-----0-----|-------------------|-------0-----0-----|
D|o-------------------|-------------------|-------------------|-------------------|
A|-------------0------|-2-----------------|-3-----------------|-2-----------------|
E|--3-----------------|-------------------|-------------------|-------------------|

    Am                  G                   D    G/B   G        D7
e|--------------------|-------------------|-------------------|-------------------|
B|--1----3--1--0------|-0----1--0---------|------------0------|-------------------|
G|----------------2---|------------2--0---|------0--2-----0---|-2-----------------|
D|--------------------|-------------------|-4-----------------|-0----0------------|
A|--0-----------------|-------------------|-5----2------------|---------3--2--0---|
E|--------------------|-3-----------------|------------3------|-------------------|

For example, here are the first 8 measures of Bach's Minuet in G major. source: Ultimate Guitar

Many popular tab sites have an autoscrolling feature, which performs a similar music-teleprompter-like role, suggesting a need for something like TabRunner.

What it does

I built:

  1. React-based tab parser to take in tab like the one above and extract out the note data into a machine instruction inspired encoding.

  2. An Arduino-powered hardware device that takes in the encoded data and renders it onto an 128x64 OLED screen, one measure at a time, with buttons that control the tempo (the delay between measures).

How we built it

  1. Used the ES8266 OLED SSD1306 library to render lines (representing guitar strings) and circles with numbers in them (representing notes).
  2. Built a small application with ReactJS for frontend and minimal styling that has a textbox for notes. Webapp Screenshot.
  3. Made up a way to represent "Note" objects, and ran the tab, which was just a standard, ASCII string, through a gauntlet of string manipulation functions to ultimately build up an array of Note data objects.
  4. Developed an encoding to represent note objects. Inspired by machine instructions, I took the note data, which was a collection of ints/floats, and converted it into a single 12 bit binary value.

    0b0SSS_HHHH_FFFF
    

    S are string bits, representing one of the six strings (ie. 001 = high E, 010 = B, etc) H are horizontal position/timing bits - stored as a value to be normalized from 0 to 15, with 0 representing the left end of a measure and 15 representing the right end. F are the fret bits. There are 19 frets on a standard guitar but I've never seen anything above 15 used, nor are the higher frets particularly playable.

  5. Used bit manipulation to parse out the note data from the integer encoding in the Arduino, then used that information to generate X/Y/Bar coordinates in which to render the notes.

  6. Added utility functions and wired up some buttons to control the speed, as well as left and right solid bar indicators to show when the start/end of a song is, since it loops through all the bars of a song, infinitely.

Challenges we ran into

  • Processing the string data using elementary string functions was quite difficult, requiring a 4 dimensional array and a lot of scribbling odd shapes on paper

  • Interfacing the Javascript objects into Arduino readable (ie. C++) code was harder than expected. I thought I could just use the standard JSON (Javascript Object Notation) string encode/decode functions but that produced a lot of issues, so I had to come up with that custom integer encoding to flatten the objects into integers, then a few bit manipulations to decode them.

Accomplishments that we're proud of

  • Building this in time!
  • Coming up with an elegant encoding for notes
  • I think some of the tab parsing is somewhat clever, if messy

What we learned

  • A lot about how/why to use bit manipulation
  • How to wire buttons with an Arduino
  • How to create a nice control loop with good feedback
  • How to deal with multidimensional arrays (harder than expected!) in Arduino code

What's next for TabRunner

  • Extending this for Ukelele tab, with supporting 4 strings instead of 6
  • Adding more complex tab notation like hammer on/pull off parsing
  • More buttons to reset/fast forward
  • Rotary encoder for tempo setting rather than buttons
  • Larger screen/better assembly to mount easily to a guitar, improved visibility

Built With

Share this project:

Updates