Skip to content

Commit

Permalink
Fix crashes in ARP. #229
Browse files Browse the repository at this point in the history
  • Loading branch information
mdemanett committed Sep 11, 2023
1 parent d2b8308 commit ed283ee
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 12 deletions.
46 changes: 35 additions & 11 deletions src/Arp.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

#include "Arp.hpp"
#include <unordered_set>

#define NOTES_IMMEDIATE_MODE "notes_immediate"
#define FIXED_GATE_MODE "fixed_gate"
Expand Down Expand Up @@ -134,28 +135,38 @@ void Arp::NoteSet::resetSequence() {
}

void Arp::NoteSet::addNote(int c, float pitch) {
Note n;
n.pitch = pitch;
n.channel = c;
int i = 0;
while (n.pitch >= _notesByPitch[i].pitch && i < _noteCount) {
if (n.pitch == _notesByPitch[i].pitch) {
for (int i = 0; i < _noteCount; ++i) {
if (_notesByPitch[i].pitch == pitch) {
return;
}
++i;
}
assert(i <= _noteCount);

dropNote(c);
_noteOn[c] = true;
_notesDirty = true;

shuffleUp(_notesByPitch, i);
Note n;
n.pitch = pitch;
n.channel = c;
int i = 0;
while (n.pitch >= _notesByPitch[i].pitch && i < _noteCount) {
++i;
}
assert(i <= maxChannels);

if (i >= maxChannels) {
i = maxChannels - 1;
}
else {
shuffleUp(_notesByPitch, i);
}
_notesByPitch[i] = n;

_notesAsPlayed[_noteCount] = n;
++_noteCount;
assert(_noteCount <= maxChannels);
assert(uniqueChannelsCount(_notesAsPlayed) == _noteCount);
assert(uniqueChannelsCount(_notesByPitch) == _noteCount);
}

void Arp::NoteSet::dropNote(int c) {
Expand All @@ -165,24 +176,27 @@ void Arp::NoteSet::dropNote(int c) {
_noteOn[c] = false;
_notesDirty = true;

assert(_noteCount > 0);
int i = 0;
while (_notesAsPlayed[i].channel != c && i < _noteCount) {
++i;
}
assert(i < _noteCount);
shuffleDown(_notesAsPlayed, i);
_notesAsPlayed[_noteCount].reset();
_notesAsPlayed[_noteCount - 1].reset();

i = 0;
while (_notesByPitch[i].channel != c && i < _noteCount) {
++i;
}
assert(i < _noteCount);
shuffleDown(_notesByPitch, i);
_notesByPitch[_noteCount].reset();
_notesByPitch[_noteCount - 1].reset();

--_noteCount;
assert(_noteCount >= 0);
assert(uniqueChannelsCount(_notesAsPlayed) == _noteCount);
assert(uniqueChannelsCount(_notesByPitch) == _noteCount);
}

void Arp::NoteSet::shuffleUp(Note* notes, int index) {
Expand Down Expand Up @@ -210,6 +224,16 @@ void Arp::NoteSet::sync() {
_syncTo->_notesDirty = false;
}

int Arp::NoteSet::uniqueChannelsCount(Note* notes) {
std::unordered_set<int> channels;
for (int i = 0; i < maxChannels; ++i) {
if (notes[i].channel >= 0) {
channels.insert(notes[i].channel);
}
}
return channels.size();
}

void Arp::reset() {
_clockTrigger.reset();
_resetTrigger.reset();
Expand Down
2 changes: 1 addition & 1 deletion src/Arp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ struct Arp : BGModule {
void reset();
};


bool _noteOn[maxChannels] {};
int _noteCount = 0;
Note _notesAsPlayed[maxChannels];
Expand All @@ -84,6 +83,7 @@ struct Arp : BGModule {
void shuffleUp(Note* notes, int index);
void shuffleDown(Note* notes, int index);
void sync();
int uniqueChannelsCount(Note* notes);
};

struct GateLengthParamQuantity : ParamQuantity {
Expand Down

0 comments on commit ed283ee

Please sign in to comment.