//====================================// // accordeome // // by Stefan Blixt // // 2007-12-30 // // last update: 2008-01-05 // //====================================// 1 => int USE_MIDI; 4 => int MIDI_DEVICE_AMOUNT; 0 => int MIDI_DEVICE; MidiOut midiOuts[MIDI_DEVICE_AMOUNT]; for ( 0 => int i; i < MIDI_DEVICE_AMOUNT; i++) { if (midiOuts[i].open(i)) { <<< "Opened MIDI device #", i, ": ", midiOuts[i].name() >>>; } else { <<< "Could not open MIDI device ", i >>>; } } //==== Voices ==== class Voice { int index; 0 => int playCount; 0 => int midiNote; fun void play(int inMidiNote) {} fun void release() {} } class MidiVoice extends Voice { MidiMsg midiMsg; fun void play(int inMidiNote) { // <<< "Play ", inMidiNote >>>; inMidiNote => midiNote; 0x90 + 0 => midiMsg.data1; // Note on + MIDI channel (sample) midiNote => midiMsg.data2; // Note value 127 => midiMsg.data3; // velocity midiOuts[MIDI_DEVICE].send(midiMsg); } fun void release() { // <<< "Release ", midiNote >>>; 0x80 + 0 => midiMsg.data1; // Note off + MIDI channel (sample) midiNote => midiMsg.data2; // Note value 0 => midiMsg.data3; // velocity midiOuts[MIDI_DEVICE].send(midiMsg); } } 0 => int nextVoice; 16 => int voiceCount; //SndVoice voices[voiceCount]; MidiVoice voices[voiceCount]; for ( 0 => int i; i < voiceCount; i++) { i => voices[i].index; } fun int playNote(int midiNote) { for (0 => int i; i < voiceCount; i++) { if (voices[i].midiNote == midiNote && voices[i].playCount > 0) { return ++voices[i].playCount; } } nextVoice => int firstNextVoice; while(voices[nextVoice].playCount > 0) { if (++nextVoice >= voiceCount) { 0 => nextVoice; } if (nextVoice == firstNextVoice) { break; } } voices[nextVoice].play(midiNote); 1 => voices[nextVoice].playCount; if (++nextVoice >= voiceCount) { 0 => nextVoice; } return 1; } fun int releaseNote(int midiNote) { for (0 => int i; i < voiceCount; i++) { if (voices[i].midiNote == midiNote && voices[i].playCount > 0) { if (--voices[i].playCount < 1) { voices[i].release(); } return voices[i].playCount; } } return -1; } //==== OSC ==== OscSend xmit; xmit.setHost("localhost", 8080); OscRecv orec; 8000 => orec.port; orec.listen(); orec.event("/256/press,i,i,i") @=> OscEvent pressEvent; //==== Monome input ==== 60 => int C; 62 => int D; 64 => int E; 65 => int F; 67 => int G; 69 => int A; 71 => int H; 12 => int OCT; [ [H, H+1, D + 1*OCT, D + 1 + 1*OCT, F + 1*OCT], [A, A+1, C + 1*OCT, C + 1 + 1*OCT, E + 1*OCT], [G, G+1, H, H+1, D + 1*OCT ], [F, F+1, A, A+1, C + 1*OCT], [E, E+1, G, G+1, H], [D, D+1, F, F+1, A], [C, C+1, E, E+1, G]] @=> int oneSection[][]; int keyboard[16][15]; 6 => int sectionLine; -2 => int octave; for (0 => int j; j < 3; j++) { for (0 => int i; i < 16; i++) { for (0 => int x; x < 5; x++) { oneSection[sectionLine][x] + (octave-1)*OCT => keyboard[i][j*5 + x]; } if (--sectionLine < 0) { 6 => sectionLine; octave++; } } } fun void keyPressed(int x, int y) { // <<< "Pressed: ", x, "/", y >>>; if (x >= 15 || y >= 16) { return; } keyboard[y][x] => int midiNote; if (playNote(midiNote) == 1) { for (0 => int keyX; keyX < 15; keyX++) { for (0 => int keyY; keyY < 16; keyY++) { if (keyboard[keyY][keyX] == midiNote) { // Light corresponding key xmit.startMsg("/256/led", "i i i"); keyX => xmit.addInt; keyY => xmit.addInt; 1 => xmit.addInt; } } } } } fun void keyReleased(int x, int y) { // <<< "Released: ", x, "/", y >>>; if (x >= 15 || y >= 16) { return; } keyboard[y][x] => int midiNote; if (releaseNote(midiNote) == 0) { for (0 => int keyX; keyX < 15; keyX++) { for (0 => int keyY; keyY < 16; keyY++) { if (keyboard[keyY][keyX] == midiNote) { // Darken corresponding key xmit.startMsg("/256/led", "i i i"); keyX => xmit.addInt; keyY => xmit.addInt; 0 => xmit.addInt; } } } } } xmit.startMsg("/256/clear", "i"); 1 => xmit.addInt; 1::second => now; xmit.startMsg("/256/clear", "i"); 0 => xmit.addInt; while (true) { pressEvent => now; while (pressEvent.nextMsg() != 0) { pressEvent.getInt() => int x; pressEvent.getInt() => int y; pressEvent.getInt() => int state; // <<< "Press event: ", x, "/", y, "/", state >>>; if (state == 1) { keyPressed(x, y); } else { keyReleased(x, y); } } }