/*---------------------------------------------------------------------------- S.M.E.L.T. : Small Musically Expressive Laptop Toolkit Copyright (c) 2007 Rebecca Fiebrink and Ge Wang. All rights reserved. http://smelt.cs.princeton.edu/ http://soundlab.cs.princeton.edu/ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 U.S.A. -----------------------------------------------------------------------------*/ //----------------------------------------------------------------------------- // name: kb-fret_scordatura.multi.ck // desc: this program maps key-down events to // pitches via a fretboard-like mapping. // allows for arbitrary "string" tuning and transposition // // author: Dan Trueman // adapted from SMELT code by Rebecca Fiebrink and Ge Wang // // to run (in command line chuck): // %> chuck kb-fret_scordatura.multi.ck // // to run (in miniAudicle): // (make sure VM is started, add the thing) //----------------------------------------------------------------------------- // base and register // left/right arrows lower/raise register 12 => int base; 3 => int register; 0 => int reg_change; // keyboard HidIn kb; // hid message HidMsg msgG; // open if( !kb.openKeyboard( 0 ) ) me.exit(); <<< "Ready?", "" >>>; // key map int key[256]; //array with key codes, for MacBook anyhow [ [29, 27, 6, 25, 5, 17, 16, 54, 55, 56], //zxcv... row [4, 22, 7, 9, 10, 11, 13, 14, 15, 51, 52], //asdf... row [20, 26, 8, 21, 23, 28, 24, 12, 18, 19, 47, 48, 49], //qwer... row [30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 45, 46, 42] //1234... row ] @=> int row[][]; //tune them strings, in fifths here, like a viola tuneString(0, 0); tuneString(1, 7); tuneString(2, 14); tuneString(3, 21); //to transpose entire instrument; 0 => C below middle C as root 7 => int transp; //transpose it up a fifth, so it's like a violin //function to tune strings //"which" indicates which row (0 to 4, bottom to top) //"note" indicates transposition from 48 (C below middle C) //so, 0=>note will tune the string in half steps above 48 fun void tuneString(int which, int note) { //note % 12 => note; for(0 => int j; j < row[which].cap(); j++) { note + j => key[row[which][j]]; <<>>; } } // yes fun void registerUp() { if( register < 10 ) { register++; 1 => reg_change; } <<< "register:", register >>>; } // yes fun void registerDown() { if( register > 0 ) { register--; 1 => reg_change; } <<< "register:", register >>>; } float freq; // infinite event loop while( true ) { // wait for event kb => now; // get message while( kb.recv( msgG ) ) { // which <<>>; if( msgG.which > 256 ) continue; if( key[msgG.which] == 0 && msgG.which != 29 ) { // register if( msgG.which == 80 && msgG.isButtonDown() ) registerDown(); else if( msgG.which == 79 && msgG.isButtonDown() ) registerUp(); } // set else if( msgG.isButtonDown() ) { spork ~ bar_voice(msgG); } } } function void bar_voice( HidMsg msg) { // sound synthesis SinOsc bar => ADSR e => JCRev r => dac; e.set(20::ms, 0::ms, 1., 100::ms); bar.gain(0.3); e.keyOn(1); // set mix .01 => r.mix; // bar settings //4 => bar.preset; // freq base + register * 12 + key[msg.which] + transp => Std.mtof => bar.freq; // fire! //1 => bar.noteOn; 100::ms => now; e.keyOff(1); 100::ms => now; }