PlectralEFFECTS - Final Notes
I have had a busy couple of weeks, and unfortunately the project has been on hold. I have been busy with getting our family home ready to go on the market.
I did however complete the implementation of continuous controllers, and obtained my main goal of the project to control the effect / envelopes from the plectrum. Please see the following video for the demonstration purpose :
The main challenge for me in implementation of the enveloped effects was gaining an understanding of MIDI Clock. The effect mode is varied between two states, depending on which side of the plectrum is used. Effects are tempo synced to the DAW and are in time with beats. MIDI Clock generates a byte 0xF8 at exactly 24 pulses per quarter note. The envelope effects are sinusoidal calculated at 1/24th of a 1/2 wave, or 0.130899 radians to keep in time with the MIDI Clock.
The code is attached below, and I hope that is of some use. I will continue on with the project and see if there is more I can implement with it, but right now I am happy to play with it.
I would have liked to have seen what I could do with the BeagleBone Black. Unfortunately, the main components including the BBB of the challenger kit never arrived.
Arduino Code :
// Include the Bounce2 library found here : // https://github.com/thomasfredericks/Bounce2 #include <Bounce2.h> #define BUTTON_PIN_1 0 #define BUTTON_PIN_2 1 #define LED_PIN 13 #define LED_PIN2 10 #define LED_PIN3 9 // Instantiate a Bounce object Bounce debouncer1 = Bounce(); Bounce debouncer2 = Bounce(); // Current clock byte midiClock; // Current effect mode byte effectMode; float rads; void noteOn(byte channel, byte pitch, byte velocity) { MIDIEvent noteOn = {0x09, 0x90 | channel, pitch, velocity}; MIDIUSB.write(noteOn); } void noteOff(byte channel, byte pitch, byte velocity) { MIDIEvent noteOff = {0x08, 0x80 | channel, pitch, velocity}; MIDIUSB.write(noteOff); } void controlChange(byte channel, byte control, byte value) { MIDIEvent event = {0x0B, 0xB0 | channel, control, value}; MIDIUSB.write(event); } bool value1state=false; bool value2state=false; void loop() { debouncer1.update(); debouncer2.update(); int value1 = debouncer1.read(); int value2 = debouncer2.read(); // Turn on the LED if either button is pressed : if ( value1 == LOW ) { digitalWrite(LED_PIN, HIGH ); if (!value1state) { effectMode=1; rads=0; value1state=true; } } else { digitalWrite(LED_PIN, LOW ); if (value1state) { value1state=false; } } if ( value2 == LOW ) { digitalWrite(LED_PIN, HIGH ); if (!value2state) { effectMode=2; rads=0.13089969*6; // phase offset value2state=true; } } else { digitalWrite(LED_PIN, LOW ); if (value2state) { value2state=false; } } while(MIDIUSB.available() > 0) { MIDIEvent e; e = MIDIUSB.read(); if (e.m1 == 0xFA) { midiClock = 0; rads = 0.0; } if (e.m1 == 0xFC) { midiClock = 0; rads = 0.0; } if (e.m1 == 0xF8) { if (midiClock == 0) { digitalWrite(LED_PIN, HIGH ); } midiClock++; if (midiClock >= 24) midiClock = 0; if (effectMode == 1) rads = rads + (0.13089969*4); else rads = rads + (0.13089969); if (rads >= PI*2) rads = 0; controlChange(0, 74, round((sin(rads)*63)+64)); MIDIUSB.flush(); } } digitalWrite(LED_PIN, LOW ); } void setup() { // Setup the first button with an internal pull-up : pinMode(BUTTON_PIN_1,INPUT_PULLUP); debouncer1.attach(BUTTON_PIN_1); debouncer1.interval(5); // interval in ms // Setup the second button with an internal pull-up : pinMode(BUTTON_PIN_2,INPUT_PULLUP); debouncer2.attach(BUTTON_PIN_2); debouncer2.interval(5); // interval in ms //Setup the LEDs : pinMode(LED_PIN,OUTPUT); pinMode(LED_PIN2,OUTPUT); pinMode(LED_PIN3,OUTPUT); }