Created
November 17, 2008 16:00
-
-
Save tmcw/25809 to your computer and use it in GitHub Desktop.
This file contains 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:macwright@gmail.com) | |
# 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