From 4d6bbcb6fdeb48bcfe2b88c8b99e752d63071f5a Mon Sep 17 00:00:00 2001 From: Alexandre Piel Date: Mon, 15 Jan 2024 22:06:02 +0100 Subject: [PATCH] sequencer --- host/audioPluginHandler.h | 23 ++++++++++++++++++--- plugins/audio/Sequencer.h | 23 +++++++++------------ plugins/audio/audioPlugin.h | 14 ++++++------- plugins/components/GridSequencerComponent.h | 19 +++++++++++++++-- plugins/components/SequencerComponent.h | 4 ++-- 5 files changed, 56 insertions(+), 27 deletions(-) diff --git a/host/audioPluginHandler.h b/host/audioPluginHandler.h index b80d643..958b371 100644 --- a/host/audioPluginHandler.h +++ b/host/audioPluginHandler.h @@ -18,6 +18,7 @@ class AudioPluginHandler : public AudioPluginHandlerInterface { // When reached the maximum, there might be a tempo issue // However, to reach it, it is almost impossible... uint64_t clockCounter = 0; + bool playing = false; struct MidiNoteEvent { uint8_t channel; @@ -198,14 +199,30 @@ class AudioPluginHandler : public AudioPluginHandlerInterface { void clockTick() { - clockCounter++; - for (Plugin& plugin : plugins) { - plugin.instance->onClockTick(clockCounter); + if (playing) { + clockCounter++; + for (Plugin& plugin : plugins) { + plugin.instance->onClockTick(&clockCounter); + } } } void sendEvent(AudioEventType event) { + switch (event) { + case AudioEventType::START: + playing = true; + break; + + case AudioEventType::STOP: + playing = false; + clockCounter = 0; + break; + + case AudioEventType::PAUSE: + playing = false; + break; + } for (Plugin& plugin : plugins) { plugin.instance->onEvent(event); } diff --git a/plugins/audio/Sequencer.h b/plugins/audio/Sequencer.h index fba1d90..48c745b 100644 --- a/plugins/audio/Sequencer.h +++ b/plugins/audio/Sequencer.h @@ -73,7 +73,7 @@ class Sequencer : public Mapping { uint8_t stepCounter = 0; uint8_t loopCounter = 0; - uint64_t * clockCounterPtr = NULL; + uint64_t* clockCounterPtr = NULL; bool active = false; @@ -181,12 +181,12 @@ class Sequencer : public Mapping { setSelectedStep(selectedStep.get()); } - void onClockTick(uint64_t clockCounter) + void onClockTick(uint64_t* clockCounter) { - clockCounterPtr = &clockCounter; + clockCounterPtr = clockCounter; // Clock events are sent at a rate of 24 pulses per quarter note // (24/4 = 6) - if (clockCounter % 6 == 0) { + if (*clockCounter % 6 == 0) { onStep(); } } @@ -196,6 +196,7 @@ class Sequencer : public Mapping { switch (event) { case AudioEventType::STOP: { active = false; + stepCounter = 0; for (int i = 0; i < MAX_STEPS; i++) { if (targetPlugin && steps[i].counter) { targetPlugin->noteOff(steps[i].note, 0); @@ -205,13 +206,12 @@ class Sequencer : public Mapping { break; } case AudioEventType::START: - stepCounter = 0; loopCounter = 0; active = true; break; case AudioEventType::PAUSE: - active = !active; + active = false; break; } } @@ -320,17 +320,14 @@ class Sequencer : public Mapping { uint8_t* index = (uint8_t*)userdata; return (void*)stepConditions[*index].name; } - case 3: // Save pattern + case 3: + return clockCounterPtr; + case 4: // Save pattern save(folder / *(std::string*)userdata); return NULL; - case 4: // Rename pattern + case 5: // Rename pattern rename(folder / *(std::string*)userdata); return NULL; - // case 5: // Toggle play/pause - // active = !active; - // return NULL; - case 5: - return clockCounterPtr; } return NULL; } diff --git a/plugins/audio/audioPlugin.h b/plugins/audio/audioPlugin.h index b307f17..1dd22c6 100644 --- a/plugins/audio/audioPlugin.h +++ b/plugins/audio/audioPlugin.h @@ -10,12 +10,12 @@ class AudioPlugin; - enum AudioEventType { - STOP, - START, - PAUSE, - AUTOSAVE - }; +enum AudioEventType { + STOP, + START, + PAUSE, + AUTOSAVE +}; class AudioPluginHandlerInterface { public: @@ -112,7 +112,7 @@ class AudioPlugin { return NULL; } - virtual void onClockTick(uint64_t clockCounter) + virtual void onClockTick(uint64_t* clockCounter) { } diff --git a/plugins/components/GridSequencerComponent.h b/plugins/components/GridSequencerComponent.h index c98230d..59594cd 100644 --- a/plugins/components/GridSequencerComponent.h +++ b/plugins/components/GridSequencerComponent.h @@ -12,7 +12,7 @@ class Track { int16_t trackId = -1; AudioPlugin* seqPlugin; std::string name = "Init"; - float volume = 1.0f; //rand() % 100 / 100.0f; + float volume = 1.0f; // rand() % 100 / 100.0f; bool active = false; Step* steps; ValueInterface* selectedStep; @@ -66,7 +66,8 @@ class GridSequencerComponent : public Component { Step selectedStepCopy; - uint8_t stepCounter = 0; + uint64_t lastClockCounter = -1; + uint8_t lastStepCounter = -1; void progressInit() { @@ -384,6 +385,20 @@ class GridSequencerComponent : public Component { renderNext(); selectedStepCopy = tracks[grid.row].steps[grid.col - 1]; } + + if (tracks[0].seqPlugin) { + uint64_t* clockCounterPtr = (uint64_t*)tracks[0].seqPlugin->data(3); + if (clockCounterPtr && lastClockCounter != *clockCounterPtr) { + lastClockCounter = *clockCounterPtr; + uint8_t stepCounter = lastClockCounter / 6 % stepsCount; + if (stepCounter != lastStepCounter) { + lastStepCounter = stepCounter; + // printf("stepCounter: %d (%ld)\n", stepCounter, lastClockCounter); + renderProgress(stepCounter); + draw.renderNext(); + } + } + } }; } diff --git a/plugins/components/SequencerComponent.h b/plugins/components/SequencerComponent.h index 0a1ee5e..f03eefe 100644 --- a/plugins/components/SequencerComponent.h +++ b/plugins/components/SequencerComponent.h @@ -358,11 +358,11 @@ class SequencerComponent : public Component { int column = (motion.position.x - position.x) / stepSize.w; if (fileMode) { if (row == rowCount && column == columnCount - 2) { - plugin.data(4, (void*)&input.value); + plugin.data(5, (void*)&input.value); fileMode = false; renderNext(); } else if (row == rowCount && column == columnCount - 1) { - plugin.data(3, (void*)&input.value); + plugin.data(4, (void*)&input.value); fileMode = false; renderNext(); } else {