Skip to content

Commit

Permalink
Add 'removeByHostNoteID' method to SurgeSynthesizer
Browse files Browse the repository at this point in the history
Mostly to make Phil's live easier with OSC. But it seems
like a handy option.

Closes surge-synthesizer#7184
  • Loading branch information
baconpaul committed Aug 18, 2023
1 parent a458c23 commit 6cb3c98
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 0 deletions.
33 changes: 33 additions & 0 deletions src/common/SurgeSynthesizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1755,6 +1755,39 @@ void SurgeSynthesizer::releaseNotePostHoldCheck(int scene, char channel, char ke
}
}

void SurgeSynthesizer::releaseNoteByHostID(int32_t host_noteid, char velocity)
{
std::array<uint16_t, 128> done;
std::fill(done.begin(), done.end(), 0);

for (int s = 0; s < n_scenes; ++s)
{
for (auto v : voices[s])
{
if (v->host_note_id == host_noteid)
{
done[v->state.key] |= 1 << v->state.channel;
}
}
}

int nidx{0};
for (auto d : done)
{
if (d)
{
for (auto ch = 0; ch < 16; ++ch)
{
if (d & 1 << ch)
{
releaseNote(ch, nidx, velocity, host_noteid);
}
}
}
nidx++;
}
}

void SurgeSynthesizer::setNoteExpression(SurgeVoice::NoteExpressionType net, int32_t note_id,
int16_t key, int16_t channel, float value)
{
Expand Down
3 changes: 3 additions & 0 deletions src/common/SurgeSynthesizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ class alignas(16) SurgeSynthesizer
void playNoteByFrequency(float freq, char velocity, int32_t id);
void releaseNote(char channel, char key, char velocity, int32_t host_noteid = -1);
void chokeNote(int16_t channel, int16_t key, char velocity, int32_t host_noteid = -1);
// Release all notes matching just this host noteid. Mostly used for OpenSoundCtrl right now
void releaseNoteByHostID(int32_t host_noteid, char velocity);

void releaseNotePostHoldCheck(int scene, char channel, char key, char velocity,
int32_t host_noteid = -1);
void resetPitchBend(int8_t channel);
Expand Down
90 changes: 90 additions & 0 deletions src/surge-testrunner/UnitTestsMIDI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1722,4 +1722,94 @@ TEST_CASE("Latch in Dual MPE", "[midi]")
}
}
}
}

TEST_CASE("Release by Note ID", "[midi]")
{
SECTION("Simple Sine Case")
{
auto s = surgeOnSine();

auto proc = [&s]() {
for (int i = 0; i < 5; ++i)
{
s->process();
}
};

auto voicecount = [&s]() -> int {
int res{0};
for (auto sc = 0; sc < n_scenes; ++sc)
{
for (const auto &v : s->voices[sc])
{
if (v->state.gate)
res++;
}
}
return res;
};

proc();

s->playNote(0, 60, 127, 0, 173);
proc();
REQUIRE(voicecount() == 1);

s->playNote(0, 64, 127, 0, 177);
proc();
REQUIRE(voicecount() == 2);

s->releaseNoteByHostID(173, 0);
proc();
REQUIRE(voicecount() == 1);

s->releaseNoteByHostID(177, 0);
proc();
REQUIRE(voicecount() == 0);
}

SECTION("Playmode DUal Sine Case")
{
auto s = surgeOnSine();
s->storage.getPatch().scenemode.val.i = sm_dual;

auto proc = [&s]() {
for (int i = 0; i < 5; ++i)
{
s->process();
}
};

auto voicecount = [&s]() -> int {
int res{0};
for (auto sc = 0; sc < n_scenes; ++sc)
{
for (const auto &v : s->voices[sc])
{
if (v->state.gate)
res++;
}
}
return res;
};

proc();

s->playNote(0, 60, 127, 0, 173);
proc();
REQUIRE(voicecount() == 2);

s->playNote(0, 64, 127, 0, 177);
proc();
REQUIRE(voicecount() == 4);

s->releaseNoteByHostID(173, 0);
proc();
REQUIRE(voicecount() == 2);

s->releaseNoteByHostID(177, 0);
proc();
REQUIRE(voicecount() == 0);
}
}

0 comments on commit 6cb3c98

Please sign in to comment.