mirror of
https://codeberg.org/armin/chromaflock.git
synced 2026-09-01 04:10:47 +02:00
updateeeees
This commit is contained in:
parent
8768d13338
commit
462891fb11
5 changed files with 69 additions and 99 deletions
|
|
@ -210,37 +210,6 @@ private:
|
||||||
[](const NotePitch& a, const NotePitch& b) { return a.note < b.note; });
|
[](const NotePitch& a, const NotePitch& b) { return a.note < b.note; });
|
||||||
int n = static_cast<int>(seq.size());
|
int n = static_cast<int>(seq.size());
|
||||||
|
|
||||||
// "Down" patterns (and any harmony pattern with Direction Down) always
|
|
||||||
// descend from each held note through the chord tones of the octave
|
|
||||||
// below it: root, fifth below, third below, then the next octave's
|
|
||||||
// root. Built from the held notes directly so nothing ever plays
|
|
||||||
// above them.
|
|
||||||
bool wantDownFigure = hasHarmony()
|
|
||||||
&& (direction == DirectionDown || pattern == Down || pattern == DownMajor);
|
|
||||||
if (wantDownFigure) {
|
|
||||||
std::vector<NotePitch> down;
|
|
||||||
int thirdBelow = 12 - harmonyThird();
|
|
||||||
std::vector<int> tops(heldNotes.begin(), heldNotes.end());
|
|
||||||
std::sort(tops.begin(), tops.end(), [](int a, int b) { return a > b; });
|
|
||||||
for (int root : tops) {
|
|
||||||
if (std::find(tops.begin(), tops.end(), root + 12) != tops.end())
|
|
||||||
continue;
|
|
||||||
float vel = velocities[root];
|
|
||||||
for (int k = 0; k < octaves; ++k) {
|
|
||||||
auto pushClamped = [&](int pitch) {
|
|
||||||
pitch = pitch < 0 ? 0 : (pitch > 127 ? 127 : pitch);
|
|
||||||
down.push_back({pitch, vel});
|
|
||||||
};
|
|
||||||
pushClamped(root - 12 * k);
|
|
||||||
if (k < octaves - 1) {
|
|
||||||
pushClamped(root - 12 * k - 5);
|
|
||||||
pushClamped(root - 12 * k - thirdBelow);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return down;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<NotePitch> order;
|
std::vector<NotePitch> order;
|
||||||
auto push = [&](int i) { order.push_back(seq[i]); };
|
auto push = [&](int i) { order.push_back(seq[i]); };
|
||||||
|
|
||||||
|
|
@ -341,16 +310,17 @@ private:
|
||||||
int up = anchor + 12;
|
int up = anchor + 12;
|
||||||
up = up > 127 ? 127 : up;
|
up = up > 127 ? 127 : up;
|
||||||
float vel = heldNotes.empty() ? 0.9f : velocities[heldNotes.back()];
|
float vel = heldNotes.empty() ? 0.9f : velocities[heldNotes.back()];
|
||||||
|
NotePitch rest{restNote, vel};
|
||||||
order.clear();
|
order.clear();
|
||||||
if (pattern == C3C4A) {
|
if (pattern == C3C4A) {
|
||||||
order = {{anchor, vel}, {anchor, vel}, {up, vel}, {anchor, vel},
|
order = {{anchor, vel}, {anchor, vel}, {up, vel}, {anchor, vel},
|
||||||
{up, vel}, {anchor, vel}, {anchor, vel}, {up, vel}};
|
{up, vel}, {anchor, vel}, rest, {up, vel}};
|
||||||
} else if (pattern == C3C4B) {
|
} else if (pattern == C3C4B) {
|
||||||
order = {{up, vel}, {anchor, vel}, {anchor, vel}, {anchor, vel},
|
order = {{up, vel}, {anchor, vel}, rest, {anchor, vel},
|
||||||
{anchor, vel}, {anchor, vel}, {anchor, vel}, {anchor, vel}};
|
{anchor, vel}, {anchor, vel}, rest, {anchor, vel}};
|
||||||
} else if (pattern == C3C4C) {
|
} else if (pattern == C3C4C) {
|
||||||
order = {{anchor, vel}, {anchor, vel}, {anchor, vel}, {up, vel},
|
order = {{anchor, vel}, {anchor, vel}, rest, {up, vel},
|
||||||
{anchor, vel}, {anchor, vel}, {anchor, vel}, {anchor, vel}};
|
rest, {anchor, vel}, rest, {anchor, vel}};
|
||||||
} else if (pattern == C3C4D) {
|
} else if (pattern == C3C4D) {
|
||||||
order = {{anchor, vel}, {anchor, vel}, {up, vel}, {anchor, vel},
|
order = {{anchor, vel}, {anchor, vel}, {up, vel}, {anchor, vel},
|
||||||
{anchor, vel}, {up, vel}, {anchor, vel}, {anchor, vel},
|
{anchor, vel}, {up, vel}, {anchor, vel}, {anchor, vel},
|
||||||
|
|
|
||||||
|
|
@ -555,6 +555,7 @@ MainContentComponent::MainContentComponent(ChromaFlockProcessor& p)
|
||||||
arpEnabledLed(p.apvts, "arpEnabled", "ON", "OFF"),
|
arpEnabledLed(p.apvts, "arpEnabled", "ON", "OFF"),
|
||||||
arpDirectionLed(p.apvts, "arpDirection", "ON", "OFF"),
|
arpDirectionLed(p.apvts, "arpDirection", "ON", "OFF"),
|
||||||
delayPingPongLed(p.apvts, "delayPingPong", "ON", "OFF"),
|
delayPingPongLed(p.apvts, "delayPingPong", "ON", "OFF"),
|
||||||
|
reverbOnLed(p.apvts, "reverbOn", "ON", "OFF"),
|
||||||
lfo1SyncLed(p.apvts, "lfo1Sync", "SYNC ON", "SYNC OFF"),
|
lfo1SyncLed(p.apvts, "lfo1Sync", "SYNC ON", "SYNC OFF"),
|
||||||
lfo2SyncLed(p.apvts, "lfo2Sync", "SYNC ON", "SYNC OFF"),
|
lfo2SyncLed(p.apvts, "lfo2Sync", "SYNC ON", "SYNC OFF"),
|
||||||
delaySyncLed(p.apvts, "delaySync", "SYNC ON", "SYNC OFF") {
|
delaySyncLed(p.apvts, "delaySync", "SYNC ON", "SYNC OFF") {
|
||||||
|
|
@ -664,6 +665,7 @@ MainContentComponent::MainContentComponent(ChromaFlockProcessor& p)
|
||||||
setupParam(delayFbKnob, delayFbAttach, "delayFeedback", "FBACK");
|
setupParam(delayFbKnob, delayFbAttach, "delayFeedback", "FBACK");
|
||||||
setupParam(delayMixKnob, delayMixAttach, "delayMix", "MIX");
|
setupParam(delayMixKnob, delayMixAttach, "delayMix", "MIX");
|
||||||
addAndMakeVisible(delayPingPongLed);
|
addAndMakeVisible(delayPingPongLed);
|
||||||
|
addAndMakeVisible(reverbOnLed);
|
||||||
setupParam(reverbSizeKnob, reverbSizeAttach, "reverbSize", "SIZE");
|
setupParam(reverbSizeKnob, reverbSizeAttach, "reverbSize", "SIZE");
|
||||||
setupParam(reverbDampKnob, reverbDampAttach, "reverbDamping", "DAMP");
|
setupParam(reverbDampKnob, reverbDampAttach, "reverbDamping", "DAMP");
|
||||||
setupParam(reverbMixKnob, reverbMixAttach, "reverbMix", "MIX");
|
setupParam(reverbMixKnob, reverbMixAttach, "reverbMix", "MIX");
|
||||||
|
|
@ -771,7 +773,7 @@ MainContentComponent::MainContentComponent(ChromaFlockProcessor& p)
|
||||||
{"Up / Minor", "Down / Minor", "Up & Down / Major", "Down & Up / Major", "Random",
|
{"Up / Minor", "Down / Minor", "Up & Down / Major", "Down & Up / Major", "Random",
|
||||||
"As Played", "Chord", "Up & Down X", "Down & Up X", "Random Once", "Octave Up",
|
"As Played", "Chord", "Up & Down X", "Down & Up X", "Random Once", "Octave Up",
|
||||||
"Octave Down", "Pinky Up", "Pinky Down", "Up / Major", "Down / Major",
|
"Octave Down", "Pinky Up", "Pinky Down", "Up / Major", "Down / Major",
|
||||||
"Up & Down / Minor", "C3/C4 1", "C3/C4 2", "C3/C4 3", "C3/C4 4", "C3/C4 5"});
|
"Up & Down / Minor", "Stab 1", "Stab 2", "Stab 3", "Stab 4", "Stab 5"});
|
||||||
setupCB(arpOctavesBox, arpOctavesAttach, "arpOctaves", {"1", "2", "3"});
|
setupCB(arpOctavesBox, arpOctavesAttach, "arpOctaves", {"1", "2", "3"});
|
||||||
setupCB(arpRateBox, arpRateAttach, "arpRate", {"1/32", "1/16", "1/8", "1/4", "1/2", "1", "2"});
|
setupCB(arpRateBox, arpRateAttach, "arpRate", {"1/32", "1/16", "1/8", "1/4", "1/2", "1", "2"});
|
||||||
|
|
||||||
|
|
@ -1047,19 +1049,7 @@ void MainContentComponent::paint(juce::Graphics& g) {
|
||||||
g.setOpacity(1.0f);
|
g.setOpacity(1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Header section background
|
// Header section: no boxed background (border removed)
|
||||||
{
|
|
||||||
auto rect = juce::Rectangle<float>(10.0f, 0.0f, 1640.0f, 80.0f);
|
|
||||||
auto glow = rect.expanded(6.0f);
|
|
||||||
g.setColour(juce::Colour(0xff222222).withAlpha(0.25f));
|
|
||||||
g.fillRoundedRectangle(glow, 12.0f);
|
|
||||||
juce::ColourGradient fillGrad(juce::Colour(0xBB222222), rect.getCentreX(), rect.getY(),
|
|
||||||
juce::Colour(0xBB111111), rect.getCentreX(), rect.getBottom(), false);
|
|
||||||
g.setGradientFill(fillGrad);
|
|
||||||
g.fillRoundedRectangle(rect, 9.0f);
|
|
||||||
g.setColour(juce::Colour(0xff333333));
|
|
||||||
g.drawRoundedRectangle(rect, 9.0f, 1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load logo
|
// Load logo
|
||||||
if (!logoLoaded) {
|
if (!logoLoaded) {
|
||||||
|
|
@ -1116,13 +1106,13 @@ void MainContentComponent::paint(juce::Graphics& g) {
|
||||||
g.drawRoundedRectangle(rect, 9.0f, 1.0f);
|
g.drawRoundedRectangle(rect, 9.0f, 1.0f);
|
||||||
};
|
};
|
||||||
|
|
||||||
drawSection(10, 80, 498, 200);
|
drawSection(10, 88, 498, 200);
|
||||||
drawSection(518, 80, 624, 200);
|
drawSection(518, 88, 624, 200);
|
||||||
drawSection(1152, 80, 498, 200);
|
drawSection(1152, 88, 498, 200);
|
||||||
drawSection(10, 290, 563, 160);
|
drawSection(10, 298, 563, 160);
|
||||||
drawSection(583, 290, 502, 160);
|
drawSection(583, 298, 502, 160);
|
||||||
drawSection(1095, 290, 555, 160);
|
drawSection(1095, 298, 555, 160);
|
||||||
drawSection(10, 884, 1640, 136);
|
drawSection(10, 892, 1640, 136);
|
||||||
|
|
||||||
// FX sub-sections
|
// FX sub-sections
|
||||||
auto drawSubSection = [&](int x, int y, int w, int h, const juce::String& title, int titlePadY = 2) {
|
auto drawSubSection = [&](int x, int y, int w, int h, const juce::String& title, int titlePadY = 2) {
|
||||||
|
|
@ -1142,25 +1132,25 @@ void MainContentComponent::paint(juce::Graphics& g) {
|
||||||
g.drawText(title, x + 6, y + titlePadY, w - 12, 14, juce::Justification::centred);
|
g.drawText(title, x + 6, y + titlePadY, w - 12, 14, juce::Justification::centred);
|
||||||
};
|
};
|
||||||
|
|
||||||
drawSubSection(10, 460, 510, 115, "DISTORTION", 6);
|
drawSubSection(10, 468, 510, 115, "DISTORTION", 6);
|
||||||
drawSubSection(528, 460, 468, 115, "COMPRESSION", 6);
|
drawSubSection(528, 468, 468, 115, "COMPRESSION", 6);
|
||||||
drawSubSection(1004, 460, 268, 115, "PANNING", 6);
|
drawSubSection(1004, 468, 268, 115, "PANNING", 6);
|
||||||
drawSubSection(1280, 460, 370, 115, "LIMITER", 6);
|
drawSubSection(1280, 468, 370, 115, "LIMITER", 6);
|
||||||
|
|
||||||
// LFO sub-sections
|
// LFO sub-sections
|
||||||
drawSubSection(10, 586, 540, 150, "LFO 1", 4);
|
drawSubSection(10, 594, 464, 150, "LFO 1", 4);
|
||||||
drawSubSection(560, 586, 530, 150, "LFO 2", 4);
|
drawSubSection(480, 594, 464, 150, "LFO 2", 4);
|
||||||
|
|
||||||
// FX2 sub-sections
|
// FX2 sub-sections
|
||||||
drawSubSection(1015, 586, 375, 150, "DELAY", 4);
|
drawSubSection(950, 594, 368, 150, "DELAY", 4);
|
||||||
drawSubSection(1395, 586, 255, 150, "REVERB", 4);
|
drawSubSection(1324, 594, 326, 150, "REVERB", 4);
|
||||||
|
|
||||||
// Arpeggiator section (replaces the removed spectrum analyzer)
|
// Arpeggiator section (replaces the removed spectrum analyzer)
|
||||||
drawSubSection(860, 746, 790, 128, "ARPEGGIATOR", 6);
|
drawSubSection(860, 754, 790, 128, "ARPEGGIATOR", 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainContentComponent::resized() {
|
void MainContentComponent::resized() {
|
||||||
auto sectionY = 84;
|
auto sectionY = 92;
|
||||||
auto knobSize = 112;
|
auto knobSize = 112;
|
||||||
auto knobSpacing = 10;
|
auto knobSpacing = 10;
|
||||||
auto labelH = 18;
|
auto labelH = 18;
|
||||||
|
|
@ -1191,33 +1181,33 @@ void MainContentComponent::resized() {
|
||||||
filterEnvAmtKnob.setBounds(1162 + (knobSize + knobSpacing) * 2, knobYF, knobSize, knobSize);
|
filterEnvAmtKnob.setBounds(1162 + (knobSize + knobSpacing) * 2, knobYF, knobSize, knobSize);
|
||||||
keyTrackKnob.setBounds(1162 + (knobSize + knobSpacing) * 3, knobYF, knobSize, knobSize);
|
keyTrackKnob.setBounds(1162 + (knobSize + knobSpacing) * 3, knobYF, knobSize, knobSize);
|
||||||
|
|
||||||
envLabel.setBounds(10, 294, 563, labelH);
|
envLabel.setBounds(10, 302, 563, labelH);
|
||||||
{
|
{
|
||||||
int rowW = 4 * knobSize + 3 * knobSpacing;
|
int rowW = 4 * knobSize + 3 * knobSpacing;
|
||||||
int sx = 10 + (563 - rowW) / 2;
|
int sx = 10 + (563 - rowW) / 2;
|
||||||
int knobYA = 304 + labelH + 6;
|
int knobYA = 312 + labelH + 6;
|
||||||
envAttackKnob.setBounds(sx, knobYA, knobSize, knobSize);
|
envAttackKnob.setBounds(sx, knobYA, knobSize, knobSize);
|
||||||
envDecayKnob.setBounds(sx + (knobSize + knobSpacing), knobYA, knobSize, knobSize);
|
envDecayKnob.setBounds(sx + (knobSize + knobSpacing), knobYA, knobSize, knobSize);
|
||||||
envSustainKnob.setBounds(sx + (knobSize + knobSpacing) * 2, knobYA, knobSize, knobSize);
|
envSustainKnob.setBounds(sx + (knobSize + knobSpacing) * 2, knobYA, knobSize, knobSize);
|
||||||
envReleaseKnob.setBounds(sx + (knobSize + knobSpacing) * 3, knobYA, knobSize, knobSize);
|
envReleaseKnob.setBounds(sx + (knobSize + knobSpacing) * 3, knobYA, knobSize, knobSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
fEnvLabel.setBounds(583, 294, 502, labelH);
|
fEnvLabel.setBounds(583, 302, 502, labelH);
|
||||||
{
|
{
|
||||||
int rowW = 4 * knobSize + 3 * knobSpacing;
|
int rowW = 4 * knobSize + 3 * knobSpacing;
|
||||||
int sx = 583 + (502 - rowW) / 2;
|
int sx = 583 + (502 - rowW) / 2;
|
||||||
int knobYFE = 304 + labelH + 6;
|
int knobYFE = 312 + labelH + 6;
|
||||||
fEnvAttackKnob.setBounds(sx, knobYFE, knobSize, knobSize);
|
fEnvAttackKnob.setBounds(sx, knobYFE, knobSize, knobSize);
|
||||||
fEnvDecayKnob.setBounds(sx + (knobSize + knobSpacing), knobYFE, knobSize, knobSize);
|
fEnvDecayKnob.setBounds(sx + (knobSize + knobSpacing), knobYFE, knobSize, knobSize);
|
||||||
fEnvSustainKnob.setBounds(sx + (knobSize + knobSpacing) * 2, knobYFE, knobSize, knobSize);
|
fEnvSustainKnob.setBounds(sx + (knobSize + knobSpacing) * 2, knobYFE, knobSize, knobSize);
|
||||||
fEnvReleaseKnob.setBounds(sx + (knobSize + knobSpacing) * 3, knobYFE, knobSize, knobSize);
|
fEnvReleaseKnob.setBounds(sx + (knobSize + knobSpacing) * 3, knobYFE, knobSize, knobSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
globalLabel.setBounds(1095, 294, 555, labelH);
|
globalLabel.setBounds(1095, 302, 555, labelH);
|
||||||
{
|
{
|
||||||
int rowW = 4 * knobSize + 3 * knobSpacing;
|
int rowW = 4 * knobSize + 3 * knobSpacing;
|
||||||
int sx = 1095 + (555 - rowW) / 2;
|
int sx = 1095 + (555 - rowW) / 2;
|
||||||
int knobYM = 304 + labelH + 6;
|
int knobYM = 312 + labelH + 6;
|
||||||
panKnob.setBounds(sx, knobYM, knobSize, knobSize);
|
panKnob.setBounds(sx, knobYM, knobSize, knobSize);
|
||||||
driveKnob.setBounds(sx + (knobSize + knobSpacing), knobYM, knobSize, knobSize);
|
driveKnob.setBounds(sx + (knobSize + knobSpacing), knobYM, knobSize, knobSize);
|
||||||
masterKnob.setBounds(sx + (knobSize + knobSpacing) * 2, knobYM, knobSize, knobSize);
|
masterKnob.setBounds(sx + (knobSize + knobSpacing) * 2, knobYM, knobSize, knobSize);
|
||||||
|
|
@ -1225,7 +1215,7 @@ void MainContentComponent::resized() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- FX SECTION ---
|
// --- FX SECTION ---
|
||||||
int fxY = 432;
|
int fxY = 440;
|
||||||
int fxKnobSize = 80;
|
int fxKnobSize = 80;
|
||||||
int fxLabelH = 16;
|
int fxLabelH = 16;
|
||||||
int fxKnobY = fxY + 54; // sub-section y(476) + titlePad(6) + titleH(14) + bottomPad(6) + 4
|
int fxKnobY = fxY + 54; // sub-section y(476) + titlePad(6) + titleH(14) + bottomPad(6) + 4
|
||||||
|
|
@ -1274,32 +1264,32 @@ void MainContentComponent::resized() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- LFO SECTION ---
|
// --- LFO SECTION ---
|
||||||
int lfoY = 566;
|
int lfoY = 574;
|
||||||
int lfoKnobSize = 80;
|
int lfoKnobSize = 80;
|
||||||
int lfoKnobY = 586 + 4 + 14 + 6; // subSectionY + titlePad + titleH + bottomPad
|
int lfoKnobY = 594 + 4 + 14 + 6; // subSectionY + titlePad + titleH + bottomPad
|
||||||
|
|
||||||
lfoLabel.setBounds(10, lfoY, 1080, fxLabelH);
|
lfoLabel.setBounds(10, lfoY, 934, fxLabelH);
|
||||||
fx2Label.setBounds(1015, lfoY, 635, fxLabelH);
|
fx2Label.setBounds(950, lfoY, 700, fxLabelH);
|
||||||
|
|
||||||
// LFO 1 sub-section (X=15, Y=642, W=530, H=110)
|
// LFO 1 sub-section (X=10, Y=642, W=464, H=110)
|
||||||
lfo1RateKnob.setBounds(22, lfoKnobY, lfoKnobSize, lfoKnobSize);
|
lfo1RateKnob.setBounds(22, lfoKnobY, lfoKnobSize, lfoKnobSize);
|
||||||
lfo1DepthKnob.setBounds(132, lfoKnobY, lfoKnobSize, lfoKnobSize);
|
lfo1DepthKnob.setBounds(132, lfoKnobY, lfoKnobSize, lfoKnobSize);
|
||||||
lfo1ShapeBox.setBounds(242, lfoKnobY + (lfoKnobSize - 28) / 2, 105, 28);
|
lfo1ShapeBox.setBounds(242, lfoKnobY + (lfoKnobSize - 28) / 2, 105, 28);
|
||||||
lfo1DestBox.setBounds(357, lfoKnobY + (lfoKnobSize - 28) / 2, 105, 28);
|
lfo1DestBox.setBounds(357, lfoKnobY + (lfoKnobSize - 28) / 2, 105, 28);
|
||||||
lfo1SyncLed.setBounds(22, lfoKnobY + lfoKnobSize + 6, 200, 28);
|
lfo1SyncLed.setBounds(22, lfoKnobY + lfoKnobSize + 6, 200, 28);
|
||||||
|
|
||||||
// LFO 2 sub-section (X=560, Y=642, W=530, H=110)
|
// LFO 2 sub-section (X=480, Y=642, W=464, H=110)
|
||||||
lfo2RateKnob.setBounds(568, lfoKnobY, lfoKnobSize, lfoKnobSize);
|
lfo2RateKnob.setBounds(492, lfoKnobY, lfoKnobSize, lfoKnobSize);
|
||||||
lfo2DepthKnob.setBounds(678, lfoKnobY, lfoKnobSize, lfoKnobSize);
|
lfo2DepthKnob.setBounds(602, lfoKnobY, lfoKnobSize, lfoKnobSize);
|
||||||
lfo2ShapeBox.setBounds(788, lfoKnobY + (lfoKnobSize - 28) / 2, 105, 28);
|
lfo2ShapeBox.setBounds(712, lfoKnobY + (lfoKnobSize - 28) / 2, 105, 28);
|
||||||
lfo2DestBox.setBounds(903, lfoKnobY + (lfoKnobSize - 28) / 2, 105, 28);
|
lfo2DestBox.setBounds(827, lfoKnobY + (lfoKnobSize - 28) / 2, 105, 28);
|
||||||
lfo2SyncLed.setBounds(568, lfoKnobY + lfoKnobSize + 6, 200, 28);
|
lfo2SyncLed.setBounds(492, lfoKnobY + lfoKnobSize + 6, 200, 28);
|
||||||
|
|
||||||
// --- FX2 SECTION ---
|
// --- FX2 SECTION ---
|
||||||
int fx2KnobY = lfoKnobY;
|
int fx2KnobY = lfoKnobY;
|
||||||
|
|
||||||
// Delay sub-section: TIME, FBACK, MIX, PING + sync combo
|
// Delay sub-section: TIME, FBACK, MIX, PING + sync combo
|
||||||
int dx = 1020;
|
int dx = 962;
|
||||||
int dGap = lfoKnobSize + 8;
|
int dGap = lfoKnobSize + 8;
|
||||||
delayTimeKnob.setBounds(dx, fx2KnobY, lfoKnobSize, lfoKnobSize);
|
delayTimeKnob.setBounds(dx, fx2KnobY, lfoKnobSize, lfoKnobSize);
|
||||||
delayFbKnob.setBounds(dx + dGap, fx2KnobY, lfoKnobSize, lfoKnobSize);
|
delayFbKnob.setBounds(dx + dGap, fx2KnobY, lfoKnobSize, lfoKnobSize);
|
||||||
|
|
@ -1309,10 +1299,12 @@ void MainContentComponent::resized() {
|
||||||
|
|
||||||
// Reverb sub-section: SIZE, DAMP, MIX (right edge aligned to 1650)
|
// Reverb sub-section: SIZE, DAMP, MIX (right edge aligned to 1650)
|
||||||
{
|
{
|
||||||
int rx = 1402;
|
int rx = 1336;
|
||||||
reverbSizeKnob.setBounds(rx, fx2KnobY, lfoKnobSize, lfoKnobSize);
|
reverbSizeKnob.setBounds(rx, fx2KnobY, lfoKnobSize, lfoKnobSize);
|
||||||
reverbDampKnob.setBounds(rx + (lfoKnobSize + 4), fx2KnobY, lfoKnobSize, lfoKnobSize);
|
reverbDampKnob.setBounds(rx + (lfoKnobSize + 4), fx2KnobY, lfoKnobSize, lfoKnobSize);
|
||||||
reverbMixKnob.setBounds(rx + (lfoKnobSize + 4) * 2, fx2KnobY, lfoKnobSize, lfoKnobSize);
|
reverbMixKnob.setBounds(rx + (lfoKnobSize + 4) * 2, fx2KnobY, lfoKnobSize, lfoKnobSize);
|
||||||
|
// On/off LED on the right, filling the remaining space before the box edge
|
||||||
|
reverbOnLed.setBounds(rx + (lfoKnobSize + 4) * 3, fx2KnobY, 1650 - (rx + (lfoKnobSize + 4) * 3), lfoKnobSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- PRESET + SCALE (vertically centered within top section, y: 0..128) ---
|
// --- PRESET + SCALE (vertically centered within top section, y: 0..128) ---
|
||||||
|
|
@ -1341,11 +1333,11 @@ void MainContentComponent::resized() {
|
||||||
midiLabel.setBounds(1354, labelY2, 64, labelH2);
|
midiLabel.setBounds(1354, labelY2, 64, labelH2);
|
||||||
midiLed.setBounds(1418, (headerH - 10) / 2, 10, 10);
|
midiLed.setBounds(1418, (headerH - 10) / 2, 10, 10);
|
||||||
|
|
||||||
scaleLabel.setBounds(1514, labelY2, 58, labelH2);
|
scaleLabel.setBounds(1499, labelY2, 58, labelH2);
|
||||||
uiScaleBox.setBounds(1574, comboY2, 80, comboH2);
|
uiScaleBox.setBounds(1559, comboY2, 80, comboH2);
|
||||||
|
|
||||||
// Visualizer area
|
// Visualizer area
|
||||||
int vizY = 746;
|
int vizY = 754;
|
||||||
int vizH = 128;
|
int vizH = 128;
|
||||||
vuMeter.setBounds(10, vizY, 40, vizH);
|
vuMeter.setBounds(10, vizY, 40, vizH);
|
||||||
waveformDisplay.setBounds(60, vizY, 790, vizH);
|
waveformDisplay.setBounds(60, vizY, 790, vizH);
|
||||||
|
|
@ -1384,7 +1376,7 @@ void MainContentComponent::resized() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Piano roll
|
// Piano roll
|
||||||
pianoRoll.setBounds(10, 884, 1640, 136);
|
pianoRoll.setBounds(10, 892, 1640, 136);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===== PianoRollComponent =====
|
// ===== PianoRollComponent =====
|
||||||
|
|
|
||||||
|
|
@ -196,7 +196,7 @@ private:
|
||||||
// Arpeggiator controls
|
// Arpeggiator controls
|
||||||
juce::Label arpEnabledLabel, arpPatternLabel, arpOctavesLabel, arpDirectionLabel, arpRateLabel;
|
juce::Label arpEnabledLabel, arpPatternLabel, arpOctavesLabel, arpDirectionLabel, arpRateLabel;
|
||||||
juce::ComboBox arpPatternBox, arpOctavesBox, arpRateBox;
|
juce::ComboBox arpPatternBox, arpOctavesBox, arpRateBox;
|
||||||
LedToggle arpEnabledLed, arpDirectionLed, delayPingPongLed;
|
LedToggle arpEnabledLed, arpDirectionLed, delayPingPongLed, reverbOnLed;
|
||||||
|
|
||||||
// Preset menu
|
// Preset menu
|
||||||
juce::TextButton presetButton{"PRESET"};
|
juce::TextButton presetButton{"PRESET"};
|
||||||
|
|
@ -274,7 +274,7 @@ private:
|
||||||
MainContentComponent content;
|
MainContentComponent content;
|
||||||
float currentScale = 1.0f;
|
float currentScale = 1.0f;
|
||||||
static constexpr int baseWidth = 1660;
|
static constexpr int baseWidth = 1660;
|
||||||
static constexpr int baseHeight = 1028;
|
static constexpr int baseHeight = 1036;
|
||||||
|
|
||||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ChromaFlockEditor)
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ChromaFlockEditor)
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -273,6 +273,9 @@ juce::AudioProcessorValueTreeState::ParameterLayout ChromaFlockProcessor::create
|
||||||
juce::ParameterID{"reverbDamping", 1}, "Reverb Damping", zeroOne, 0.5f));
|
juce::ParameterID{"reverbDamping", 1}, "Reverb Damping", zeroOne, 0.5f));
|
||||||
layout.add(std::make_unique<juce::AudioParameterFloat>(
|
layout.add(std::make_unique<juce::AudioParameterFloat>(
|
||||||
juce::ParameterID{"reverbMix", 1}, "Reverb Mix", zeroOne, 0.2f));
|
juce::ParameterID{"reverbMix", 1}, "Reverb Mix", zeroOne, 0.2f));
|
||||||
|
layout.add(std::make_unique<juce::AudioParameterChoice>(
|
||||||
|
juce::ParameterID{"reverbOn", 1}, "Reverb On",
|
||||||
|
juce::StringArray{"Off", "On"}, 1));
|
||||||
|
|
||||||
// ARPEGGIATOR
|
// ARPEGGIATOR
|
||||||
layout.add(std::make_unique<juce::AudioParameterChoice>(
|
layout.add(std::make_unique<juce::AudioParameterChoice>(
|
||||||
|
|
@ -284,7 +287,7 @@ juce::AudioProcessorValueTreeState::ParameterLayout ChromaFlockProcessor::create
|
||||||
"Down & Up / Major", "Random", "As Played", "Chord", "Up & Down X",
|
"Down & Up / Major", "Random", "As Played", "Chord", "Up & Down X",
|
||||||
"Down & Up X", "Random Once", "Octave Up", "Octave Down", "Pinky Up",
|
"Down & Up X", "Random Once", "Octave Up", "Octave Down", "Pinky Up",
|
||||||
"Pinky Down", "Up / Major", "Down / Major", "Up & Down / Minor",
|
"Pinky Down", "Up / Major", "Down / Major", "Up & Down / Minor",
|
||||||
"C3/C4 1", "C3/C4 2", "C3/C4 3", "C3/C4 4", "C3/C4 5"}, 0));
|
"Stab 1", "Stab 2", "Stab 3", "Stab 4", "Stab 5"}, 0));
|
||||||
layout.add(std::make_unique<juce::AudioParameterChoice>(
|
layout.add(std::make_unique<juce::AudioParameterChoice>(
|
||||||
juce::ParameterID{"arpOctaves", 1}, "Arp Octaves",
|
juce::ParameterID{"arpOctaves", 1}, "Arp Octaves",
|
||||||
juce::StringArray{"1", "2", "3"}, 1));
|
juce::StringArray{"1", "2", "3"}, 1));
|
||||||
|
|
@ -460,9 +463,11 @@ void ChromaFlockProcessor::processBlock(juce::AudioBuffer<float>& buffer, juce::
|
||||||
std::vector<int> stopNotes;
|
std::vector<int> stopNotes;
|
||||||
std::vector<Arpeggiator::NotePitch> playNotes;
|
std::vector<Arpeggiator::NotePitch> playNotes;
|
||||||
arp.step(stopNotes, playNotes);
|
arp.step(stopNotes, playNotes);
|
||||||
|
bool isRest = playNotes.empty();
|
||||||
for (int n : stopNotes)
|
for (int n : stopNotes)
|
||||||
synth.noteOff(1, juce::jlimit(0, 127, n + transpose), 0.0f, true);
|
synth.noteOff(1, juce::jlimit(0, 127, n + transpose), 0.0f, !isRest);
|
||||||
for (const auto& np : playNotes)
|
for (const auto& np : playNotes)
|
||||||
|
if (np.note >= 0 && np.note <= 127)
|
||||||
synth.noteOn(1, juce::jlimit(0, 127, np.note + transpose), np.velocity);
|
synth.noteOn(1, juce::jlimit(0, 127, np.note + transpose), np.velocity);
|
||||||
arpSampleCount = 0.0;
|
arpSampleCount = 0.0;
|
||||||
}
|
}
|
||||||
|
|
@ -475,9 +480,11 @@ void ChromaFlockProcessor::processBlock(juce::AudioBuffer<float>& buffer, juce::
|
||||||
std::vector<int> stopNotes;
|
std::vector<int> stopNotes;
|
||||||
std::vector<Arpeggiator::NotePitch> playNotes;
|
std::vector<Arpeggiator::NotePitch> playNotes;
|
||||||
arp.step(stopNotes, playNotes);
|
arp.step(stopNotes, playNotes);
|
||||||
|
bool isRest = playNotes.empty();
|
||||||
for (int n : stopNotes)
|
for (int n : stopNotes)
|
||||||
synth.noteOff(1, juce::jlimit(0, 127, n + transpose), 0.0f, true);
|
synth.noteOff(1, juce::jlimit(0, 127, n + transpose), 0.0f, !isRest);
|
||||||
for (const auto& np : playNotes)
|
for (const auto& np : playNotes)
|
||||||
|
if (np.note >= 0 && np.note <= 127)
|
||||||
synth.noteOn(1, juce::jlimit(0, 127, np.note + transpose), np.velocity);
|
synth.noteOn(1, juce::jlimit(0, 127, np.note + transpose), np.velocity);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -520,7 +527,8 @@ void ChromaFlockProcessor::processBlock(juce::AudioBuffer<float>& buffer, juce::
|
||||||
}
|
}
|
||||||
delay.setParameters(delayTimeMs, getParam("delayFeedback"), getParam("delayMix"),
|
delay.setParameters(delayTimeMs, getParam("delayFeedback"), getParam("delayMix"),
|
||||||
getParam("delayPingPong") > 0.5f);
|
getParam("delayPingPong") > 0.5f);
|
||||||
reverbFX.setParameters(getParam("reverbSize"), getParam("reverbDamping"), 0.8f, getParam("reverbMix"));
|
float reverbMix = getParam("reverbOn") > 0.5f ? getParam("reverbMix") : 0.0f;
|
||||||
|
reverbFX.setParameters(getParam("reverbSize"), getParam("reverbDamping"), 0.8f, reverbMix);
|
||||||
limiter.setParameters(getParam("limiterThreshold"), getParam("limiterCeiling"),
|
limiter.setParameters(getParam("limiterThreshold"), getParam("limiterCeiling"),
|
||||||
getParam("limiterRelease"));
|
getParam("limiterRelease"));
|
||||||
|
|
||||||
|
|
|
||||||
BIN
bg.png
BIN
bg.png
Binary file not shown.
|
Before Width: | Height: | Size: 2.5 MiB After Width: | Height: | Size: 1.1 MiB |
Loading…
Add table
Add a link
Reference in a new issue