Polyrhythm tracks

This commit is contained in:
Dejvino
2026-03-04 23:20:27 +01:00
parent 288a363618
commit e9f9682663
7 changed files with 78 additions and 53 deletions
+22 -12
View File
@@ -4,6 +4,7 @@
#include "config.h"
#include "SharedState.h"
static int local_numSteps[NUM_TRACKS];
static Step local_sequence[NUM_TRACKS][NUM_STEPS];
static Step local_nextSequence[NUM_TRACKS][NUM_STEPS];
@@ -42,16 +43,24 @@ static void handlePlayback() {
midi.lock();
memcpy(local_sequence, sequence, sizeof(local_sequence));
memcpy(local_nextSequence, nextSequence, sizeof(local_nextSequence));
for (int i = 0; i < NUM_TRACKS; i++) local_numSteps[i] = numSteps[i];
midi.unlock();
int master_len = 0;
for(int i=0; i<NUM_TRACKS; i++) {
if(local_numSteps[i] > master_len) master_len = local_numSteps[i];
}
if (master_len == 0) master_len = NUM_STEPS;
for(int t=0; t<NUM_TRACKS; t++) {
int trackChannel = midiChannels[t];
int nextStep = playbackStep + 1;
if (nextStep >= numSteps) nextStep = 0;
int track_len = local_numSteps[t];
int current_step = playbackStep % track_len;
int next_step = (playbackStep + 1) % track_len;
// Determine if we are tying to the next note
bool isTied = local_sequence[t][playbackStep].tie && (local_sequence[t][nextStep].note != -1);
int prevNote = local_sequence[t][playbackStep].note;
bool isTied = local_sequence[t][current_step].tie && (local_sequence[t][next_step].note != -1);
int prevNote = local_sequence[t][current_step].note;
// Note Off for previous step (if NOT tied)
if (!isTied && prevNote != -1) {
@@ -61,9 +70,8 @@ static void handlePlayback() {
playbackStep++;
bool justPanicked = false;
if (playbackStep >= numSteps) {
playbackStep = 0;
// When the global step counter completes a full cycle of the longest track
if ((playbackStep > 0) && ((playbackStep % master_len) == 0)) {
for (int i=0; i<NUM_TRACKS; i++) midi.panic(midiChannels[i]);
justPanicked = true;
@@ -114,16 +122,18 @@ static void handlePlayback() {
// Note On for new step
for(int t=0; t<NUM_TRACKS; t++) {
int trackChannel = midiChannels[t];
int prevStep = (playbackStep == 0) ? numSteps - 1 : playbackStep - 1;
bool wasTied = local_sequence[t][prevStep].tie && (local_sequence[t][playbackStep].note != -1);
int prevNote = local_sequence[t][prevStep].note;
int currentNote = local_sequence[t][playbackStep].note;
int track_len = local_numSteps[t];
int current_step = playbackStep % track_len;
int prev_step = (playbackStep == 0) ? track_len - 1 : (playbackStep - 1) % track_len;
bool wasTied = local_sequence[t][prev_step].tie && (local_sequence[t][current_step].note != -1);
int prevNote = local_sequence[t][prev_step].note;
int currentNote = local_sequence[t][current_step].note;
// If tied to the SAME note, do not retrigger (sustain)
bool isContinuing = wasTied && (prevNote == currentNote) && !justPanicked;
if (!trackMute[t] && currentNote != -1 && !isContinuing) {
uint8_t velocity = local_sequence[t][playbackStep].accent ? 127 : 100;
uint8_t velocity = local_sequence[t][current_step].accent ? 127 : 100;
midi.sendNoteOn(currentNote, velocity, trackChannel);
}