Hi All Jucers… I need a way to cast a IIRCoefficent to an array of float coefficients so I can use them for designing a filter graph. Is it possible?
Did you take a look at the class documentation? From there it’s easy to find it out. If you didn’t, you should get used to take a look there first
Now if you’re talking about the old IIRCoefficients
class, you’ll find out here https://docs.juce.com/master/classIIRCoefficients.html that it has a public attribute coefficients[5]
. So accessing the array is as simple as myIIRCoefficients.coefficients
.
If you are talking about the new dsp::IIRCoefficients
class, you’ll find out here https://docs.juce.com/master/structdsp_1_1IIR_1_1Coefficients.html that it has the member function getRawCoefficients()
returning a pointer to the raw coefficient array. In this case, accessing the array look like myIIRCoefficients.getRawCoefficients()
ok thanks! Now I have access to the coefficents:
I have this code:
dsp::IIR::Coefficients<float>::Ptr newCoefficients;
switch (filterType)
{
case LowPass:
newCoefficients = dsp::IIR::Coefficients<float>::makeLowPass (fs, frequency, Q);
b0 = newCoefficients->getRawCoefficients()[0];
b1 = newCoefficients->getRawCoefficients()[1];
b2 = newCoefficients->getRawCoefficients()[2];
a0 = newCoefficients->getRawCoefficients()[3];
a1 = newCoefficients->getRawCoefficients()[4];
a2 = newCoefficients->getRawCoefficients()[5];
break;
...
And I Pass to this function in paint() of my filterGraph component
tracePath.clear();
if (traceType == Magnitude)
{
float scaleFactor = (((height / 2) - (height - 5) / (numHorizontalLines + 1) - 2.5f) / maxdB);
float traceMagnitude = (float) (filterVector [0].getResponse (lowFreq).magnitudeValue);
for (int i = 1; i < numFilters; i++)
{
traceMagnitude *= (float) (filterVector [i].getResponse (lowFreq).magnitudeValue);
}
traceMagnitude = 20 * log10 (traceMagnitude);
tracePath.startNewSubPath (2.5f, (height / 2) - (traceMagnitude * scaleFactor));
for (float xPos = 3.5; xPos < (width - 2.5); xPos += 1)
{
float freq = xToFreq (xPos);
traceMagnitude = (float) (filterVector [0].getResponse (freq).magnitudeValue);
for (int i = 1; i < numFilters; i++)
{
traceMagnitude *= (float) (filterVector [i].getResponse (freq).magnitudeValue);
}
traceMagnitude = 20 * log10 (traceMagnitude);
tracePath.lineTo (xPos, (height / 2) - (traceMagnitude * scaleFactor));
}
}
if (traceType == Phase)
{
float scaleFactor = ((height / 2) - (height - 5) / (numHorizontalLines + 1) - 2.5f) / (float_Pi * maxPhas);
float traceMagnitude = (float) (filterVector [0].getResponse (lowFreq).phaseValue);
for (int i = 1; i < numFilters; i++)
{
traceMagnitude += (float) (filterVector [i].getResponse (lowFreq).phaseValue);
}
float prevPhase = traceMagnitude;
float unwrapSummand = 0;
tracePath.startNewSubPath (2.5f, (height / 2) - (traceMagnitude * scaleFactor));
for (float xPos = 3.5; xPos < (width - 2.5); xPos += 1)
{
float freq = xToFreq (xPos);
traceMagnitude = (float) (filterVector [0].getResponse (freq).phaseValue);
for (int i = 1; i < numFilters; i++)
{
traceMagnitude += (float) (filterVector [i].getResponse (freq).phaseValue);
}
if (fabs (traceMagnitude - prevPhase) > 5)
{
unwrapSummand += float_Pi * 2;
}
prevPhase = traceMagnitude;
tracePath.lineTo (xPos, (height / 2) - ((traceMagnitude + unwrapSummand) * scaleFactor));
}
}
g.setColour (traceColour);
g.strokePath (tracePath, PathStrokeType (1.0f));
And I get this error;
the old working code was:
switch (filterType)
{
case LowPass:
b0 = (1 - cos(w0)) / 2;
b1 = 1 - cos(w0);
b2 = (1 - cos(w0)) / 2;
a0 = 1 + alpha;
a1 = -2 * cos(w0);
a2 = 1 - alpha;
break;
...
And with that code the graph is plotted.With the other, the debugger say to me that the traceMagnitude is NaN…
In the line before the error you write:
but the magnitude is likely to be 0 from time to time… so together with log10 it should ring a bell…
sorry, I can’t understand…
The logarithm of 0 is undefined, since the equation y = 10 ^ x
has no solution for y == 0. The number you are getting for log10 (0) is NaN (“not a number”). So you should check if traceMagnitude > 0 before trying to compute the log of that.
Or even better, make use of the Decibels::gainToDecibels() function.
ok now I understand, thank you very much!
If I use Decibels::gainToDecibels, the path isn’t plotted…
I haven’t read your code, but you probably have to check your maths and in which range the numbers are:
gain = 0 => dB = -infinity (defaults to -80.0, can be specified)
gain = 0.5 => dB = - 6dB
gain = 1 => dB = 0
so you can simply map to your rect:
auto y = jmap (Decibels::gainToDecibels (magnitude, -80.8f), -80.0f, 0.0f, rect.getBottom(), rect.getY());
BTW. I think this thread will be interesting for you: