// Script which maps keyboard events into piano keys, allowing you to // play melodies on the computer keyboard, tracker-style. // Works for US keyboards only, however the keymap can be easily changed. // (Generated by examining output from Chuck's kb.ck example file.) // This may need some work to support polyphony properly. Specifically, // the single Event will need an array of notes, and timing will have to // be measured to detect chords. // - Radarsat-1, 2007 // radarsat1@gmail.com KBHit kb; false => int verbose; 5 => int octave; class KeyEvent extends Event { int note; float freq; string notename; int octave; } public class kbpiano { static KeyEvent@ evt; } KeyEvent kevt @=> kbpiano.evt; // Unused, but good for reference -- upper keyboard octave keycodes [113, 50, 119, 51, 101, 114, 53, 116, 54, 121, 55, 117, 105, 57, 111, 48, 112, 91, 61, 93] @=> int upper[]; // Unused, but good for reference -- lower keyboard octave keycodes [122, 115, 120, 100, 99, 118, 103, 98, 104, 110, 106, 109, 44, 108, 46, 59, 47] @=> int lower[]; [27, 91, 65] @=> int octup[]; // Cursor up [27, 91, 66] @=> int octdown[]; // Cursor down ["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"] @=> string notes[]; [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12, -1, 14, 16, 27, -1, 13, 15, -1, 18, 20, 22, -1, 25, -1, 15, -1, 30, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29, -1, 31, -1, -1, -1, -1, 7, 4, 3, 16, -1, 6, 8, 24, 10, -1, 13, 11, 9, 26, 28, 12, 17, 1, 19, 23, 5, 14, 2, 21, 0, -1, -1, -1, -1, -1] @=> int keymap[]; fun void handle_octave() { kb => now; kb.getchar() => int char; if ((char == octup[1]) || (char == octdown[1])) { kb => now; kb.getchar() => char; if (char == octup[2]) { octave+1 => octave; if (octave > 8) 8 => octave; } else if ((char == octdown[2])) { octave-1 => octave; if (octave < 0) 0 => octave; } if (verbose) <<<"Octave:",octave>>>; } } while (true) { kb => now; while (kb.more()) { kb.getchar() => int char; if ((char == octup[0]) || (char == octdown[0])) { handle_octave(); } else { keymap[char] => int note; if (note >= 0) { if (verbose) <<>>; note + (octave*12) => kevt.note; octave => kevt.octave; notes[note%12] => kevt.notename; Math.mtof(kevt.note) => kevt.freq; kevt.broadcast(); } } } }