Created
September 1, 2008 16:54
-
-
Save ahx/8322 to your computer and use it in GitHub Desktop.
A very simple onscreen midi-keyboard using Shoes and Midator.
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
# | |
# A simple onscreen midi-keyboard using Shoes and Midiator. | |
# No key-up Event. | |
# | |
# Set Keyboard layout here: | |
KEYBOARD_LAYOUT = :de # only :de and :us are supported, by now. See MidiKeymap#map_keys! | |
# | |
# You will need a midi input for this. | |
# On OSX you could use http://notahat.com/midi_patchbay | |
# and http://notahat.com/simplesynth or Garage Band | |
# | |
# Authors: Andreas Haller(http://github.com/ahaller) | |
# Copyright (c) 2008 Andreas Haller | |
# This code released under the terms of the MIT license. | |
# | |
# enjoy. | |
Shoes.setup do | |
gem 'midiator >= 0.2.0' | |
end | |
require 'midiator' | |
# Methods for drawing the piano keys | |
module ClaviatureDrawing | |
module Highlightable | |
def highlight | |
self.style :stroke => app.fuchsia | |
end | |
def unhighlight | |
self.style :stroke => app.black | |
end | |
end | |
def draw_keys | |
stroke black | |
strokewidth 4 | |
key_pattern = [:w,:b,:w,:b,:w,:w,:b,:w,:b,:w,:b,:w] | |
keys = [] | |
20.times do |i| | |
key_type = key_pattern[i % key_pattern.length] | |
case key_type | |
when :w | |
k = draw_white_key | |
translate 64, 0 | |
when :b | |
# FIXME Fix z-index of black keys. The black keys should be in front of white keys. | |
k = draw_black_key | |
end | |
k.extend Highlightable | |
keys << k | |
end | |
keys | |
end | |
def draw_white_key | |
nofill | |
rect 0, 0, 60, 130, 4 | |
end | |
def draw_black_key | |
fill black | |
rect -20, 0, 40, 80, 4 | |
end | |
end | |
# Responsible for mapping Keystrings to Midi-tones. | |
class Keymap | |
attr_accessor :octave | |
def initialize(options = {}) | |
options = { | |
:layout => :de, | |
:octave => 2 | |
}.merge!(options) | |
@octave = options[:octave] | |
set_layout!(options[:layout]) | |
end | |
def midi_tone_of(keystring) | |
# TODO Oktave richtig mit einberechnen!.. | |
(@octave+1) * 12 + @tones[keystring] | |
end | |
# Method to find out, which key has been pressed, the most left key is 0 ... | |
def index_of(keystring) | |
@tones[keystring] | |
end | |
private | |
def set_layout!(lang) | |
@keys = { | |
:de => %w(a w s e d f t g z h u j k o l p ö ä + # ), | |
:us => %w(a w s e d f t g y h u j k o l p ; ' ] \\ ) | |
}[lang] | |
map_keys! | |
end | |
def map_keys! | |
@tones = {} | |
@keys.each_with_index do |k, i| | |
@tones[k] = i | |
end | |
end | |
end | |
# The Shoes App | |
Shoes.app(:title => "Midi Keyboard", :width => 766, :height => 136, :resizable => false) do | |
self.extend ClaviatureDrawing | |
def play(note, time) | |
# Midiator sleeps for 'time' after each note, so we start a new threat (is this ok?) | |
Thread.new { @midi.play(note, time) } # note, duration, channel, velocity | |
end | |
def highlight(shape, time) | |
shape.highlight | |
timer time do | |
shape.unhighlight | |
end | |
end | |
background yellow | |
# setup midi driver | |
@midi = MIDIator::Interface.new | |
@midi.autodetect_driver | |
# setup keymap | |
@keymap = Keymap.new(:layout => KEYBOARD_LAYOUT) | |
# draw keys | |
@key_shapes = draw_keys | |
keypress do |key| | |
case key | |
when "1" | |
@keymap.octave -= 1 | |
when "2" | |
@keymap.octave += 1 | |
else | |
t = 1 | |
play(@keymap.midi_tone_of(key), t) | |
highlight(@key_shapes[@keymap.index_of(key)], t) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment