To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.
root / CollidoscopeTeensy / CollidoscopeTeensy_new.ino @ 13:69d60ae38d62
History | View | Annotate | Download (9.01 KB)
| 1 | 1:b5bcad8e7803 | f | |
|---|---|---|---|
| 2 | /****************************************************************************** |
||
| 3 | 5:75b744078d66 | f | * Copyright (C) 2015 Ben Bengler (mail@benbengler.com) |
| 4 | * Copyright (C) 2016 Queen Mary University of London |
||
| 5 | 13:69d60ae38d62 | f | * Authors: Ben Bengler, Fiore Martin, Christopher Paton (christopher.paton@gmail.com) |
| 6 | 1:b5bcad8e7803 | f | * |
| 7 | 5:75b744078d66 | f | * This file is part of Collidoscope. |
| 8 | * |
||
| 9 | * Collidoscope is free software: you can redistribute it and/or modify |
||
| 10 | * it under the terms of the GNU General Public License as published by |
||
| 11 | * the Free Software Foundation, either version 3 of the License, or |
||
| 12 | * (at your option) any later version. |
||
| 13 | * |
||
| 14 | * This program is distributed in the hope that it will be useful, |
||
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
| 17 | * GNU General Public License for more details. |
||
| 18 | * |
||
| 19 | * You should have received a copy of the GNU General Public License |
||
| 20 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
||
| 21 | 1:b5bcad8e7803 | f | * |
| 22 | 5:75b744078d66 | f | **************************************************************************** |
| 23 | * |
||
| 24 | 1:b5bcad8e7803 | f | * Teensy 2 ++ pinout: https://www.pjrc.com/teensy/card4b.pdf |
| 25 | * |
||
| 26 | * ANALOG INPUTS: |
||
| 27 | * Wavejet -> F0 (38) [Horizontal rail 1] |
||
| 28 | * Wavejet -> F1 (39) [Horizontal rail 2] |
||
| 29 | * Filter 1 -> F2 (40) [Vertical rail 1] |
||
| 30 | * Filter 2 -> F4 (42) [Vertical rail 2] |
||
| 31 | * |
||
| 32 | * DIGITAL INPUTS [INTERRUPTS]: |
||
| 33 | * Sel. length 1 -> INT0/INT1 (0, 1) [Encoder 1] |
||
| 34 | * Sel. length 2 -> INT2/INT3 (2, 3) [Encoder 2] |
||
| 35 | * Duration 1 -> INT4/INT5 (36, 37)[Encoder 3] |
||
| 36 | * Duration 2 -> INT6/INT7 (18, 19)[Encoder 4] |
||
| 37 | * |
||
| 38 | * DIGITAL INPUTS: |
||
| 39 | * Play1 toggle -> B0 (20) |
||
| 40 | * Record1 -> B1 (21) |
||
| 41 | * Play2 toggle -> B3 (22) |
||
| 42 | * Record2 -> B4 (24) |
||
| 43 | * |
||
| 44 | * DIGITAL OUTPUTS: |
||
| 45 | * Record Button 1 Led -> D4 (4) |
||
| 46 | * Record Button 2 Led -> D5 (5) |
||
| 47 | 5:75b744078d66 | f | * |
| 48 | 1:b5bcad8e7803 | f | ******************************************************************************/ |
| 49 | |||
| 50 | #include <Encoder.h> |
||
| 51 | #include <Bounce.h> |
||
| 52 | |||
| 53 | /////////////////////////////////////////////////// |
||
| 54 | //MIDI settings |
||
| 55 | const int midi_chan_inst1 = 1; // MIDI channel for Instrument 1 |
||
| 56 | const int midi_chan_inst2 = 2; // MIDI channel for Instrument 2 |
||
| 57 | |||
| 58 | const int cc_length = 1; // MIDI cc controlling selection length |
||
| 59 | const int cc_duration = 2; // MIDI cc controlling duration |
||
| 60 | const int cc_filter = 7; // MIDI cc controlling LP filter |
||
| 61 | const int cc_play = 4; // MIDI cc controlling PLAY |
||
| 62 | const int cc_record = 5; // MIDI cc controlling RECORD |
||
| 63 | //const int cc_reset = 100; // MIDI cc controlling instrument RESET |
||
| 64 | |||
| 65 | /////////////////////////////////////////////////// |
||
| 66 | //Default Values: |
||
| 67 | const int Enc_def = 64; //default selection length |
||
| 68 | int MIDI_led_state = LOW; |
||
| 69 | |||
| 70 | /////////////////////////////////////////////////// |
||
| 71 | // Interface Inputs |
||
| 72 | |||
| 73 | 13:69d60ae38d62 | f | //Buttons |
| 74 | 1:b5bcad8e7803 | f | |
| 75 | const int Pin_play1 = 20; //B0 |
||
| 76 | const int Pin_record1 = 21; //B1 |
||
| 77 | const int Pin_play2 = 23; //B3 |
||
| 78 | const int Pin_record2 = 24; //B4 |
||
| 79 | const int Pin_record1_led = 4; //D4 |
||
| 80 | const int Pin_record2_led = 5; //D5 |
||
| 81 | const int Pin_MIDIled = 6; |
||
| 82 | |||
| 83 | Bounce button1 = Bounce(Pin_play1, 5); |
||
| 84 | Bounce button2 = Bounce(Pin_record1, 5); |
||
| 85 | Bounce button3 = Bounce(Pin_play2, 5); |
||
| 86 | Bounce button4 = Bounce(Pin_record2, 5); |
||
| 87 | |||
| 88 | |||
| 89 | 13:69d60ae38d62 | f | //Encoders |
| 90 | 1:b5bcad8e7803 | f | Encoder Enc1 (0, 1); //Encoder for section length on Wavejet 1 |
| 91 | Encoder Enc2 (2, 3); //Encoder for section length on Wavejet 2 |
||
| 92 | 13:69d60ae38d62 | f | Encoder Enc3 (36, 37); //Encoder for duration of Wavejet 1 [granularisation effect] |
| 93 | Encoder Enc4 (18, 19); //Encoder for duration of Wavejet 2 [granularisation effect] |
||
| 94 | |||
| 95 | 1:b5bcad8e7803 | f | |
| 96 | // Variables |
||
| 97 | 13:69d60ae38d62 | f | const int jitter_thresh = 10; // threshold value for analog INs to make up for input jitter |
| 98 | 1:b5bcad8e7803 | f | |
| 99 | //Store recent values to detect parameter change |
||
| 100 | long Enc1_old = -999; |
||
| 101 | long Enc2_old = -999; |
||
| 102 | 13:69d60ae38d62 | f | |
| 103 | long Enc3_old = 0; |
||
| 104 | long Enc4_old = 0; |
||
| 105 | 1:b5bcad8e7803 | f | |
| 106 | uint16_t Jet1_old = 0; |
||
| 107 | int16_t Jet1_old_MIDI = -1; |
||
| 108 | uint16_t Jet2_old = 0; |
||
| 109 | int16_t Jet2_old_MIDI = -1; |
||
| 110 | 13:69d60ae38d62 | f | |
| 111 | 1:b5bcad8e7803 | f | uint16_t filter1_old = 0; |
| 112 | int16_t filter1_old_MIDI = -1; |
||
| 113 | uint16_t filter2_old = 0; |
||
| 114 | int16_t filter2_old_MIDI = -1; |
||
| 115 | |||
| 116 | 13:69d60ae38d62 | f | uint16_t dur1_old = 0; |
| 117 | int16_t dur1_old_MIDI = -1; |
||
| 118 | uint16_t dur2_old = 0; |
||
| 119 | int16_t dur2_old_MIDI = -1; |
||
| 120 | 1:b5bcad8e7803 | f | |
| 121 | 13:69d60ae38d62 | f | |
| 122 | void setup() |
||
| 123 | {
|
||
| 124 | pinMode(Pin_play1, INPUT_PULLUP); |
||
| 125 | pinMode(Pin_record1, INPUT_PULLUP); |
||
| 126 | pinMode(Pin_play2, INPUT_PULLUP); |
||
| 127 | pinMode(Pin_record2, INPUT_PULLUP); |
||
| 128 | |||
| 129 | |||
| 130 | pinMode(Pin_MIDIled, OUTPUT); |
||
| 131 | pinMode(Pin_record1_led, OUTPUT); |
||
| 132 | pinMode(Pin_record2_led, OUTPUT); |
||
| 133 | } |
||
| 134 | |||
| 135 | void loop() |
||
| 136 | {
|
||
| 137 | 1:b5bcad8e7803 | f | digitalWrite(Pin_MIDIled, LOW); |
| 138 | digitalWrite(Pin_record1_led, HIGH); |
||
| 139 | digitalWrite(Pin_record2_led, HIGH); |
||
| 140 | 13:69d60ae38d62 | f | |
| 141 | 1:b5bcad8e7803 | f | button1.update(); |
| 142 | button2.update(); |
||
| 143 | button3.update(); |
||
| 144 | button4.update(); |
||
| 145 | |||
| 146 | 13:69d60ae38d62 | f | uint16_t Jet1_new = analogRead(0); //read Wavejet/Rail 1; ADJUST INPUT RANGE ACCORDING TO SENSOR |
| 147 | uint16_t Jet2_new = analogRead(1); //read Wavejet/Rail 2; ADJUST INPUT RANGE ACCORDING TO SENSOR |
||
| 148 | uint16_t filter1_new = analogRead(2); //read filter Instrument 1; ADJUST INPUT RANGE ACCORDING TO SENSOR |
||
| 149 | uint16_t filter2_new = analogRead(4); //read filter Instrument 2; ADJUST INPUT RANGE ACCORDING TO SENSOR |
||
| 150 | uint16_t dur1_new = analogRead(3); |
||
| 151 | uint16_t dur2_new = analogRead(5); |
||
| 152 | 1:b5bcad8e7803 | f | |
| 153 | 13:69d60ae38d62 | f | //------ SEND INSTRUMENT 1 MIDI ----------- |
| 154 | 1:b5bcad8e7803 | f | |
| 155 | 13:69d60ae38d62 | f | // Play button instrument 1 |
| 156 | if (button1.fallingEdge()){
|
||
| 157 | usbMIDI.sendControlChange(cc_play, 1, midi_chan_inst1); |
||
| 158 | 1:b5bcad8e7803 | f | } |
| 159 | 13:69d60ae38d62 | f | |
| 160 | if (button1.risingEdge()){
|
||
| 161 | usbMIDI.sendControlChange(cc_play, 0, midi_chan_inst1); |
||
| 162 | 1:b5bcad8e7803 | f | } |
| 163 | |||
| 164 | 13:69d60ae38d62 | f | |
| 165 | // Record button instrument 1 |
||
| 166 | if (button2.fallingEdge()){
|
||
| 167 | usbMIDI.sendControlChange(cc_record, 1, midi_chan_inst1); |
||
| 168 | 1:b5bcad8e7803 | f | } |
| 169 | |||
| 170 | 13:69d60ae38d62 | f | // Selection start position instrument 1 |
| 171 | // <calibrate> |
||
| 172 | if (Jet1_new > Jet1_old+jitter_thresh || Jet1_new < Jet1_old-jitter_thresh){
|
||
| 173 | 1:b5bcad8e7803 | f | |
| 174 | 13:69d60ae38d62 | f | int16_t midiVal = constrain( map(Jet1_new, 994, 121, 0, 149), 0, 149 ); |
| 175 | 1:b5bcad8e7803 | f | if( midiVal != Jet1_old_MIDI ){
|
| 176 | Jet1_old_MIDI = midiVal; |
||
| 177 | usbMIDI.sendPitchBend( midiVal, midi_chan_inst1 ); |
||
| 178 | } |
||
| 179 | |||
| 180 | Jet1_old = Jet1_new; |
||
| 181 | digitalWrite(Pin_MIDIled, HIGH); |
||
| 182 | 13:69d60ae38d62 | f | } |
| 183 | 1:b5bcad8e7803 | f | |
| 184 | 13:69d60ae38d62 | f | //Filter instrument 1 |
| 185 | // <calibrate> |
||
| 186 | if ( filter1_new != filter1_old ) {
|
||
| 187 | 1:b5bcad8e7803 | f | |
| 188 | 13:69d60ae38d62 | f | int16_t midiVal = constrain( map(filter1_new, 137, 734, 0, 127), 0, 127 ); |
| 189 | 1:b5bcad8e7803 | f | if( midiVal != filter1_old_MIDI){
|
| 190 | filter1_old_MIDI = midiVal; |
||
| 191 | usbMIDI.sendControlChange(cc_filter, midiVal, midi_chan_inst1); |
||
| 192 | } |
||
| 193 | |||
| 194 | filter1_old = filter1_new; |
||
| 195 | digitalWrite(Pin_MIDIled, HIGH); |
||
| 196 | } |
||
| 197 | 13:69d60ae38d62 | f | |
| 198 | //Selection length instrument 1 |
||
| 199 | long Enc1_new = Enc1.read(); |
||
| 200 | Enc1_new = constrain(Enc1_new, 0, 127); //constrain to 7-bit MIDI range |
||
| 201 | |||
| 202 | if (Enc1_new <= 0){ //Dynamic reset of counter to MIDI range
|
||
| 203 | Enc1.write(0); |
||
| 204 | } |
||
| 205 | else if (Enc1_new >= 127){
|
||
| 206 | Enc1.write(127); |
||
| 207 | } |
||
| 208 | |||
| 209 | 1:b5bcad8e7803 | f | if (Enc1_new != Enc1_old) {
|
| 210 | Enc1_old = Enc1_new; |
||
| 211 | usbMIDI.sendControlChange(cc_length, Enc1_new, midi_chan_inst1); |
||
| 212 | digitalWrite(Pin_MIDIled, HIGH); |
||
| 213 | } |
||
| 214 | 13:69d60ae38d62 | f | |
| 215 | //Grain duration instrument 1 |
||
| 216 | long Enc3_new = Enc3.read(); |
||
| 217 | Enc3_new = constrain(Enc3_new, 0, 127); //constrain to 7-bit MIDI range |
||
| 218 | 1:b5bcad8e7803 | f | |
| 219 | 13:69d60ae38d62 | f | if (Enc3_new <= 0){
|
| 220 | Enc3.write(0); |
||
| 221 | } |
||
| 222 | else if (Enc3_new >= 127){
|
||
| 223 | Enc3.write(127); |
||
| 224 | } |
||
| 225 | |||
| 226 | 1:b5bcad8e7803 | f | if (Enc3_new != Enc3_old) {
|
| 227 | Enc3_old = Enc3_new; |
||
| 228 | usbMIDI.sendControlChange(cc_duration, Enc3_new, midi_chan_inst1); |
||
| 229 | digitalWrite(Pin_MIDIled, HIGH); |
||
| 230 | } |
||
| 231 | 13:69d60ae38d62 | f | |
| 232 | //------ SEND INSTRUMENT 2 MIDI ----------- |
||
| 233 | 1:b5bcad8e7803 | f | |
| 234 | |||
| 235 | 13:69d60ae38d62 | f | //Play button instrument 2 |
| 236 | if (button3.fallingEdge()) {
|
||
| 237 | 1:b5bcad8e7803 | f | usbMIDI.sendControlChange(cc_play, 1, midi_chan_inst2); |
| 238 | } |
||
| 239 | |||
| 240 | 13:69d60ae38d62 | f | if (button3.risingEdge()) {
|
| 241 | 1:b5bcad8e7803 | f | usbMIDI.sendControlChange(cc_play, 0, midi_chan_inst2); |
| 242 | } |
||
| 243 | |||
| 244 | 13:69d60ae38d62 | f | //Record button instrument 2 |
| 245 | 1:b5bcad8e7803 | f | if (button4.fallingEdge()) {
|
| 246 | usbMIDI.sendControlChange(cc_record, 1, midi_chan_inst2); |
||
| 247 | } |
||
| 248 | |||
| 249 | 13:69d60ae38d62 | f | // Selection start position instrument 2 |
| 250 | // <calibrate> |
||
| 251 | 1:b5bcad8e7803 | f | if (Jet2_new > Jet2_old+jitter_thresh || Jet2_new < Jet2_old-jitter_thresh) {
|
| 252 | 13:69d60ae38d62 | f | |
| 253 | int16_t midiVal = constrain( map( Jet2_new, 103, 993, 149, 0 ), 0, 149 ); |
||
| 254 | |||
| 255 | 1:b5bcad8e7803 | f | if( midiVal != Jet2_old_MIDI ){
|
| 256 | Jet2_old_MIDI = midiVal; |
||
| 257 | usbMIDI.sendPitchBend( midiVal, midi_chan_inst2 ); |
||
| 258 | } |
||
| 259 | |||
| 260 | Jet2_old = Jet2_new; |
||
| 261 | digitalWrite(Pin_MIDIled, HIGH); |
||
| 262 | } |
||
| 263 | |||
| 264 | 13:69d60ae38d62 | f | //Filter instrument 2 |
| 265 | // <calibrate> |
||
| 266 | if ( filter2_new != filter2_old ) {
|
||
| 267 | |||
| 268 | int16_t midiVal = constrain( map(filter2_new, 125, 684, 0, 127), 0, 127 ); |
||
| 269 | 1:b5bcad8e7803 | f | if( midiVal != filter2_old_MIDI){
|
| 270 | filter2_old_MIDI = midiVal; |
||
| 271 | usbMIDI.sendControlChange(cc_filter, midiVal, midi_chan_inst2); |
||
| 272 | } |
||
| 273 | |||
| 274 | filter2_old = filter2_new; |
||
| 275 | digitalWrite(Pin_MIDIled, HIGH); |
||
| 276 | 13:69d60ae38d62 | f | } |
| 277 | |||
| 278 | //Selection length instrument 2 |
||
| 279 | long Enc2_new = Enc2.read(); |
||
| 280 | Enc2_new = constrain(Enc2_new, 0, 127); //constrain to 7-bit MIDI range |
||
| 281 | |||
| 282 | if (Enc2_new <= 0){ //Dynamic reset of counter to MIDI range
|
||
| 283 | Enc2.write(0); |
||
| 284 | 1:b5bcad8e7803 | f | } |
| 285 | 13:69d60ae38d62 | f | else if (Enc2_new >= 127){
|
| 286 | Enc2.write(127); |
||
| 287 | } |
||
| 288 | |||
| 289 | 1:b5bcad8e7803 | f | if (Enc2_new != Enc2_old) {
|
| 290 | Enc2_old = Enc2_new; |
||
| 291 | usbMIDI.sendControlChange(cc_length, Enc2_new, midi_chan_inst2); |
||
| 292 | digitalWrite(Pin_MIDIled, HIGH); |
||
| 293 | } |
||
| 294 | 13:69d60ae38d62 | f | |
| 295 | //Grain duration instrument 2 |
||
| 296 | long Enc4_new = Enc4.read(); |
||
| 297 | Enc4_new = constrain(Enc4_new, 0, 127); //constrain to 7-bit MIDI range |
||
| 298 | |||
| 299 | if (Enc4_new <= 0){
|
||
| 300 | Enc4.write(0); |
||
| 301 | } |
||
| 302 | else if (Enc4_new >= 127){
|
||
| 303 | Enc4.write(127); |
||
| 304 | } |
||
| 305 | 1:b5bcad8e7803 | f | |
| 306 | if (Enc4_new != Enc4_old) {
|
||
| 307 | Enc4_old = Enc4_new; |
||
| 308 | usbMIDI.sendControlChange(cc_duration, Enc4_new, midi_chan_inst2); |
||
| 309 | digitalWrite(Pin_MIDIled, HIGH); |
||
| 310 | } |
||
| 311 | |||
| 312 | } |