Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions dsp/Params.cmajor
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ namespace Percupuff
float cowbellPanning;
float cowbellVelocity;
float cowbellMidi;
float cabasaLevel;
float cabasaPanning;
float cabasaVelocity;
float cabasaMidi;
float maracasLevel;
float maracasPanning;
float maracasVelocity;
Expand Down Expand Up @@ -177,6 +181,10 @@ namespace Percupuff
p.cowbellPanning = 0.0f;
p.cowbellVelocity = 100.0f;
p.cowbellMidi = 56.0f;
p.cabasaLevel = 50.0f;
p.cabasaPanning = 0.0f;
p.cabasaVelocity = 100.0f;
p.cabasaMidi = 69.0f;
p.maracasLevel = 50.0f;
p.maracasPanning = 0.0f;
p.maracasVelocity = 100.0f;
Expand Down Expand Up @@ -268,6 +276,10 @@ namespace Percupuff
input event float cowbellPanning [[ name: "cowbellPanning", min: -100, max: 100, init: 0, step: 5 ]];
input event float cowbellVelocity [[ name: "cowbellVelocity", min: 0, max: 100, init: 100, step: 1 ]];
input event float cowbellMidi [[ name: "cowbellMidi", min: 0, max: 127, init: 56, step: 1 ]];
input event float cabasaLevel [[ name: "cabasaLevel", min: 0, max: 100, init: 50, step: 1 ]];
input event float cabasaPanning [[ name: "cabasaPanning", min: -100, max: 100, init: 0, step: 5 ]];
input event float cabasaVelocity [[ name: "cabasaVelocity", min: 0, max: 100, init: 100, step: 1 ]];
input event float cabasaMidi [[ name: "cabasaMidi", min: 0, max: 127, init: 69, step: 1 ]];
input event float maracasLevel [[ name: "maracasLevel", min: 0, max: 100, init: 50, step: 1 ]];
input event float maracasPanning [[ name: "maracasPanning", min: -100, max: 100, init: 0, step: 5 ]];
input event float maracasVelocity [[ name: "maracasVelocity", min: 0, max: 100, init: 100, step: 1 ]];
Expand Down Expand Up @@ -362,6 +374,10 @@ namespace Percupuff
event cowbellPanning (float f) { params.cowbellPanning = f; update(); }
event cowbellVelocity (float f) { params.cowbellVelocity = f; update(); }
event cowbellMidi (float f) { params.cowbellMidi = f; update(); }
event cabasaLevel (float f) { params.cabasaLevel = f; update(); }
event cabasaPanning (float f) { params.cabasaPanning = f; update(); }
event cabasaVelocity (float f) { params.cabasaVelocity = f; update(); }
event cabasaMidi (float f) { params.cabasaMidi = f; update(); }
event maracasLevel (float f) { params.maracasLevel = f; update(); }
event maracasPanning (float f) { params.maracasPanning = f; update(); }
event maracasVelocity (float f) { params.maracasVelocity = f; update(); }
Expand Down
4 changes: 4 additions & 0 deletions dsp/Percupuff.cmajor
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ namespace Percupuff
bongos = Drums::Bongos;
sideStick = Drums::SideStick;
rideBell = Drums::RideBell;
cabasa = Drums::Cabasa;
maracas = Drums::Maracas;
gainLimiter = std::levels::ConstantGain (float<2>, 1.0f);
mpe = std::midi::MPEConverter;
Expand All @@ -58,6 +59,7 @@ namespace Percupuff
p.paramsOut -> electricSnare.paramsIn;
p.paramsOut -> sideStick.paramsIn;
p.paramsOut -> rideBell.paramsIn;
p.paramsOut -> cabasa.paramsIn;
p.paramsOut -> maracas.paramsIn;

// Send the midi events so the sound processors know when to start playing.
Expand All @@ -73,6 +75,7 @@ namespace Percupuff
mpe -> bongos.eventIn;
mpe -> sideStick.eventIn;
mpe -> rideBell.eventIn;
mpe -> cabasa.eventIn;
mpe -> maracas.eventIn;
mpe -> noteOn;

Expand All @@ -98,6 +101,7 @@ namespace Percupuff
bongos -> gainLimiter;
sideStick -> gainLimiter;
rideBell -> gainLimiter;
cabasa -> gainLimiter;
maracas -> gainLimiter;

// Output the result.
Expand Down
105 changes: 105 additions & 0 deletions dsp/drums/Cabasa.cmajor
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
namespace Percupuff
{
namespace Drums
{
processor Cabasa {
input event (std::notes::NoteOn) eventIn;
output stream float<2> out;
input event Params paramsIn;

float triggerVelocity = 0.0f;
int midiNotePitch = 0;
float outputLevel = 0.5f;
float panning = 0.0f;

event paramsIn(Params p) {
midiNotePitch = int(p.cabasaMidi);
outputLevel = p.cabasaLevel * 0.01f;
panning = p.cabasaPanning;
}

event eventIn(std::notes::NoteOn n) {
if (int(n.pitch) == midiNotePitch)
triggerVelocity = sqrt(n.velocity);
}

node envelope = Envelope;
node noise = std::noise::White;

// Use one resonant SVF, this gives the metallic "clack" sound
node filter = std::filters::tpt::svf::Processor(
std::filters::tpt::svf::Mode::bandPass, 4000.0f, 5.0f
);

void main()
{
envelope.attackIn <- 0.0008f;
let baseCutoff = 3800.0f; // Metallic "clack" frequency
let baseQ = 5.0f; // This resonance is the "metal" sound

loop
{
while (triggerVelocity == 0)
advance();

let baseVel = triggerVelocity;
triggerVelocity = 0.0f;

float burstCount = 4 + (baseVel * 25);
// Slightly increased spacing for a "heavier" bead sound
float burstSpacing = 0.0005f + (1.0f - baseVel) * 0.0045f;

for (int i = 0; i < int(burstCount); ++i)
{
float velJitter = 0.8f + (noise.out * 0.2f);
float burstVel = baseVel * velJitter;

// Modified release for more "body" on each bead hit
envelope.releaseIn <- 0.004f + (noise.out * 0.001f);
envelope.triggerIn <- void;
envelope.advance();

float gain = envelope.gainOut;

// Alternate stereo motion slightly
float altPan = ((i % 2 == 0) ? -0.4f : 0.4f) + (panning * 0.01f);

// Add jitter to cutoff and Q for a more natural, chaotic sound
filter.frequency <- baseCutoff + (noise.out * 400.0f);
filter.q <- baseQ + (noise.out * 0.5f);

while (gain > 0.001f)
{
float raw = noise.out;

// Run the noise through the filter
filter.in <- raw;
float filtered = filter.out;

float outSample = filtered * gain * burstVel * outputLevel;

float leftGain = 0.5f * (1.0f - altPan);
float rightGain = 0.5f * (1.0f + altPan);
out <- (outSample * leftGain, outSample * rightGain);

noise.advance();
filter.advance();
envelope.advance();
advance();

gain = envelope.gainOut;
}

float jitter = (noise.out * 0.0003f);
int silentSamples = int((burstSpacing + jitter) * float(processor.frequency));
for (int s = 0; s < silentSamples; ++s)
{
out <- (0.0f, 0.0f); // Output silence in stereo
advance();
}
}
}
}
}
}
}
1 change: 1 addition & 0 deletions percupuff.cmajorpatch
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"dsp/drums/Bongos.cmajor",
"dsp/drums/SideStick.cmajor",
"dsp/drums/RideBell.cmajor",
"dsp/drums/Cabasa.cmajor",
"dsp/drums/Maracas.cmajor",
"dsp/Percupuff.cmajor"
],
Expand Down
1 change: 1 addition & 0 deletions view/src/params.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export const instruments = {

cowbell: { name: "Cowbell", group: "๐Ÿฎ", midi: 56 },

cabasa: { name: "Cabasa", group: null, midi: 69 },
maracas: { name: "Maracas", group: null, midi: 70 },

// Example of adding an instrument without having it show up in the UI yet.
Expand Down