commit ad75e3744776a25a307cc0809a14867bec751923
parent 8e2d5b49dc03517c60f363b1048dcfc93277f48e
Author: fundamental <mark.d.mccurry@gmail.com>
Date: Mon, 30 May 2016 09:35:43 -0400
FilterParams: Add OSC Method To Get Response
Diffstat:
4 files changed, 68 insertions(+), 42 deletions(-)
diff --git a/src/DSP/AnalogFilter.cpp b/src/DSP/AnalogFilter.cpp
@@ -61,28 +61,35 @@ void AnalogFilter::cleanup()
needsinterpolation = false;
}
-void AnalogFilter::computefiltercoefs(void)
+AnalogFilter::Coeff AnalogFilter::computeCoeff(int type, float cutoff, float q,
+ int stages, float gain, float fs, int &order)
{
- float tmp;
+ AnalogFilter::Coeff coeff;
bool zerocoefs = false; //this is used if the freq is too high
+ const float samplerate_f = fs;
+ const float halfsamplerate_f = fs/2;
+
//do not allow frequencies bigger than samplerate/2
- float freq = this->freq;
+ float freq = cutoff;
if(freq > (halfsamplerate_f - 500.0f)) {
freq = halfsamplerate_f - 500.0f;
zerocoefs = true;
}
+
if(freq < 0.1f)
freq = 0.1f;
+
//do not allow bogus Q
if(q < 0.0f)
q = 0.0f;
+
+
float tmpq, tmpgain;
if(stages == 0) {
tmpq = q;
tmpgain = gain;
- }
- else {
+ } else {
tmpq = (q > 1.0f) ? powf(q, 1.0f / (stages + 1)) : q;
tmpgain = powf(gain, 1.0f / (stages + 1));
}
@@ -100,6 +107,9 @@ void AnalogFilter::computefiltercoefs(void)
//the "Cookbook formulae for audio EQ" by Robert Bristow-Johnson
//The original location of the Cookbook is:
//http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
+ float tmp;
+ float tgp1;
+ float tgm1;
switch(type) {
case 0: //LPF 1 pole
if(!zerocoefs)
@@ -205,20 +215,15 @@ void AnalogFilter::computefiltercoefs(void)
if(!zerocoefs) {
tmpq = sqrtf(tmpq);
beta = sqrtf(tmpgain) / tmpq;
- tmp = (tmpgain + 1.0f) + (tmpgain - 1.0f) * cs + beta * sn;
-
- c[0] = tmpgain
- * ((tmpgain
- + 1.0f) - (tmpgain - 1.0f) * cs + beta * sn) / tmp;
- c[1] = 2.0f * tmpgain
- * ((tmpgain - 1.0f) - (tmpgain + 1.0f) * cs) / tmp;
- c[2] = tmpgain
- * ((tmpgain
- + 1.0f) - (tmpgain - 1.0f) * cs - beta * sn) / tmp;
- d[1] = -2.0f * ((tmpgain - 1.0f) + (tmpgain + 1.0f) * cs)
- / tmp * -1.0f;
- d[2] = ((tmpgain + 1.0f) + (tmpgain - 1.0f) * cs - beta * sn)
- / tmp * -1.0f;
+ tgp1 = tmpgain + 1.0f;
+ tgm1 = tmpgain - 1.0f;
+ tmp = tgp1 + tgm1 * cs + beta * sn;
+
+ c[0] = tmpgain * (tgp1 - tgm1 * cs + beta * sn) / tmp;
+ c[1] = 2.0f * tmpgain * (tgm1 - tgp1 * cs) / tmp;
+ c[2] = tmpgain * (tgp1 - tgm1 * cs - beta * sn) / tmp;
+ d[1] = -2.0f * (tgm1 + tgp1 * cs) / tmp * -1.0f;
+ d[2] = (tgp1 + tgm1 * cs - beta * sn) / tmp * -1.0f;
}
else {
c[0] = tmpgain;
@@ -230,20 +235,15 @@ void AnalogFilter::computefiltercoefs(void)
if(!zerocoefs) {
tmpq = sqrtf(tmpq);
beta = sqrtf(tmpgain) / tmpq;
- tmp = (tmpgain + 1.0f) - (tmpgain - 1.0f) * cs + beta * sn;
-
- c[0] = tmpgain
- * ((tmpgain
- + 1.0f) + (tmpgain - 1.0f) * cs + beta * sn) / tmp;
- c[1] = -2.0f * tmpgain
- * ((tmpgain - 1.0f) + (tmpgain + 1.0f) * cs) / tmp;
- c[2] = tmpgain
- * ((tmpgain
- + 1.0f) + (tmpgain - 1.0f) * cs - beta * sn) / tmp;
- d[1] = 2.0f * ((tmpgain - 1.0f) - (tmpgain + 1.0f) * cs)
- / tmp * -1.0f;
- d[2] = ((tmpgain + 1.0f) - (tmpgain - 1.0f) * cs - beta * sn)
- / tmp * -1.0f;
+ tgp1 = tmpgain + 1.0f;
+ tgm1 = tmpgain - 1.0f;
+ tmp = tgp1 - tgm1 * cs + beta * sn;
+
+ c[0] = tmpgain * (tgp1 + tgm1 * cs + beta * sn) / tmp;
+ c[1] = -2.0f * tmpgain * (tgm1 + tgp1 * cs) / tmp;
+ c[2] = tmpgain * (tgp1 + tgm1 * cs - beta * sn) / tmp;
+ d[1] = 2.0f * (tgm1 - tgp1 * cs) / tmp * -1.0f;
+ d[2] = (tgp1 - tgm1 * cs - beta * sn) / tmp * -1.0f;
}
else {
c[0] = 1.0f;
@@ -252,10 +252,16 @@ void AnalogFilter::computefiltercoefs(void)
order = 2;
break;
default: //wrong type
- type = 0;
- computefiltercoefs();
+ assert(false && "wrong type for a filter");
break;
}
+ return coeff;
+}
+
+void AnalogFilter::computefiltercoefs(void)
+{
+ coeff = AnalogFilter::computeCoeff(type, freq, q, stages, gain,
+ samplerate_f, order);
}
diff --git a/src/DSP/AnalogFilter.h b/src/DSP/AnalogFilter.h
@@ -46,6 +46,9 @@ class AnalogFilter:public Filter
d[3]; //Feed Back
} coeff, oldCoeff;
+ static Coeff computeCoeff(int type, float cutoff, float q, int stages,
+ float gain, float fs, int &order);
+
private:
struct fstage {
float x1, x2; //Input History
diff --git a/src/Params/FilterParams.cpp b/src/Params/FilterParams.cpp
@@ -14,6 +14,7 @@
#include "FilterParams.h"
#include "../Misc/Util.h"
#include "../Misc/Time.h"
+#include "../DSP/AnalogFilter.h"
#include <cmath>
#include <cstdio>
#include <cstdlib>
@@ -117,6 +118,25 @@ const rtosc::Ports FilterParams::ports = {
FilterParams *obj = (FilterParams *) d.obj;
d.reply(d.loc, "f", obj->getoctavesfreq());
}},
+ {"response:",
+ rDoc("Get a frequency response"),
+ NULL, [](const char *, RtData &d) {
+ FilterParams *obj = (FilterParams *) d.obj;
+ int order = 0;
+ float gain = dB2rap(obj->getgain());
+ if(obj->Ptype != 6 && obj->Ptype != 7 && obj->Ptype != 8)
+ gain = 1.0;
+ auto cf = AnalogFilter::computeCoeff(obj->Ptype,
+ Filter::getrealfreq(obj->getfreq()),
+ obj->getq(), obj->Pstages,
+ gain, 48000, order);
+ if(order == 2) {
+ d.reply(d.loc, "fffffff",
+ (float)obj->Pstages,
+ cf.c[0], cf.c[1], cf.c[2],
+ 0.0, cf.d[1], cf.d[2]);
+ }
+ }},
// "", NULL, [](){}},"/freq"
//{"Pvowels#" FF_MAX_VOWELS "/formants#" FF_MAX_FORMANTS "/amp",
// "", NULL, [](){}},
@@ -294,21 +314,18 @@ float FilterParams::getfreqpos(float freq) const
*/
float FilterParams::getformantfreq(unsigned char freq) const
{
- float result = getfreqx(freq / 127.0f);
- return result;
+ return getfreqx(freq / 127.0f);
}
float FilterParams::getformantamp(unsigned char amp) const
{
- float result = powf(0.1f, (1.0f - amp / 127.0f) * 4.0f);
- return result;
+ return powf(0.1f, (1.0f - amp / 127.0f) * 4.0f);
}
float FilterParams::getformantq(unsigned char q) const
{
//temp
- float result = powf(25.0f, (q - 32.0f) / 64.0f);
- return result;
+ return powf(25.0f, (q - 32.0f) / 64.0f);
}
diff --git a/src/Synth/Envelope.cpp b/src/Synth/Envelope.cpp
@@ -90,7 +90,7 @@ void Envelope::releasekey()
if(keyreleased)
return;
keyreleased = true;
- if(forcedrelease != 0)
+ if(forcedrelease)
t = 0.0f;
}