+ EQ-8, EQ-12: reduce copypasta by using a class template

(cherry picked from commit cf7eaaf5c0c7b9bebf5df24024a1680c35a96702)
This commit is contained in:
Krzysztof Foltman
2009-11-15 18:58:42 +00:00
committed by Tobias Doerffel
parent c3febb507a
commit c84cdb7728
6 changed files with 272 additions and 889 deletions

View File

@@ -26,6 +26,7 @@
#include <pthread.h>
#include <exception>
#include <string>
#include <complex>
#include "primitives.h"
#include "preset.h"
@@ -563,9 +564,37 @@ public:
static const char *impl_get_id() { return id; } \
static const char *impl_get_label() { return label; } \
extern const char *calf_copyright_info;
bool get_freq_gridline(int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context, bool use_frequencies = true);
/// convert amplitude value to normalized grid-ish value (0dB = 0.5, 30dB = 1.0, -30 dB = 0.0, -60dB = -0.5, -90dB = -1.0)
static inline float dB_grid(float amp)
{
return log(amp) * (1.0 / log(256.0)) + 0.4;
}
template<class Fx>
static bool get_graph(Fx &fx, int subindex, float *data, int points)
{
for (int i = 0; i < points; i++)
{
typedef std::complex<double> cfloat;
double freq = 20.0 * pow (20000.0 / 20.0, i * 1.0 / points);
data[i] = dB_grid(fx.freq_gain(subindex, freq, fx.srate));
}
return true;
}
/// convert normalized grid-ish value back to amplitude value
static inline float dB_grid_inv(float pos)
{
return pow(256.0, pos - 0.4);
}
/// set drawing color based on channel index (0 or 1)
void set_channel_color(cairo_iface *context, int channel);
};
#endif

View File

@@ -92,6 +92,12 @@ public:
PLUGIN_NAME_ID_LABEL("multichorus", "multichorus", "Multi Chorus")
};
enum CalfEqMode {
MODE12DB,
MODE24DB,
MODE36DB
};
/// Monosynth - metadata
struct monosynth_metadata: public plugin_metadata<monosynth_metadata>
{
@@ -211,6 +217,7 @@ struct equalizer8band_metadata: public plugin_metadata<equalizer8band_metadata>
param_p3_active, param_p3_level, param_p3_freq, param_p3_q,
param_p4_active, param_p4_level, param_p4_freq, param_p4_q,
param_count };
enum { PeakBands = 4, first_graph_param = param_hp_active, last_graph_param = param_p4_q };
PLUGIN_NAME_ID_LABEL("equalizer8band", "equalizer8band", "Equalizer 8 Band")
};
/// Markus's 12-band EQ - metadata
@@ -232,6 +239,7 @@ struct equalizer12band_metadata: public plugin_metadata<equalizer12band_metadata
param_p7_active, param_p7_level, param_p7_freq, param_p7_q,
param_p8_active, param_p8_level, param_p8_freq, param_p8_q,
param_count };
enum { PeakBands = 8, first_graph_param = param_hp_active, last_graph_param = param_p8_q };
PLUGIN_NAME_ID_LABEL("equalizer12band", "equalizer12band", "Equalizer 12 Band")
};

View File

@@ -37,7 +37,7 @@ namespace calf_plugins {
using namespace dsp;
struct ladspa_plugin_info;
#if 0
class amp_audio_module: public null_audio_module
{
@@ -1038,30 +1038,28 @@ public:
int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline);
};
/// Equalizer 12 Band by Markus Schmidt (based on Krzysztof's filters)
class equalizer12band_audio_module: public audio_module<equalizer12band_metadata>, public frequency_response_line_graph {
/// Equalizer N Band by Markus Schmidt (based on Krzysztof's filters)
template<class BaseClass>
class equalizerNband_audio_module: public audio_module<BaseClass>, public frequency_response_line_graph {
public:
typedef audio_module<BaseClass> AM;
using AM::in_count;
using AM::out_count;
using AM::param_count;
using AM::PeakBands;
private:
enum { graph_param_count = BaseClass::last_graph_param - BaseClass::first_graph_param + 1, params_per_band = AM::param_p2_active - AM::param_p1_active };
float hp_mode_old, hp_freq_old;
float lp_mode_old, lp_freq_old;
float ls_level_old, ls_freq_old;
float hs_level_old, hs_freq_old;
float p_level_old[8], p_freq_old[8], p_q_old[8];
float hp_mode_old1, hp_freq_old1, hp_active_old1;
float lp_mode_old1, lp_freq_old1, lp_active_old1;
float ls_level_old1, ls_freq_old1, ls_active_old1;
float hs_level_old1, hs_freq_old1, hs_active_old1;
float p_level_old1[8], p_freq_old1[8], p_q_old1[8], p_active_old1[8];
enum CalfEqModes {
MODE12DB,
MODE24DB,
MODE36DB
};
CalfEqModes eq_mode, eq_mode_old1[2];
float p_level_old[PeakBands], p_freq_old[PeakBands], p_q_old[PeakBands];
float old_params_for_graph[graph_param_count];
uint32_t clip_inL, clip_outL, clip_inR, clip_outR;
float meter_inL, meter_outL, meter_inR, meter_outR;
biquad_d2<float> hpL[3], hpR[3], lpL[3], lpR[3];
biquad_d2<float> hp[3][2], lp[3][2];
biquad_d2<float> lsL, lsR, hsL, hsR;
biquad_d2<float> pL[8], pR[8];
biquad_d2<float> pL[PeakBands], pR[PeakBands];
public:
typedef std::complex<double> cfloat;
float *ins[in_count];
@@ -1070,149 +1068,23 @@ public:
uint32_t srate;
bool is_active;
volatile int last_generation, last_calculated_generation;
equalizer12band_audio_module();
equalizerNband_audio_module();
void activate();
void deactivate();
void params_changed();
float freq_gain(int index, double freq, uint32_t sr)
float freq_gain(int index, double freq, uint32_t sr);
void set_sample_rate(uint32_t sr)
{
float ret = 1.f;
if(*params[param_hp_active] > 0.f) {
switch((int)*params[param_hp_mode]) {
case MODE12DB:
ret *= hpL[0].freq_gain(freq, sr);
ret *= hpR[0].freq_gain(freq, sr);
break;
case MODE24DB:
ret *= hpL[0].freq_gain(freq, sr) * hpL[0].freq_gain(freq, sr);
ret *= hpR[0].freq_gain(freq, sr) * hpR[0].freq_gain(freq, sr);
break;
case MODE36DB:
ret *= hpL[0].freq_gain(freq, sr) * hpL[0].freq_gain(freq, sr) * hpL[0].freq_gain(freq, sr);
ret *= hpR[0].freq_gain(freq, sr) * hpR[0].freq_gain(freq, sr) * hpR[0].freq_gain(freq, sr);
break;
}
}
if(*params[param_lp_active] > 0.f) {
switch((int)*params[param_lp_mode]) {
case MODE12DB:
ret *= lpL[0].freq_gain(freq, sr);
ret *= lpR[0].freq_gain(freq, sr);
break;
case MODE24DB:
ret *= lpL[0].freq_gain(freq, sr) * lpL[0].freq_gain(freq, sr);
ret *= lpR[0].freq_gain(freq, sr) * lpR[0].freq_gain(freq, sr);
break;
case MODE36DB:
ret *= lpL[0].freq_gain(freq, sr) * lpL[0].freq_gain(freq, sr) * lpL[0].freq_gain(freq, sr);
ret *= lpR[0].freq_gain(freq, sr) * lpR[0].freq_gain(freq, sr) * lpR[0].freq_gain(freq, sr);
break;
}
}
ret *= (*params[param_ls_active] > 0.f) ? lsL.freq_gain(freq, sr) : 1;
ret *= (*params[param_hs_active] > 0.f) ? hsL.freq_gain(freq, sr) : 1;
ret *= (*params[param_p1_active] > 0.f) ? pL[0].freq_gain(freq, sr) : 1;
ret *= (*params[param_p2_active] > 0.f) ? pL[1].freq_gain(freq, sr) : 1;
ret *= (*params[param_p3_active] > 0.f) ? pL[2].freq_gain(freq, sr) : 1;
ret *= (*params[param_p4_active] > 0.f) ? pL[3].freq_gain(freq, sr) : 1;
ret *= (*params[param_p5_active] > 0.f) ? pL[4].freq_gain(freq, sr) : 1;
ret *= (*params[param_p6_active] > 0.f) ? pL[5].freq_gain(freq, sr) : 1;
ret *= (*params[param_p7_active] > 0.f) ? pL[6].freq_gain(freq, sr) : 1;
ret *= (*params[param_p8_active] > 0.f) ? pL[7].freq_gain(freq, sr) : 1;
return ret;
srate = sr;
}
void set_sample_rate(uint32_t sr);
uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask);
bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context);
bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context);
int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline);
};
/// Equalizer 8 Band by Markus Schmidt (based on Krzysztof's filters)
class equalizer8band_audio_module: public audio_module<equalizer8band_metadata>, public frequency_response_line_graph {
private:
float hp_mode_old, hp_freq_old;
float lp_mode_old, lp_freq_old;
float ls_level_old, ls_freq_old;
float hs_level_old, hs_freq_old;
float p_level_old[4], p_freq_old[4], p_q_old[4];
float hp_mode_old1, hp_freq_old1, hp_active_old1;
float lp_mode_old1, lp_freq_old1, lp_active_old1;
float ls_level_old1, ls_freq_old1, ls_active_old1;
float hs_level_old1, hs_freq_old1, hs_active_old1;
float p_level_old1[4], p_freq_old1[4], p_q_old1[4], p_active_old1[4];
enum CalfEqModes {
MODE12DB,
MODE24DB,
MODE36DB
};
CalfEqModes eq_mode, eq_mode_old1[2];
uint32_t clip_inL, clip_outL, clip_inR, clip_outR;
float meter_inL, meter_outL, meter_inR, meter_outR;
biquad_d2<float> hpL[3], hpR[3], lpL[3], lpR[3];
biquad_d2<float> lsL, lsR, hsL, hsR;
biquad_d2<float> pL[4], pR[4];
public:
typedef std::complex<double> cfloat;
float *ins[in_count];
float *outs[out_count];
float *params[param_count];
uint32_t srate;
bool is_active;
volatile int last_generation, last_calculated_generation;
equalizer8band_audio_module();
void activate();
void deactivate();
void params_changed();
float freq_gain(int index, double freq, uint32_t sr)
{
float ret = 1.f;
if(*params[param_hp_active] > 0.f) {
switch((int)*params[param_hp_mode]) {
case MODE12DB:
ret *= hpL[0].freq_gain(freq, sr);
ret *= hpR[0].freq_gain(freq, sr);
break;
case MODE24DB:
ret *= hpL[0].freq_gain(freq, sr) * hpL[0].freq_gain(freq, sr);
ret *= hpR[0].freq_gain(freq, sr) * hpR[0].freq_gain(freq, sr);
break;
case MODE36DB:
ret *= hpL[0].freq_gain(freq, sr) * hpL[0].freq_gain(freq, sr) * hpL[0].freq_gain(freq, sr);
ret *= hpR[0].freq_gain(freq, sr) * hpR[0].freq_gain(freq, sr) * hpR[0].freq_gain(freq, sr);
break;
}
}
if(*params[param_lp_active] > 0.f) {
switch((int)*params[param_lp_mode]) {
case MODE12DB:
ret *= lpL[0].freq_gain(freq, sr);
ret *= lpR[0].freq_gain(freq, sr);
break;
case MODE24DB:
ret *= lpL[0].freq_gain(freq, sr) * lpL[0].freq_gain(freq, sr);
ret *= lpR[0].freq_gain(freq, sr) * lpR[0].freq_gain(freq, sr);
break;
case MODE36DB:
ret *= lpL[0].freq_gain(freq, sr) * lpL[0].freq_gain(freq, sr) * lpL[0].freq_gain(freq, sr);
ret *= lpR[0].freq_gain(freq, sr) * lpR[0].freq_gain(freq, sr) * lpR[0].freq_gain(freq, sr);
break;
}
}
ret *= (*params[param_ls_active] > 0.f) ? lsL.freq_gain(freq, sr) : 1;
ret *= (*params[param_hs_active] > 0.f) ? hsL.freq_gain(freq, sr) : 1;
ret *= (*params[param_p1_active] > 0.f) ? pL[0].freq_gain(freq, sr) : 1;
ret *= (*params[param_p2_active] > 0.f) ? pL[1].freq_gain(freq, sr) : 1;
ret *= (*params[param_p3_active] > 0.f) ? pL[2].freq_gain(freq, sr) : 1;
ret *= (*params[param_p4_active] > 0.f) ? pL[3].freq_gain(freq, sr) : 1;
return ret;
}
void set_sample_rate(uint32_t sr);
uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask);
bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context);
bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context);
int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline);
};
typedef equalizerNband_audio_module<equalizer8band_metadata> equalizer8band_audio_module;
typedef equalizerNband_audio_module<equalizer12band_metadata> equalizer12band_audio_module;
/// Equalizer 5 Band by Markus Schmidt (based on Krzysztof's filters)
class equalizer5band_audio_module: public audio_module<equalizer5band_metadata>, public frequency_response_line_graph {

View File

@@ -21,6 +21,7 @@
#include <assert.h>
#include <memory.h>
#include <calf/giface.h>
#include <calf/osctlnet.h>
#include <stdio.h>
using namespace std;
using namespace calf_utils;
@@ -202,12 +203,10 @@ void calf_plugins::plugin_ctl_iface::clear_preset() {
const char *calf_plugins::load_gui_xml(const std::string &plugin_id)
{
#if 0
try {
return strdup(calf_utils::load_file((std::string(PKGLIBDIR) + "/gui-" + plugin_id + ".xml").c_str()).c_str());
}
catch(file_exception e)
#endif
{
return NULL;
}
@@ -235,6 +234,63 @@ bool calf_plugins::check_for_string_ports(parameter_properties *parameters, int
return false;
}
bool calf_plugins::get_freq_gridline(int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context, bool use_frequencies)
{
if (subindex < 0 )
return false;
if (use_frequencies)
{
if (subindex < 28)
{
vertical = true;
if (subindex == 9) legend = "100 Hz";
if (subindex == 18) legend = "1 kHz";
if (subindex == 27) legend = "10 kHz";
float freq = 100;
if (subindex < 9)
freq = 10 * (subindex + 1);
else if (subindex < 18)
freq = 100 * (subindex - 9 + 1);
else if (subindex < 27)
freq = 1000 * (subindex - 18 + 1);
else
freq = 10000 * (subindex - 27 + 1);
pos = log(freq / 20.0) / log(1000);
if (!legend.empty())
context->set_source_rgba(0, 0, 0, 0.2);
else
context->set_source_rgba(0, 0, 0, 0.1);
return true;
}
subindex -= 28;
}
if (subindex >= 32)
return false;
float gain = 16.0 / (1 << subindex);
pos = dB_grid(gain);
if (pos < -1)
return false;
if (subindex != 4)
context->set_source_rgba(0, 0, 0, subindex & 1 ? 0.1 : 0.2);
if (!(subindex & 1))
{
std::stringstream ss;
ss << (24 - 6 * subindex) << " dB";
legend = ss.str();
}
vertical = false;
return true;
}
void calf_plugins::set_channel_color(cairo_iface *context, int channel)
{
if (channel & 1)
context->set_source_rgba(0.35, 0.4, 0.2, 1);
else
context->set_source_rgba(0.35, 0.4, 0.2, 0.5);
context->set_line_width(1.5);
}
#if USE_DSSI
struct osc_cairo_control: public cairo_iface
{
@@ -322,4 +378,5 @@ calf_plugins::dssi_feedback_sender::~dssi_feedback_sender()
// client->send("/iQuit");
delete client;
}
#endif

View File

@@ -30,7 +30,7 @@
using namespace dsp;
using namespace calf_plugins;
const char *calf_plugins::calf_copyright_info = "(C) 2001-2008 Krzysztof Foltman, license: LGPL";
const char *calf_plugins::calf_copyright_info = "(C) 2001-2009 Krzysztof Foltman, Thor Harald Johanssen, Markus Schmidt and others; license: LGPL";
////////////////////////////////////////////////////////////////////////////

File diff suppressed because it is too large Load Diff