Midi_keyboard
Using aconnect
and aseqdump
to make a simple terminal piano keyboard.
It’s just a sketch.. version 0.0.1.
TODO Link to heading
- detect screenwidth
- more fullsize keyboard
- update ‘chords’ on release
- detect ‘hung’ keys
- output intervals and chord-names
CODE Link to heading
require 'set'
require 'open3'
acon = `aconnect -i`.scan(/client (\d+): '(.*?)'/).to_h
puts 'Select Instrument by number :'
acon.each {|k, v| puts '[%s] %s' % [k, v]}
PORT = gets.chomp
PIANO = DATA.read
WHITE,BLACK = [0,2,4,5,7,9,11], [1,3,-1,6,8,10]
abort('No such Instrument') unless inst = acon[PORT]
wr, RD = Open3.popen2("aseqdump -p #{PORT}"); wr.close
X = {
cls: proc {print "\e[2J"},
cursor: proc {|show| print show ? "\e[?25h" : "\e[?25l"},
at: proc {|l,c| print "\e[#{l};#{c}H"},
red: proc {|s| print "\e[37;41m#{s}\e[0m"},
rat: proc {|l,c,str| X.at[l,c]; X.red[str]},
piano: proc {X.at[0,0]; print PIANO},
keys: proc {|held|
held.each {|key|
lc = BLACK.include?(key) ?
[2, BLACK.index(key) * 4 + 5, ' '] :
[4, (i=WHITE.index(key)) * 4 + 3, 'CDEFGAB'[i]]
X.rat[*lc]
}
},
twelve: proc {|s| s.to_a.map {|i| i % 12 }},
bye: proc {RD.close; X.cursor[true]; exit}
}.then {|hsh| Struct.new(*hsh.keys).new(*hsh.values)}
trap('SIGINT') { X.bye[] }
X.cls[]; X.cursor[false]; X.piano[]
held = Set[]
# main loop
while line = RD.gets
if line =~ /Note (on|off).*?note (\d+)/
$1['on'] ? held.add($2.to_i) : held.delete($2.to_i)
held.empty? ? X.piano[] : X.keys[X.twelve[held]]
end
end
X.bye[]
__END__
| |█| |█| | |█| |█| |█| |
| |█| |█| | |█| |█| |█| |
| | | | | | | |
| C | D | E | F | G | A | B |