Created
November 17, 2008 16:00
-
-
Save tmcw/25809 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| require 'rubygems' | |
| require 'RMagick' | |
| # This script draws ukulele chords for use in | |
| # tabs or elsewhere | |
| # | |
| # Author:: Tom MacWright (mailto:[email protected]) | |
| # Copyright:: Copyright (c) 2008 Tom MacWright | |
| # License:: BSD License | |
| CHORD_LIST = { | |
| 'C' => [3, 0, 0, 0], | |
| 'Cm' => [3, 3, 3, 0], | |
| 'C7' => [1, 0, 0, 0], | |
| 'CM7' => [2, 0, 0, 0], | |
| 'Cm7' => [3, 3, 3, 3], | |
| 'Cdim' => [3, 2, 3, 2], | |
| 'Cm7(b5)' => [3, 2, 3, 3], | |
| 'Caug' => [3, 0, 0, 1], | |
| 'Csus4' => [3, 3, 5, 5], | |
| 'C6' => [0, 0, 0, 0], | |
| 'C7(9)' => [1, 0, 2, 0], | |
| 'CM7(9)' => [2, 0, 2, 0], | |
| 'CmM7' => [3, 3, 3, 4], | |
| 'Cadd9' => [3, 0, 2, 0], | |
| 'C#' => [4, 1, 1, 1], | |
| 'C#m' => [4, 4, 4, 1], | |
| 'C#7' => [2, 1, 1, 1], | |
| 'C#M7' => [3, 1, 1, 1], | |
| 'C#m7' => [2, 0, 1, 1], | |
| 'C#dim' => [1, 0, 1, 0], | |
| 'C#m7(b5)' => [3, 2, 3, 3], | |
| 'C#aug' => [0, 1, 1, 2], | |
| 'C#sus4' => [2, 2, 1, 1], | |
| 'C#6' => [1, 1, 1, 1], | |
| 'C#7(9)' => [2, 1, 3, 1], | |
| 'C#M7(9)' => [3, 1, 3, 1], | |
| 'C#mM7' => [3, 0, 1, 1], | |
| 'C#add9' => [4, 1, 3, 1], | |
| 'Db' => [4, 1, 1, 1], | |
| 'Dbm' => [4, 4, 4, 1], | |
| 'Db7' => [2, 1, 1, 1], | |
| 'DbM7' => [3, 1, 1, 1], | |
| 'Dbm7' => [2, 0, 1, 1], | |
| 'Dbdim' => [1, 0, 1, 0], | |
| 'Dbm7(b5)' => [3, 2, 3, 3], | |
| 'Dbaug' => [0, 1, 1, 2], | |
| 'Dbsus4' => [2, 2, 1, 1], | |
| 'Db6' => [1, 1, 1, 1], | |
| 'Db7(9)' => [2, 1, 3, 1], | |
| 'DbM7(9)' => [3, 1, 3, 1], | |
| 'DbmM7' => [3, 0, 1, 1], | |
| 'Dbadd9' => [4, 1, 3, 1], | |
| 'D' => [0, 2, 2, 2], | |
| 'Dm' => [0, 1, 2, 2], | |
| 'D7' => [3, 2, 2, 2], | |
| 'DM7' => [4, 2, 2, 2], | |
| 'Dm7' => [3, 1, 2, 2], | |
| 'Ddim' => [2, 1, 2, 1], | |
| 'Dm7(b5)' => [3, 1, 2, 1], | |
| 'Daug' => [1, 2, 2, 3], | |
| 'Dsus4' => [0, 3, 2, 2], | |
| 'D6' => [2, 2, 2, 2], | |
| 'D7(9)' => [3, 2, 4, 2], | |
| 'DM7(9)' => [4, 2, 4, 2], | |
| 'DmM7' => [4, 1, 2, 2], | |
| 'Dadd9' => [5, 2, 4, 2], | |
| 'D#' => [1, 3, 3, 0], | |
| 'D#m' => [1, 2, 3, 3], | |
| 'D#7' => [4, 3, 3, 3], | |
| 'D#M7' => [5, 3, 3, 3], | |
| 'D#m7' => [4, 2, 3, 3], | |
| 'D#dim' => [3, 2, 3, 2], | |
| 'D#m7(b5)' => [4, 2, 3, 2], | |
| 'D#aug' => [2, 3, 3, 0], | |
| 'D#sus4' => [1, 4, 3, 3], | |
| 'D#6' => [4, 4, 4, 4], | |
| 'D#7(9)' => [1, 1, 1, 0], | |
| 'D#M7(9)' => [1, 1, 2, 0], | |
| 'D#mM7' => [5, 2, 3, 3], | |
| 'D#add9' => [1, 1, 3, 0], | |
| 'Eb' => [1, 3, 3, 0], | |
| 'Ebm' => [1, 2, 3, 3], | |
| 'Eb7' => [4, 3, 3, 3], | |
| 'EbM7' => [5, 3, 3, 3], | |
| 'Ebm7' => [4, 2, 3, 3], | |
| 'Ebdim' => [3, 2, 3, 2], | |
| 'Ebm7(b5)' => [4, 2, 3, 2], | |
| 'Ebaug' => [2, 3, 3, 0], | |
| 'Ebsus4' => [1, 4, 3, 3], | |
| 'Eb6' => [4, 4, 4, 4], | |
| 'Eb7(9)' => [1, 1, 1, 0], | |
| 'EbM7(9)' => [1, 1, 2, 0], | |
| 'EbmM7' => [5, 2, 3, 3], | |
| 'Ebadd9' => [1, 1, 3, 0], | |
| 'E' => [2, 4, 4, 4], | |
| 'Em' => [2, 3, 4, 0], | |
| 'E7' => [2, 0, 2, 1], | |
| 'EM7' => [2, 0, 3, 1], | |
| 'Em7' => [2, 0, 2, 0], | |
| 'Edim' => [1, 0, 1, 0], | |
| 'Em7(b5)' => [1, 0, 2, 0], | |
| 'Eaug' => [3, 0, 0, 1], | |
| 'Esus4' => [2, 5, 4, 4], | |
| 'E6' => [2, 0, 1, 1], | |
| 'E7(9)' => [2, 2, 2, 1], | |
| 'EM7(9)' => [2, 2, 3, 1], | |
| 'EmM7' => [2, 0, 3, 0], | |
| 'Eadd9' => [2, 2, 4, 1], | |
| 'F' => [0, 1, 0, 2], | |
| 'Fm' => [3, 1, 0, 1], | |
| 'F7' => [3, 1, 3, 2], | |
| 'FM7' => [0, 0, 5, 5], | |
| 'Fm7' => [3, 1, 3, 1], | |
| 'Fdim' => [2, 1, 2, 1], | |
| 'Fm7(b5)' => [2, 1, 3, 1], | |
| 'Faug' => [0, 1, 1, 2], | |
| 'Fsus4' => [1, 1, 0, 3], | |
| 'F6' => [3, 1, 2, 2], | |
| 'F7(9)' => [3, 3, 3, 2], | |
| 'FM7(9)' => [0, 0, 0, 0], | |
| 'FmM7' => [3, 1, 4, 1], | |
| 'Fadd9' => [0, 1, 0, 0], | |
| 'F#' => [1, 2, 1, 3], | |
| 'F#m' => [0, 2, 1, 2], | |
| 'F#7' => [4, 2, 4, 3], | |
| 'F#M7' => [4, 2, 5, 3], | |
| 'F#m7' => [4, 2, 4, 2], | |
| 'F#dim' => [3, 2, 3, 2], | |
| 'F#m7(b5)' => [3, 2, 4, 2], | |
| 'F#aug' => [1, 2, 2, 3], | |
| 'F#sus4' => [4, 2, 4, 4], | |
| 'F#6' => [4, 2, 3, 3], | |
| 'F#7(9)' => [4, 4, 4, 3], | |
| 'F#M7(9)' => [1, 1, 1, 1], | |
| 'F#mM7' => [4, 2, 5, 2], | |
| 'F#add9' => [1, 2, 1, 1], | |
| 'Gb' => [1, 2, 1, 3], | |
| 'Gbm' => [0, 2, 1, 2], | |
| 'Gb7' => [4, 2, 4, 3], | |
| 'GbM7' => [4, 2, 5, 3], | |
| 'Gbm7' => [4, 2, 4, 2], | |
| 'Gbdim' => [3, 2, 3, 2], | |
| 'Gbm7(b5)' => [3, 2, 4, 2], | |
| 'Gbaug' => [1, 2, 2, 3], | |
| 'Gbsus4' => [4, 2, 4, 4], | |
| 'Gb6' => [4, 2, 3, 3], | |
| 'Gb7(9)' => [4, 4, 4, 3], | |
| 'GbM7(9)' => [1, 1, 1, 1], | |
| 'GbmM7' => [4, 2, 5, 2], | |
| 'Gbadd9' => [1, 2, 1, 1], | |
| 'G' => [2, 3, 2, 0], | |
| 'Gm' => [1, 3, 2, 0], | |
| 'G7' => [2, 1, 2, 0], | |
| 'GM7' => [2, 2, 2, 0], | |
| 'Gm7' => [1, 1, 2, 0], | |
| 'Gdim' => [1, 0, 1, 0], | |
| 'Gm7(b5)' => [1, 1, 1, 0], | |
| 'Gaug' => [2, 3, 3, 0], | |
| 'Gsus4' => [3, 3, 2, 0], | |
| 'G6' => [2, 0, 2, 0], | |
| 'G7(9)' => [2, 1, 2, 2], | |
| 'GM7(9)' => [2, 2, 2, 2], | |
| 'GmM7' => [5, 3, 6, 3], | |
| 'Gadd9' => [2, 3, 2, 2], | |
| 'G#' => [3, 4, 3, 5], | |
| 'G#m' => [2, 4, 3, 1], | |
| 'G#7' => [3, 2, 3, 1], | |
| 'G#M7' => [3, 3, 3, 1], | |
| 'G#m7' => [2, 2, 3, 1], | |
| 'G#dim' => [2, 1, 2, 1], | |
| 'G#m7(b5)' => [2, 2, 2, 1], | |
| 'G#aug' => [3, 0, 0, 1], | |
| 'G#sus4' => [4, 4, 3, 1], | |
| 'G#6' => [3, 1, 3, 1], | |
| 'G#7(9)' => [3, 2, 3, 3], | |
| 'G#M7(9)' => [3, 3, 3, 3], | |
| 'G#mM7' => [6, 4, 7, 4], | |
| 'G#add9' => [3, 4, 3, 3], | |
| 'Ab' => [3, 4, 3, 5], | |
| 'Abm' => [2, 4, 3, 1], | |
| 'Ab7' => [3, 2, 3, 1], | |
| 'AbM7' => [3, 3, 3, 1], | |
| 'Abm7' => [2, 2, 3, 1], | |
| 'Abdim' => [2, 1, 2, 1], | |
| 'Abm7(b5)' => [2, 2, 2, 1], | |
| 'Abaug' => [3, 0, 0, 1], | |
| 'Absus4' => [4, 4, 3, 1], | |
| 'Ab6' => [3, 1, 3, 1], | |
| 'Ab7(9)' => [3, 2, 3, 3], | |
| 'AbM7(9)' => [3, 3, 3, 3], | |
| 'AbmM7' => [6, 4, 7, 4], | |
| 'Abadd9' => [3, 4, 3, 3], | |
| 'A' => [0, 0, 1, 2], | |
| 'Am' => [0, 0, 0, 2], | |
| 'A7' => [0, 0, 1, 0], | |
| 'AM7' => [0, 0, 1, 1], | |
| 'Am7' => [0, 0, 0, 0], | |
| 'Adim' => [3, 2, 3, 2], | |
| 'Am7(b5)' => [3, 3, 3, 2], | |
| 'Aaug' => [0, 1, 1, 2], | |
| 'Asus4' => [0, 0, 2, 2], | |
| 'A6' => [4, 2, 4, 2], | |
| 'A7(9)' => [2, 3, 1, 2], | |
| 'AM7(9)' => [2, 4, 1, 2], | |
| 'AmM7' => [0, 0, 0, 1], | |
| 'Aadd9' => [2, 0, 1, 2], | |
| 'A#' => [1, 1, 2, 3], | |
| 'A#m' => [1, 1, 1, 3], | |
| 'A#7' => [1, 1, 2, 1], | |
| 'A#M7' => [0, 1, 2, 3], | |
| 'A#m7' => [1, 1, 1, 1], | |
| 'A#dim' => [1, 0, 1, 0], | |
| 'A#m7(b5)' => [1, 0, 1, 1], | |
| 'A#aug' => [1, 2, 2, 3], | |
| 'A#sus4' => [1, 1, 3, 3], | |
| 'A#6' => [1, 1, 2, 0], | |
| 'A#7(9)' => [3, 4, 2, 3], | |
| 'A#M7(9)' => [5, 5, 5, 5], | |
| 'A#mM7' => [1, 1, 1, 2], | |
| 'A#add9' => [3, 1, 2, 3], | |
| 'Bb' => [1, 1, 2, 3], | |
| 'Bbm' => [1, 1, 1, 3], | |
| 'Bb7' => [1, 1, 2, 1], | |
| 'BbM7' => [0, 1, 2, 3], | |
| 'Bbm7' => [1, 1, 1, 1], | |
| 'Bbdim' => [1, 0, 1, 0], | |
| 'Bbm7(b5)' => [1, 0, 1, 1], | |
| 'Bbaug' => [1, 2, 2, 3], | |
| 'Bbsus4' => [1, 1, 3, 3], | |
| 'Bb6' => [1, 1, 2, 0], | |
| 'Bb7(9)' => [3, 4, 2, 3], | |
| 'BbM7(9)' => [5, 5, 5, 5], | |
| 'BbmM7' => [1, 1, 1, 2], | |
| 'Bbadd9' => [3, 1, 2, 3], | |
| 'B' => [2, 2, 3, 4], | |
| 'Bm' => [2, 2, 2, 4], | |
| 'B7' => [2, 2, 3, 2], | |
| 'BM7' => [1, 2, 3, 4], | |
| 'Bm7' => [2, 2, 2, 2], | |
| 'Bdim' => [2, 1, 2, 1], | |
| 'Bm7(b5)' => [2, 1, 2, 2], | |
| 'Baug' => [2, 3, 3, 4], | |
| 'Bsus4' => [2, 2, 4, 4], | |
| 'B6' => [2, 2, 3, 1], | |
| 'B7(9)' => [4, 2, 3, 2], | |
| 'BM7(9)' => [4, 1, 3, 3], | |
| 'BmM7' => [2, 2, 2, 3], | |
| 'Badd9' => [4, 2, 3, 4], | |
| } | |
| NOTES = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'] | |
| STRINGS = ['G', 'C', 'E', 'A'] | |
| def draw_chord(chord_name) | |
| # chord_name.gsub!("x", "#") | |
| if not FileTest.exist? "/home/tom/ukulele/static/chords/"+chord_name+".png" | |
| chord(chord_name) | |
| end | |
| end | |
| def chord(chord_name) | |
| return generate(chord_name, get_flets(chord_name.gsub("x", "#"))) | |
| end | |
| def get_flets(chord_name) | |
| if CHORD_LIST.has_key? chord_name then | |
| return CHORD_LIST[chord_name].reverse | |
| else | |
| chord_name.sub!("maj", "M") | |
| if CHORD_LIST.has_key? chord_name then | |
| return CHORD_LIST[chord_name].reverse | |
| end | |
| end | |
| end | |
| def generate(chord, flets) | |
| # Frets are 10px high | |
| # The strings are 12px apart | |
| height = (flets.max * 10) + 60 | |
| width = ((STRINGS.length - 1) * 12) + 16 | |
| last_fret = 15 + ((flets.max + 1) * 10) | |
| last_string = 5 + ((STRINGS.length - 1) * 12) | |
| canvas = Magick::Image.new(width, height) | |
| gc = Magick::Draw.new | |
| gc.stroke('gray25') | |
| (0..(STRINGS.length - 1)).each do |string| | |
| gc.line(5 + 12 * string, 15, 5 + 12 * string, last_fret) | |
| end | |
| (0..(flets.max + 1)).each do |fret| | |
| if fret == 0 | |
| gc.stroke_width(3) | |
| else | |
| gc.stroke_width(1) | |
| end | |
| gc.line(5, 15 + 10 * fret, last_string, 15 + 10 * fret) | |
| end | |
| gc.stroke('transparent') | |
| i = 0 | |
| flets.each { |f| | |
| if f > 0 then | |
| gc.circle( | |
| 5 + 12 * i, | |
| 15 + 10 * f, | |
| 8 + 12 * i, | |
| 18 + 10 * f | |
| ) | |
| end | |
| a = NOTES.index(STRINGS[i]) + f | |
| n = a % NOTES.length | |
| gc.font_family = "arial" | |
| gc.pointsize = 6 | |
| gc.text(1 + 13 * i, last_fret + 14, NOTES[n]) | |
| i = i + 1 | |
| } | |
| gc.font_weight = 100 | |
| gc.pointsize = 11 | |
| gc.text(0, 10, chord.gsub("x", "#")) | |
| gc.draw(canvas) | |
| canvas.write('static/chords/'+chord+".png") | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment