I'm trying to create guitar Wah Wah effect (basically band pass filter with dynamic frequency range). I'm using Steinberg SDK for it. I refactored this code to work in real time and it looks like this:
double Fc = 2500.0f * Hz + 350.0f; // Hz is a 0-1 float value
double F1 = 2.0f * sin((PI*Fc) / processSetup.sampleRate);
yh[0] = inputChannel[0];
yb[0] = F1 * yh[0];
yl[0] = F1 * yb[0];
double Q1 = 2 * 0.05;
for (int n = 1; n < data.numSamples; n++)
{
yh[n] = inputChannel[n] - yl[n-1] - Q1 * yb[n-1];
yb[n] = (F1 * yh[n] + yb[n - 1]);
yl[n] = F1 * yb[n] + yl[n - 1];
}
for (int n = 0; n < data.numSamples; n++)
outputChannel[n] = yb[n];
And it basically works but whole proccess added wierd popping sound, listen here.
After analizing FFT I noticed additional low and high frequencies and assume it cause those sounds. Here is example without and with effect:
But I don't know what is wrong with my code as it is the same like that example in matlab. If someone notice where is the issue I would be grateful for help.
Thank you in advance.
thanks for those reponses. Here are more explenations.
1. To TimWescott, all containers are float.
Here is screen with time domain before effect use and after
- To A_A, here whole procces code, but I whink everything before
if (data.numSamples > 0)
is not important it is only grabbing current controlls values.
tresult PLUGIN_API PlugProcessor::process (Vst::ProcessData& data)
{
//--- Read inputs parameter changes-----------
if (data.inputParameterChanges)
{
int32 numParamsChanged = data.inputParameterChanges->getParameterCount ();
for (int32 index = 0; index < numParamsChanged; index++)
{
Vst::IParamValueQueue* paramQueue =
data.inputParameterChanges->getParameterData (index);
if (paramQueue)
{
Vst::ParamValue value;
int32 sampleOffset;
int32 numPoints = paramQueue->getPointCount ();
switch (paramQueue->getParameterId ())
{
case HelloWorldParams::kParamGainId:
if (paramQueue->getPoint (numPoints - 1, sampleOffset, value) ==
kResultTrue)
mParam1 = value;
break;
case HelloWorldParams::kParamQId:
if (paramQueue->getPoint(numPoints - 1, sampleOffset, value) ==
kResultTrue)
Q = value;
break;
case HelloWorldParams::kParamHzId:
if (paramQueue->getPoint(numPoints - 1, sampleOffset, value) ==
kResultTrue)
Hz = value;
break;
case HelloWorldParams::kBypassId:
if (paramQueue->getPoint (numPoints - 1, sampleOffset, value) ==
kResultTrue)
mBypass = (value > 0.5f);
break;
}
}
}
}
if (data.numSamples > 0)
{
uint64 arr;
getBusArrangement(1, 0, arr);
int32 numChannels = Vst::SpeakerArr::getChannelCount(arr);
for (int32 channel = 0; channel < numChannels; channel++)
{
float* inputChannel = data.inputs[0].channelBuffers32[channel];
float* outputChannel = data.outputs[0].channelBuffers32[channel];
if (this->mBypass)
{
for (int32 sample = 0; sample < data.numSamples; sample++)
{
outputChannel[sample] = inputChannel[sample];
}
continue;
}
if (yl.size() != data.numSamples)
{
yl.resize(data.numSamples);
yh.resize(data.numSamples);
yb.resize(data.numSamples);
}
double Fc = 2500.0f * Hz + 350.0f;
double F1 = 2.0f * sin((PI*Fc) / processSetup.sampleRate); // it is 44100 Hz
yh[0] = inputChannel[0];
yb[0] = F1 * yh[0];
yl[0] = F1 * yb[0];
double Q1 = 2 * 0.05;
for (int n = 1; n < data.numSamples; n++)
{
yh[n] = inputChannel[n] - yl[n-1] - Q1 * yb[n-1];
yb[n] = (F1 * yh[n] + yb[n - 1]);
yl[n] = F1 * yb[n] + yl[n - 1];
}
for (int n = 0; n < data.numSamples; n++)
outputChannel[n] = yb[n];
}
}
return kResultOk;
}
And here are settings of Reaper on which I'm running this VST:
Thanks
process()
of your plugin and the system settings you use to run it? (Buffer size, sampling frequency)? The VST SDK does not take care of "state" between calls, this is up to the plugin itself. $\endgroup$