From 385d5cf301e4d0fb6173e7c33262fb915a13b024 Mon Sep 17 00:00:00 2001 From: midilab Date: Mon, 22 Jan 2024 07:47:20 -0300 Subject: [PATCH] version 2.0 breakchanges --- README.md | 39 ++++++++++++++----- .../AVRUartSlaveMidiClockMonitor.ino | 12 +++--- .../AcidStepSequencer/AcidStepSequencer.ino | 32 ++++++++------- .../ESP32UartMasterMidiClock.ino | 8 ++-- .../LeonardoUsbSlaveMidiClockMonitor.ino | 8 ++-- examples/MidiClock/MidiClock.ino | 10 ++--- .../STM32UartMasterMidiClock.ino | 8 ++-- .../TeensyUsbMasterMidiClock.ino | 8 ++-- .../TeensyUsbSlaveMidiClock.ino | 8 ++-- .../TeensyUsbSlaveMidiClockMonitor.ino | 8 ++-- .../XiaoUsbMasterMidiClock.ino | 8 ++-- 11 files changed, 87 insertions(+), 62 deletions(-) diff --git a/README.md b/README.md index ddfdca3..a04c7cb 100755 --- a/README.md +++ b/README.md @@ -18,6 +18,27 @@ The uClock library API operates through attached callback functions mechanism: 5. **onClockStartCallback()** on uClock Start event 6. **onClockStopCallback()** on uClock Stop event +## uClock v2.0 Breakchanges + +If you are comming from uClock version < 2.0 versions keep attention to the breakchanges so you can update your code to the new API interface changes: + +#### setCallback functions name changing: +**setClock96PPQNOutput(onClock96PPQNOutputCallback)** is now setOnPPQN(onPPQNCallback) and his clock depends on the PPQN setup using setPPQN (clockPPQNResolution). For clock setup you now use a separeted callback via setOnSync24(onSync48Callback) or setOnSync24(onSync48Callback) +**setOnClockStartOutput(onClockStartCallback)** is now setOnClockStart(onClockStartCallback) +**setOnClockStopOutput(onClockStopCallback)** is now setOnClockStop(onClockStopCallback) +**setOnClockStartOutput(onClockStartCallback)** is now setOnClockStart(onClockStartCallback) +**setClock16PPQNOutput(ClockOut16PPQN)** is now setOnStep(onStepCall) and its not dependent on clock PPQN resolution + +#### Tick resolution and sequencers + +If you have write a sequencer using setClock16PPQNOutput only its ok to just change the API call to setOnStep, but if you were dependent on setClock96PPQNOutput you migth need to review you tick counting system depending on wich PPQN clock resolution you choose. + + +## Examples + +You will find more complete examples on examples/ folder: + + ```c++ #include @@ -71,7 +92,7 @@ Here is an example on how to create a simple MIDI Sync Box on Arduino boards #define MIDI_START 0xFA #define MIDI_STOP 0xFC -// The callback function wich will be called by Clock each Pulse of 96PPQN clock resolution. +// The callback function wich will be called by Clock each Pulse of 24PPQN clock resolution. void onSync24Callback(uint32_t tick) { // Send MIDI_CLOCK to external gears Serial.write(MIDI_CLOCK); @@ -168,7 +189,7 @@ A clone of Roland TB303 step sequencer main engine, here is an example with no u // Sequencer config #define STEP_MAX_SIZE 16 -#define NOTE_LENGTH 4 // min: 1 max: 5 DO NOT EDIT BEYOND!!! +#define NOTE_LENGTH 12 // min: 1 max: 23 DO NOT EDIT BEYOND!!! 12 = 50% on 96ppqn, same as original tb303. 62.5% for triplets time signature #define NOTE_VELOCITY 90 #define ACCENT_VELOCITY 127 @@ -223,7 +244,7 @@ void sendMidiMessage(uint8_t command, uint8_t byte1, uint8_t byte2) } // The callback function wich will be called by uClock each Pulse of 16PPQN clock resolution. Each call represents exactly one step. -void ClockOut16PPQN(uint32_t tick) +void onStepCallback(uint32_t tick) { uint16_t step; uint16_t length = NOTE_LENGTH; @@ -240,7 +261,7 @@ void ClockOut16PPQN(uint32_t tick) ++step; step = step % _step_length; if ( _sequencer[step].glide == true && _sequencer[step].rest == false ) { - length = NOTE_LENGTH + (i * 6); + length = NOTE_LENGTH + (i * 24); break; } else if ( _sequencer[step].rest == false ) { break; @@ -261,7 +282,7 @@ void ClockOut16PPQN(uint32_t tick) } // The callback function wich will be called by uClock each Pulse of 96PPQN clock resolution. -void ClockOut96PPQN(uint32_t tick) +void onPPQNCallback(uint32_t tick) { // Send MIDI_CLOCK to external hardware Serial.write(MIDI_CLOCK); @@ -307,14 +328,14 @@ void setup() uClock.init(); // Set the callback function for the clock output to send MIDI Sync message. - uClock.setClock96PPQNOutput(ClockOut96PPQN); + uClock.setOnPPQN(onPPQNCallback); // Set the callback function for the step sequencer on 16ppqn - uClock.setClock16PPQNOutput(ClockOut16PPQN); + uClock.setOnStep(onStepCallback); // Set the callback function for MIDI Start and Stop messages. - uClock.setOnClockStartOutput(onClockStart); - uClock.setOnClockStopOutput(onClockStop); + uClock.setOnClockStart(onClockStart); + uClock.setOnClockStop(onClockStop); // Set the clock BPM to 126 BPM uClock.setTempo(126); diff --git a/examples/AVRUartSlaveMidiClockMonitor/AVRUartSlaveMidiClockMonitor.ino b/examples/AVRUartSlaveMidiClockMonitor/AVRUartSlaveMidiClockMonitor.ino index 1b255f0..10bf4f2 100644 --- a/examples/AVRUartSlaveMidiClockMonitor/AVRUartSlaveMidiClockMonitor.ino +++ b/examples/AVRUartSlaveMidiClockMonitor/AVRUartSlaveMidiClockMonitor.ino @@ -51,7 +51,7 @@ void handle_bpm_led(uint32_t tick) { } // Internal clock handlers -void ClockOut96PPQN(uint32_t tick) { +void onSync24Callback(uint32_t tick) { // Send MIDI_CLOCK to external gears MIDI.sendRealTime(MIDI_CLOCK); handle_bpm_led(tick); @@ -87,7 +87,7 @@ void setup() { // Initiate MIDI communications, listen to all channels, disable soft MIDI thru MIDI.begin(); MIDI.turnThruOff(); -MIDI.setHandleClock(onExternalClock); + MIDI.setHandleClock(onExternalClock); MIDI.setHandleStart(onExternalStart); MIDI.setHandleStop(onExternalStop); @@ -98,7 +98,7 @@ MIDI.setHandleClock(onExternalClock); // // OLED setup // Please check you oled model to correctly init him -// The complete list is available here: https://github.com/olikraus/u8g2/wiki/u8g2setupcpp + // The complete list is available here: https://github.com/olikraus/u8g2/wiki/u8g2setupcpp // //u8x8 = new U8X8_SH1106_128X64_NONAME_HW_I2C(U8X8_PIN_NONE); u8x8 = new U8X8_SSD1306_128X64_NONAME_HW_I2C(U8X8_PIN_NONE); @@ -112,10 +112,10 @@ MIDI.setHandleClock(onExternalClock); // uClock Setup // uClock.init(); - uClock.setClock96PPQNOutput(ClockOut96PPQN); + uClock.setOnSync24(onSync24Callback); // For MIDI Sync Start and Stop - uClock.setOnClockStartOutput(onClockStart); - uClock.setOnClockStopOutput(onClockStop); + uClock.setOnClockStart(onClockStart); + uClock.setOnClockStop(onClockStop); uClock.setMode(uClock.EXTERNAL_CLOCK); //uClock.setTempo(136.5); //uClock.start(); diff --git a/examples/AcidStepSequencer/AcidStepSequencer.ino b/examples/AcidStepSequencer/AcidStepSequencer.ino index bed0953..5531fa9 100644 --- a/examples/AcidStepSequencer/AcidStepSequencer.ino +++ b/examples/AcidStepSequencer/AcidStepSequencer.ino @@ -6,7 +6,7 @@ // Sequencer config #define STEP_MAX_SIZE 16 -#define NOTE_LENGTH 4 // min: 1 max: 5 DO NOT EDIT BEYOND!!! +#define NOTE_LENGTH 12 // min: 1 max: 23 DO NOT EDIT BEYOND!!! 12 = 50% on 96ppqn, same as original tb303. 62.5% for triplets time signature #define NOTE_VELOCITY 90 #define ACCENT_VELOCITY 127 @@ -47,8 +47,7 @@ uint16_t _step_length = STEP_MAX_SIZE; // make sure all above sequencer data are modified atomicly only // eg. ATOMIC(_sequencer[0].accent = true); ATOMIC(_step_length = 7); -uint8_t _tmpSREG; -#define ATOMIC(X) _tmpSREG = SREG; cli(); X; SREG = _tmpSREG; +#define ATOMIC(X) noInterrupts(); X; interrupts(); // shared data to be used for user interface feedback bool _playing = false; @@ -63,8 +62,8 @@ void sendMidiMessage(uint8_t command, uint8_t byte1, uint8_t byte2) Serial.write(byte2); } -// The callback function wich will be called by uClock each Pulse of 16PPQN clock resolution. Each call represents exactly one step. -void ClockOut16PPQN(uint32_t tick) +// Each call represents exactly one step. +void onStepCallback(uint32_t tick) { uint16_t step; uint16_t length = NOTE_LENGTH; @@ -102,11 +101,8 @@ void ClockOut16PPQN(uint32_t tick) } // The callback function wich will be called by uClock each Pulse of 96PPQN clock resolution. -void ClockOut96PPQN(uint32_t tick) +void onPPQNCallback(uint32_t tick) { - // Send MIDI_CLOCK to external hardware - Serial.write(MIDI_CLOCK); - // handle note on stack for ( uint8_t i = 0; i < NOTE_STACK_SIZE; i++ ) { if ( _note_stack[i].length != -1 ) { @@ -122,6 +118,11 @@ void ClockOut96PPQN(uint32_t tick) tempoInterface(tick); } +void onSync24Callback(uint32_t tick) { + // Send MIDI_CLOCK to external gears + Serial.write(MIDI_CLOCK); +} + // The callback function wich will be called when clock starts by using Clock.start() method. void onClockStart() { @@ -157,14 +158,17 @@ void setup() uClock.init(); // Set the callback function for the clock output to send MIDI Sync message. - uClock.setClock96PPQNOutput(ClockOut96PPQN); - + uClock.setOnPPQN(onPPQNCallback); + + // for MIDI sync + uClock.setOnSync24(onSync24Callback); + // Set the callback function for the step sequencer on 16ppqn - uClock.setClock16PPQNOutput(ClockOut16PPQN); + uClock.setOnStep(onStepCallback); // Set the callback function for MIDI Start and Stop messages. - uClock.setOnClockStartOutput(onClockStart); - uClock.setOnClockStopOutput(onClockStop); + uClock.setOnClockStart(onClockStart); + uClock.setOnClockStop(onClockStop); // Set the clock BPM to 126 BPM uClock.setTempo(126); diff --git a/examples/ESP32UartMasterMidiClock/ESP32UartMasterMidiClock.ino b/examples/ESP32UartMasterMidiClock/ESP32UartMasterMidiClock.ino index 03831ee..25da851 100644 --- a/examples/ESP32UartMasterMidiClock/ESP32UartMasterMidiClock.ino +++ b/examples/ESP32UartMasterMidiClock/ESP32UartMasterMidiClock.ino @@ -34,7 +34,7 @@ void handle_bpm_led(uint32_t tick) } // Internal clock handlers -void ClockOut96PPQN(uint32_t tick) { +void onSync24Callback(uint32_t tick) { // Send MIDI_CLOCK to external gears Serial.write(MIDI_CLOCK); handle_bpm_led(tick); @@ -59,10 +59,10 @@ void setup() { // Inits the clock uClock.init(); // Set the callback function for the clock output to send MIDI Sync message. - uClock.setClock96PPQNOutput(ClockOut96PPQN); + uClock.setOnSync24(onSync24Callback); // Set the callback function for MIDI Start and Stop messages. - uClock.setOnClockStartOutput(onClockStart); - uClock.setOnClockStopOutput(onClockStop); + uClock.setOnClockStart(onClockStart); + uClock.setOnClockStop(onClockStop); // Set the clock BPM to 126 BPM uClock.setTempo(126); // Starts the clock, tick-tac-tick-tac... diff --git a/examples/LeonardoUsbSlaveMidiClockMonitor/LeonardoUsbSlaveMidiClockMonitor.ino b/examples/LeonardoUsbSlaveMidiClockMonitor/LeonardoUsbSlaveMidiClockMonitor.ino index 491d861..76b5f63 100644 --- a/examples/LeonardoUsbSlaveMidiClockMonitor/LeonardoUsbSlaveMidiClockMonitor.ino +++ b/examples/LeonardoUsbSlaveMidiClockMonitor/LeonardoUsbSlaveMidiClockMonitor.ino @@ -48,7 +48,7 @@ void handle_bpm_led(uint32_t tick) } // Internal clock handlers -void ClockOut96PPQN(uint32_t tick) { +void onSync24Callback(uint32_t tick) { // Send MIDI_CLOCK to external gears MIDI.sendRealTime(MIDI_CLOCK); handle_bpm_led(tick); @@ -103,10 +103,10 @@ void setup() { // uClock Setup // uClock.init(); - uClock.setClock96PPQNOutput(ClockOut96PPQN); + uClock.setOnSync24(onSync24Callback); // For MIDI Sync Start and Stop - uClock.setOnClockStartOutput(onClockStart); - uClock.setOnClockStopOutput(onClockStop); + uClock.setOnClockStart(onClockStart); + uClock.setOnClockStop(onClockStop); uClock.setMode(uClock.EXTERNAL_CLOCK); //uClock.setTempo(136.5); //uClock.start(); diff --git a/examples/MidiClock/MidiClock.ino b/examples/MidiClock/MidiClock.ino index 6ca4bb5..169e504 100755 --- a/examples/MidiClock/MidiClock.ino +++ b/examples/MidiClock/MidiClock.ino @@ -6,8 +6,8 @@ #define MIDI_START 0xFA #define MIDI_STOP 0xFC -// The callback function wich will be called by Clock each Pulse of 96PPQN clock resolution. -void ClockOut96PPQN(uint32_t tick) +// The callback function wich will be called by Clock each Pulse of 24PPQN clock resolution. +void onSync24Callback(uint32_t tick) { // Send MIDI_CLOCK to external gears Serial.write(MIDI_CLOCK); @@ -34,10 +34,10 @@ void setup() // Inits the clock uClock.init(); // Set the callback function for the clock output to send MIDI Sync message. - uClock.setClock96PPQNOutput(ClockOut96PPQN); + uClock.setOnSync24(onSync24Callback); // Set the callback function for MIDI Start and Stop messages. - uClock.setOnClockStartOutput(onClockStart); - uClock.setOnClockStopOutput(onClockStop); + uClock.setOnClockStart(onClockStart); + uClock.setOnClockStop(onClockStop); // Set the clock BPM to 126 BPM uClock.setTempo(126); diff --git a/examples/STM32UartMasterMidiClock/STM32UartMasterMidiClock.ino b/examples/STM32UartMasterMidiClock/STM32UartMasterMidiClock.ino index 969e403..e3421c6 100644 --- a/examples/STM32UartMasterMidiClock/STM32UartMasterMidiClock.ino +++ b/examples/STM32UartMasterMidiClock/STM32UartMasterMidiClock.ino @@ -40,7 +40,7 @@ void handle_bpm_led(uint32_t tick) } // Internal clock handlers -void ClockOut96PPQN(uint32_t tick) { +void onSync24Callback(uint32_t tick) { // Send MIDI_CLOCK to external gear Serial1.write(MIDI_CLOCK); handle_bpm_led(tick); @@ -67,10 +67,10 @@ void setup() { // Inits the clock uClock.init(); // Set the callback function for the clock output to send MIDI Sync message. - uClock.setClock96PPQNOutput(ClockOut96PPQN); + uClock.setOnSync24(onSync24Callback); // Set the callback function for MIDI Start and Stop messages. - uClock.setOnClockStartOutput(onClockStart); - uClock.setOnClockStopOutput(onClockStop); + uClock.setOnClockStart(onClockStart); + uClock.setOnClockStop(onClockStop); // Set the clock BPM to 126 BPM uClock.setTempo(120); // Starts the clock, tick-tac-tick-tac... diff --git a/examples/TeensyUsbMasterMidiClock/TeensyUsbMasterMidiClock.ino b/examples/TeensyUsbMasterMidiClock/TeensyUsbMasterMidiClock.ino index ad10e3c..2c814b4 100644 --- a/examples/TeensyUsbMasterMidiClock/TeensyUsbMasterMidiClock.ino +++ b/examples/TeensyUsbMasterMidiClock/TeensyUsbMasterMidiClock.ino @@ -36,7 +36,7 @@ void handle_bpm_led(uint32_t tick) } // Internal clock handlers -void ClockOut96PPQN(uint32_t tick) { +void onSync24Callback(uint32_t tick) { // Send MIDI_CLOCK to external gears usbMIDI.sendRealTime(usbMIDI.Clock); handle_bpm_led(tick); @@ -58,10 +58,10 @@ void setup() { // Inits the clock uClock.init(); // Set the callback function for the clock output to send MIDI Sync message. - uClock.setClock96PPQNOutput(ClockOut96PPQN); + uClock.setOnSync24(onSync24Callback); // Set the callback function for MIDI Start and Stop messages. - uClock.setOnClockStartOutput(onClockStart); - uClock.setOnClockStopOutput(onClockStop); + uClock.setOnClockStart(onClockStart); + uClock.setOnClockStop(onClockStop); // Set the clock BPM to 126 BPM uClock.setTempo(126); // Starts the clock, tick-tac-tick-tac... diff --git a/examples/TeensyUsbSlaveMidiClock/TeensyUsbSlaveMidiClock.ino b/examples/TeensyUsbSlaveMidiClock/TeensyUsbSlaveMidiClock.ino index 5a017b3..98c1ee3 100644 --- a/examples/TeensyUsbSlaveMidiClock/TeensyUsbSlaveMidiClock.ino +++ b/examples/TeensyUsbSlaveMidiClock/TeensyUsbSlaveMidiClock.ino @@ -36,7 +36,7 @@ void handle_bpm_led(uint32_t tick) } // Internal clock handlers -void ClockOut96PPQN(uint32_t tick) { +void onSync24Callback(uint32_t tick) { // Send MIDI_CLOCK to external gears on other port? //usbMIDI.sendRealTime(usbMIDI.Clock); handle_bpm_led(tick); @@ -79,10 +79,10 @@ void setup() { // Inits the clock uClock.init(); // Set the callback function for the clock output to send MIDI Sync message. - uClock.setClock96PPQNOutput(ClockOut96PPQN); + uClock.setOnSync24(onSync24Callback); // Set the callback function for MIDI Start and Stop messages. - uClock.setOnClockStartOutput(onClockStart); - uClock.setOnClockStopOutput(onClockStop); + uClock.setOnClockStart(onClockStart); + uClock.setOnClockStop(onClockStop); // set to external sync mode uClock.setMode(1); } diff --git a/examples/TeensyUsbSlaveMidiClockMonitor/TeensyUsbSlaveMidiClockMonitor.ino b/examples/TeensyUsbSlaveMidiClockMonitor/TeensyUsbSlaveMidiClockMonitor.ino index 1c05c0e..57b2989 100644 --- a/examples/TeensyUsbSlaveMidiClockMonitor/TeensyUsbSlaveMidiClockMonitor.ino +++ b/examples/TeensyUsbSlaveMidiClockMonitor/TeensyUsbSlaveMidiClockMonitor.ino @@ -50,7 +50,7 @@ void handle_bpm_led(uint32_t tick) } // Internal clock handlers -void ClockOut96PPQN(uint32_t tick) { +void onSync24Callback(uint32_t tick) { // Send MIDI_CLOCK to external gears usbMIDI.sendRealTime(MIDI_CLOCK); handle_bpm_led(tick); @@ -110,10 +110,10 @@ void setup() { // // Setup our clock system uClock.init(); - uClock.setClock96PPQNOutput(ClockOut96PPQN); + uClock.setOnSync24(onSync24Callback); // For MIDI Sync Start and Stop - uClock.setOnClockStartOutput(onClockStart); - uClock.setOnClockStopOutput(onClockStop); + uClock.setOnClockStart(onClockStart); + uClock.setOnClockStop(onClockStop); uClock.setMode(uClock.EXTERNAL_CLOCK); // make use of 250us timer to handle midi input sync teensyTimer.begin(handleMidiInput, 250); diff --git a/examples/XiaoUsbMasterMidiClock/XiaoUsbMasterMidiClock.ino b/examples/XiaoUsbMasterMidiClock/XiaoUsbMasterMidiClock.ino index 2bcd0f4..c052f79 100644 --- a/examples/XiaoUsbMasterMidiClock/XiaoUsbMasterMidiClock.ino +++ b/examples/XiaoUsbMasterMidiClock/XiaoUsbMasterMidiClock.ino @@ -33,7 +33,7 @@ void handle_bpm_led(uint32_t tick) } // Internal clock handlers -void ClockOut96PPQN(uint32_t tick) { +void onSync24Callback(uint32_t tick) { // Send MIDI_CLOCK to external gears MIDI_USB.sendRealTime(midi::Clock); handle_bpm_led(tick); @@ -57,10 +57,10 @@ void setup() { // Inits the clock uClock.init(); // Set the callback function for the clock output to send MIDI Sync message. - uClock.setClock96PPQNOutput(ClockOut96PPQN); + uClock.setOnSync24(onSync24Callback); // Set the callback function for MIDI Start and Stop messages. - uClock.setOnClockStartOutput(onClockStart); - uClock.setOnClockStopOutput(onClockStop); + uClock.setOnClockStart(onClockStart); + uClock.setOnClockStop(onClockStop); // Set the clock BPM to 126 BPM uClock.setTempo(126); // Starts the clock, tick-tac-tick-tac...