From CSWiki
Hid hi;
HidMsg msg;
0 => int deviceNum;
hi.openKeyboard( deviceNum ) => int deviceAvailable;
if ( deviceAvailable == 0 ) me.exit();
<<< "keyboard '", hi.name(), "' ready" >>>;
SinOsc sine => ADSR envelope => dac;
envelope.set(20::ms, 25::ms, 0.1, 150::ms);
//array with key codes, for MacBook anyhow
[
[30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 45, 46, 42], //1234... row
[20, 26, 8, 21, 23, 28, 24, 12, 18, 19, 47, 48, 49], //qwer... row
[4, 22, 7, 9, 10, 11, 13, 14, 15, 51, 52], //asdf... row
[29, 27, 6, 25, 5, 17, 16, 54, 55, 56] //zxcv... row
] @=> int row[][];
//our big array of pitch values, indexed by ASCII value
int keyToPitch_table[256];
//this function takes each row and tunes it in half steps, based
//on whatever fundamental pitch note specified
fun void tuneString(int whichString, int basepitch) {
for (0 => int i; i < row[whichString].cap(); i++) {
basepitch + i => keyToPitch_table[row[whichString][i]];
<<<row[whichString][i], keyToPitch_table[row[whichString][i]]>>>;
}
}
//tune them strings in 5ths
tuneString(3, 55);
tuneString(2, 62);
tuneString(1, 69);
tuneString(0, 76);
while( true )
{
hi => now;
while( hi.recv( msg ) )
{
if( msg.isButtonDown() )
{
<<< "down:", msg.which >>>;
//set the pitch, based on key value
keyToPitch_table[ msg.which ] => Std.mtof => sine.freq;
<<<sine.freq()>>>;
//turn the note on, wait 1.5 seconds, turn it off
envelope.keyOn();
150::ms => now;
envelope.keyOff();
}
else
{
<<< "up:", msg.which >>>;
}
}
}