marvinh
September 19, 2024, 12:33pm
1
struct Onepole {
double g;
double s;
double sr;
void init() {
s = 0;
setParams(480, 44100.0);
}
void setParams(double cutoff, double sampleRate) {
g = tan(M_PI*(cutoff/sampleRate));
}
double process(double in) {
double out = ( g * (in) + s ) / ( g + 1 );
s = 2 * out - s;
return out;
}
};
void startNote (int midiNoteNumber, float velocity,
juce::SynthesiserSound* /*sound*/,
int /*currentPitchWheelPosition*/) override
{
gate = 1.0;
//tailOff = 0.0;
}
void stopNote (float /*velocity*/, bool allowTailOff) override
{
gate = 0;
//clearCurrentNote();
}
while (--numSamples >= 0)
{
auto s = //sampledata
auto g = gateLP.process(gate);
for (auto i = outputBuffer.getNumChannels(); --i >= 0;)
outputBuffer.addSample (i, startSample, s*g);
startSample++;
if(juce::approximatelyEqual(0.0, g)){
clearCurrentNote();
}
}
marvinh
September 19, 2024, 12:56pm
2
if you are trying to avoid clicks you have to create two mini voices for each parent voice
like so
env = 0 on start note
envInc is set to 1/32.0 samples or so to fade in
this way you dont have to write your own midi handlers
while (--numSamples >= 0)
{
double s = 0;
if(env < 1.0){
s = env*mini[swap].process() + (1-env)*mini[!swap].process();
env += envInc;
}else{
s = mini[swap].process();
}
auto g = gateLP.process(gate);
for (auto i = outputBuffer.getNumChannels(); --i >= 0;)
outputBuffer.addSample (i, startSample, s*g);
startSample++;
if(juce::approximatelyEqual(0.0, g)){
clearCurrentNote();
}
}