rework arpeggiator with blank notes and progressions

This commit is contained in:
Armin 2026-08-13 02:09:39 +02:00
commit d034139b5e
5 changed files with 219 additions and 104 deletions

View file

@ -30,6 +30,8 @@ public:
C3C4A,
C3C4B,
C3C4C,
C3C4D,
C3C4E,
numPatterns
};
@ -123,9 +125,16 @@ public:
}
if (pattern == Chord) {
static const bool chordBlanks[] =
{false, false, true, false, false, true, false, false,
true, false, false, true, false, true, false, true};
bool blank = chordBlanks[stepIndex % 16];
++stepIndex;
notesToStop = currentNotes;
notesToPlay = pool;
currentNotes.clear();
if (blank)
return;
notesToPlay = pool;
for (const auto& np : pool)
currentNotes.push_back(np.note);
return;
@ -145,11 +154,15 @@ public:
notesToStop = currentNotes;
currentNotes.clear();
currentNotes.push_back(np.note);
notesToPlay.push_back(np);
if (np.note != restNote) {
currentNotes.push_back(np.note);
notesToPlay.push_back(np);
}
}
private:
static constexpr int restNote = -1;
// Harmony patterns arpeggiate a third + fifth after each root: minor
// (root, +3, +7) or major (root, +4, +7). Each is a separate step.
bool hasHarmony() const {
@ -300,23 +313,30 @@ private:
}
break;
case PinkyUp:
case PinkyDown:
for (int hi = n - 1, lo = 0; hi >= lo; --hi, ++lo) {
if (pattern == PinkyUp) {
push(hi);
if (lo < hi) push(lo);
} else {
push(lo);
if (lo < hi) push(hi);
}
case PinkyDown: {
int anchor = heldNotes.empty() ? 48 : heldNotes.back();
int up = anchor + 12;
up = up > 127 ? 127 : up;
float vel = heldNotes.empty() ? 0.9f : velocities[heldNotes.back()];
NotePitch rest{restNote, vel};
order.clear();
if (pattern == PinkyUp) {
order = {{anchor, vel}, rest, {up, vel}, {anchor, vel},
rest, {up, vel}, {anchor, vel}, {anchor, vel}};
} else {
order = {{up, vel}, rest, {anchor, vel}, {up, vel},
rest, {anchor, vel}, {up, vel}, {up, vel}};
}
break;
}
case AsPlayed:
order = pool;
break;
case C3C4A:
case C3C4B:
case C3C4C: {
case C3C4C:
case C3C4D:
case C3C4E: {
int anchor = heldNotes.empty() ? 48 : heldNotes.back();
int up = anchor + 12;
up = up > 127 ? 127 : up;
@ -328,9 +348,20 @@ private:
} else if (pattern == C3C4B) {
order = {{up, vel}, {anchor, vel}, {anchor, vel}, {anchor, vel},
{anchor, vel}, {anchor, vel}, {anchor, vel}, {anchor, vel}};
} else {
} else if (pattern == C3C4C) {
order = {{anchor, vel}, {anchor, vel}, {anchor, vel}, {up, vel},
{anchor, vel}, {anchor, vel}, {anchor, vel}, {anchor, vel}};
} else if (pattern == C3C4D) {
order = {{anchor, vel}, {anchor, vel}, {up, vel}, {anchor, vel},
{anchor, vel}, {up, vel}, {anchor, vel}, {anchor, vel},
{up, vel}, {anchor, vel}, {anchor, vel}, {up, vel},
{anchor, vel}, {anchor, vel}, {anchor, vel}, {anchor, vel}};
} else {
NotePitch rest{restNote, vel};
order = {{anchor, vel}, {anchor, vel}, rest, {anchor, vel},
{anchor, vel}, rest, {anchor, vel}, {anchor, vel},
rest, {anchor, vel}, {anchor, vel}, rest,
{anchor, vel}, {anchor, vel}, {anchor, vel}, {anchor, vel}};
}
break;
}
@ -359,7 +390,9 @@ private:
}
if (direction == DirectionDown && pattern != Random && pattern != RandomOnce
&& pattern != AsPlayed && pattern != C3C4A && pattern != C3C4B && pattern != C3C4C)
&& pattern != AsPlayed && pattern != C3C4A && pattern != C3C4B
&& pattern != C3C4C && pattern != C3C4D && pattern != C3C4E
&& pattern != PinkyUp && pattern != PinkyDown)
std::sort(order.begin(), order.end(),
[](const NotePitch& a, const NotePitch& b) { return a.note > b.note; });