Skip to content

Commit b18e74b

Browse files
committed
led event indicator
1 parent 7d41e7a commit b18e74b

5 files changed

Lines changed: 103 additions & 14 deletions

File tree

‎plugins/drumkit/include/drumkit_engine.hpp‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,10 @@ class Engine {
5151
void applyParameter(std::uint32_t index, float value);
5252

5353
float sampleRate_;
54+
std::uint32_t trigDecayLength_ = 4800;
5455
std::array<float, kParameterCount> parameters_ {};
5556
std::array<bool, kInstrumentCount> muted_ {};
57+
std::array<std::uint32_t, kInstrumentCount> trigDecay_ {};
5658

5759
std::unique_ptr<KickVoice> kick_;
5860
std::unique_ptr<SnareVoice> snare_;

‎plugins/drumkit/include/drumkit_params.hpp‎

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ struct ParameterSpec {
1414
float maximum;
1515
float defaultValue;
1616
bool boolean;
17+
bool output = false;
1718
};
1819

1920
enum ParameterId : std::uint32_t {
@@ -92,6 +93,17 @@ enum ParameterId : std::uint32_t {
9293
kParamBashPan,
9394
kParamCowbellPan,
9495
kParamClavePan,
96+
kParamKickTrig,
97+
kParamClapTrig,
98+
kParamSnareTrig,
99+
kParamCrashTrig,
100+
kParamClosedHHTrig,
101+
kParamTom1Trig,
102+
kParamOpenHHTrig,
103+
kParamTom2Trig,
104+
kParamBashTrig,
105+
kParamCowbellTrig,
106+
kParamClaveTrig,
95107
kParameterCount
96108
};
97109

@@ -120,6 +132,7 @@ struct InstrumentSpec {
120132
std::uint32_t levelParam;
121133
std::uint32_t muteParam;
122134
std::uint32_t panParam;
135+
std::uint32_t trigParam;
123136
};
124137

125138
inline constexpr std::array<ParameterSpec, kParameterCount> kParameterSpecs = {{
@@ -198,6 +211,17 @@ inline constexpr std::array<ParameterSpec, kParameterCount> kParameterSpecs = {{
198211
{"Bash Pan", "bash_pan", -1.0f, 1.0f, 0.42f, false},
199212
{"Cowbell Pan", "cowbell_pan", -1.0f, 1.0f, 0.14f, false},
200213
{"Clave Pan", "clave_pan", -1.0f, 1.0f, -0.24f, false},
214+
{"Kick Trig", "kick_trig", 0.0f, 1.0f, 0.0f, false, true},
215+
{"Clap Trig", "clap_trig", 0.0f, 1.0f, 0.0f, false, true},
216+
{"Snare Trig", "snare_trig", 0.0f, 1.0f, 0.0f, false, true},
217+
{"Crash Trig", "crash_trig", 0.0f, 1.0f, 0.0f, false, true},
218+
{"Closed HH Trig", "hh_closed_trig", 0.0f, 1.0f, 0.0f, false, true},
219+
{"Tom 1 Trig", "tom1_trig", 0.0f, 1.0f, 0.0f, false, true},
220+
{"Open HH Trig", "hh_open_trig", 0.0f, 1.0f, 0.0f, false, true},
221+
{"Tom 2 Trig", "tom2_trig", 0.0f, 1.0f, 0.0f, false, true},
222+
{"Bash Trig", "bash_trig", 0.0f, 1.0f, 0.0f, false, true},
223+
{"Cowbell Trig", "cowbell_trig", 0.0f, 1.0f, 0.0f, false, true},
224+
{"Clave Trig", "clave_trig", 0.0f, 1.0f, 0.0f, false, true},
201225
}};
202226

203227
[[nodiscard]] inline float normalizedKickPitchToHz(const float value)
@@ -218,17 +242,17 @@ inline constexpr std::array<ParameterSpec, kParameterCount> kParameterSpecs = {{
218242
}
219243

220244
inline constexpr std::array<InstrumentSpec, kInstrumentCount> kInstrumentSpecs = {{
221-
{InstrumentId::Kick, "Kick", "KICK", 36, kParamKickLevel, kParamKickMute, kParamKickPan},
222-
{InstrumentId::Clap, "Clap", "CLAP", 39, kParamClapLevel, kParamClapMute, kParamClapPan},
223-
{InstrumentId::Snare, "Snare", "SNARE", 40, kParamSnareLevel, kParamSnareMute, kParamSnarePan},
224-
{InstrumentId::Crash, "Crash", "CRASH", 41, kParamCrashLevel, kParamCrashMute, kParamCrashPan},
225-
{InstrumentId::ClosedHH, "Closed Hat", "CHH", 42, kParamClosedHHLevel, kParamClosedHHMute, kParamClosedHHPan},
226-
{InstrumentId::Tom1, "Low Tom", "LTOM", 45, kParamTom1Level, kParamTom1Mute, kParamTom1Pan},
227-
{InstrumentId::OpenHH, "Open Hat", "OHH", 46, kParamOpenHHLevel, kParamOpenHHMute, kParamOpenHHPan},
228-
{InstrumentId::Tom2, "High Tom", "HTOM", 50, kParamTom2Level, kParamTom2Mute, kParamTom2Pan},
229-
{InstrumentId::Bash, "Bash", "BASH", 51, kParamBashLevel, kParamBashMute, kParamBashPan},
230-
{InstrumentId::Cowbell, "Cowbell", "COW", 52, kParamCowbellLevel, kParamCowbellMute, kParamCowbellPan},
231-
{InstrumentId::Clave, "Clave", "CLAVE", 53, kParamClaveLevel, kParamClaveMute, kParamClavePan},
245+
{InstrumentId::Kick, "Kick", "KICK", 36, kParamKickLevel, kParamKickMute, kParamKickPan, kParamKickTrig},
246+
{InstrumentId::Clap, "Clap", "CLAP", 39, kParamClapLevel, kParamClapMute, kParamClapPan, kParamClapTrig},
247+
{InstrumentId::Snare, "Snare", "SNARE", 40, kParamSnareLevel, kParamSnareMute, kParamSnarePan, kParamSnareTrig},
248+
{InstrumentId::Crash, "Crash", "CRASH", 41, kParamCrashLevel, kParamCrashMute, kParamCrashPan, kParamCrashTrig},
249+
{InstrumentId::ClosedHH, "Closed Hat", "CHH", 42, kParamClosedHHLevel, kParamClosedHHMute, kParamClosedHHPan, kParamClosedHHTrig},
250+
{InstrumentId::Tom1, "Low Tom", "LTOM", 45, kParamTom1Level, kParamTom1Mute, kParamTom1Pan, kParamTom1Trig},
251+
{InstrumentId::OpenHH, "Open Hat", "OHH", 46, kParamOpenHHLevel, kParamOpenHHMute, kParamOpenHHPan, kParamOpenHHTrig},
252+
{InstrumentId::Tom2, "High Tom", "HTOM", 50, kParamTom2Level, kParamTom2Mute, kParamTom2Pan, kParamTom2Trig},
253+
{InstrumentId::Bash, "Bash", "BASH", 51, kParamBashLevel, kParamBashMute, kParamBashPan, kParamBashTrig},
254+
{InstrumentId::Cowbell, "Cowbell", "COW", 52, kParamCowbellLevel, kParamCowbellMute, kParamCowbellPan, kParamCowbellTrig},
255+
{InstrumentId::Clave, "Clave", "CLAVE", 53, kParamClaveLevel, kParamClaveMute, kParamClavePan, kParamClaveTrig},
232256
}};
233257

234258
} // namespace downspout::drumkit

‎plugins/drumkit/src/dpf/DrumkitPlugin.cpp‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,13 @@ class DrumkitPlugin : public Plugin
8585
const auto& spec = kParameterSpecs[index];
8686
parameter.name = spec.name;
8787
parameter.symbol = spec.symbol;
88-
parameter.hints = kParameterIsAutomatable;
89-
if (spec.boolean)
90-
parameter.hints |= kParameterIsBoolean | kParameterIsInteger;
88+
if (spec.output) {
89+
parameter.hints = kParameterIsOutput;
90+
} else {
91+
parameter.hints = kParameterIsAutomatable;
92+
if (spec.boolean)
93+
parameter.hints |= kParameterIsBoolean | kParameterIsInteger;
94+
}
9195
parameter.ranges.min = spec.minimum;
9296
parameter.ranges.max = spec.maximum;
9397
parameter.ranges.def = spec.defaultValue;

‎plugins/drumkit/src/dpf/DrumkitUI.cpp‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,11 @@ class DrumkitUI : public UI
483483
panRects_[index] = {panCx - panR, panCy - panR, panR * 2.0f, panR * 2.0f};
484484
drawPanKnob(index, panCx, panCy, panR, color, muted);
485485

486+
const float ledCx = rect.x + rect.w * 0.5f;
487+
const float ledCy = rect.y + 248.0f;
488+
const bool lit = values_[kInstrumentSpecs[index].trigParam] >= 0.5f;
489+
drawNoteLED(ledCx, ledCy, 6.0f, color, lit, muted);
490+
486491
const Rect mute {rect.x + 12.0f, rect.y + rect.h - 42.0f, rect.w - 24.0f, 28.0f};
487492
muteRects_[index] = mute;
488493
drawMuteButton(mute, color, muted);
@@ -513,6 +518,31 @@ class DrumkitUI : public UI
513518
closePath();
514519
}
515520

521+
void drawNoteLED(const float cx, const float cy, const float r, const Color& color, const bool lit, const bool muted)
522+
{
523+
if (lit && !muted) {
524+
beginPath();
525+
circle(cx, cy, r + 4.0f);
526+
fillColor(color.r, color.g, color.b, 50);
527+
fill();
528+
}
529+
530+
beginPath();
531+
circle(cx, cy, r);
532+
if (lit && !muted)
533+
fillColor(color.r, color.g, color.b, 240);
534+
else
535+
fillColor(26, 31, 33, 255);
536+
fill();
537+
538+
if (lit && !muted) {
539+
beginPath();
540+
circle(cx - r * 0.28f, cy - r * 0.38f, r * 0.32f);
541+
fillColor(255, 255, 255, 90);
542+
fill();
543+
}
544+
}
545+
516546
void drawMuteButton(const Rect& rect, const Color& color, const bool muted)
517547
{
518548
beginPath();

‎plugins/drumkit/src/drumkit_engine.cpp‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ namespace {
2424

2525
Engine::Engine(const float sampleRate)
2626
: sampleRate_(sampleRate)
27+
, trigDecayLength_(static_cast<std::uint32_t>(sampleRate * 0.1f))
2728
, reverbL_(sampleRate)
2829
, reverbR_(sampleRate)
2930
, dcBlockerL_(0.999f)
@@ -40,6 +41,7 @@ Engine::Engine(const float sampleRate)
4041
void Engine::setSampleRate(const float sampleRate)
4142
{
4243
sampleRate_ = sampleRate > 1.0f ? sampleRate : 48000.0f;
44+
trigDecayLength_ = static_cast<std::uint32_t>(sampleRate_ * 0.1f);
4345
rebuildVoices();
4446
for (std::uint32_t i = 0; i < kParameterCount; ++i)
4547
applyParameter(i, parameters_[i]);
@@ -111,50 +113,67 @@ void Engine::handleNoteOn(const std::uint8_t note, const std::uint8_t velocity)
111113
{
112114
const float vel = static_cast<float>(velocity) / 127.0f;
113115

116+
auto fireTrig = [&](const InstrumentId id) {
117+
const std::size_t idx = instrumentIndex(id);
118+
trigDecay_[idx] = trigDecayLength_;
119+
parameters_[kInstrumentSpecs[idx].trigParam] = 1.0f;
120+
};
121+
114122
switch (note)
115123
{
116124
case 36:
125+
fireTrig(InstrumentId::Kick);
117126
if (!isInstrumentMuted(InstrumentId::Kick))
118127
kick_->trigger(vel);
119128
break;
120129
case 39:
130+
fireTrig(InstrumentId::Clap);
121131
if (!isInstrumentMuted(InstrumentId::Clap))
122132
clap_->trigger(1.0f);
123133
break;
124134
case 40:
135+
fireTrig(InstrumentId::Snare);
125136
if (!isInstrumentMuted(InstrumentId::Snare))
126137
snare_->trigger(vel);
127138
break;
128139
case 41:
140+
fireTrig(InstrumentId::Crash);
129141
if (!isInstrumentMuted(InstrumentId::Crash))
130142
crash_->trigger(1.0f);
131143
break;
132144
case 42:
145+
fireTrig(InstrumentId::ClosedHH);
133146
openHH_->kill();
134147
if (!isInstrumentMuted(InstrumentId::ClosedHH))
135148
closedHH_->trigger(1.0f);
136149
break;
137150
case 45:
151+
fireTrig(InstrumentId::Tom1);
138152
if (!isInstrumentMuted(InstrumentId::Tom1))
139153
loTom_->trigger(vel);
140154
break;
141155
case 46:
156+
fireTrig(InstrumentId::OpenHH);
142157
if (!isInstrumentMuted(InstrumentId::OpenHH))
143158
openHH_->trigger(1.0f);
144159
break;
145160
case 50:
161+
fireTrig(InstrumentId::Tom2);
146162
if (!isInstrumentMuted(InstrumentId::Tom2))
147163
hiTom_->trigger(vel);
148164
break;
149165
case 51:
166+
fireTrig(InstrumentId::Bash);
150167
if (!isInstrumentMuted(InstrumentId::Bash))
151168
bash_->trigger(vel);
152169
break;
153170
case 52:
171+
fireTrig(InstrumentId::Cowbell);
154172
if (!isInstrumentMuted(InstrumentId::Cowbell))
155173
cowbell_->trigger(vel);
156174
break;
157175
case 53:
176+
fireTrig(InstrumentId::Clave);
158177
if (!isInstrumentMuted(InstrumentId::Clave))
159178
clave_->trigger(vel);
160179
break;
@@ -165,6 +184,12 @@ void Engine::handleNoteOn(const std::uint8_t note, const std::uint8_t velocity)
165184

166185
StereoFrame Engine::processStereo()
167186
{
187+
for (std::size_t i = 0; i < kInstrumentCount; ++i)
188+
{
189+
if (trigDecay_[i] > 0 && --trigDecay_[i] == 0)
190+
parameters_[kInstrumentSpecs[i].trigParam] = 0.0f;
191+
}
192+
168193
StereoFrame frame;
169194

170195
for (std::size_t i = 0; i < kInstrumentCount; ++i)
@@ -193,7 +218,11 @@ StereoFrame Engine::processStereo()
193218
void Engine::reset()
194219
{
195220
for (std::size_t i = 0; i < kInstrumentCount; ++i)
221+
{
196222
resetInstrument(static_cast<InstrumentId>(i));
223+
trigDecay_[i] = 0;
224+
parameters_[kInstrumentSpecs[i].trigParam] = 0.0f;
225+
}
197226

198227
reverbL_.reset();
199228
reverbR_.reset();

0 commit comments

Comments
 (0)