Polyrhythm tracks
This commit is contained in:
+22
-12
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user