Merge branch 'calf-updates'
* calf-updates:
Reimplement modulation matrix (and tables in general) using configure variables. Slow and most likely incomplete, but a good start.
Add extra checks to detect when param_count != param array size - 1.
Fix another install-related crash, this time due to invalid params in fluidsynth. (cherry picked from commit 034e3a47cd40eb6bb7d221274fda2a5c1c79f42f)
Fix the infamous crash on install. (cherry picked from commit f0568e2f8a4c7d0003cc5a15e300aa2ebb3f93cb)
The range given in the comment wasn't really correct. (cherry picked from commit 292cdaa81dab7e7d948f597041cb86d70dc5ff92)
Use symmetric dB range for EQ plugins.
Fix a few bugs in compilation of limited versions (DSSI without GUI, no JACK host).
Initialise the vintage delay properly... hopefully this time. (cherry picked from commit c96ff1d680148cc877fab3b641d666068eea06aa)
Unbreak Monosynth by changing listview to use a 'key' attribute instead of 'param'.
(cherry picked from commit c562952800)
This commit is contained in:
@@ -222,27 +222,15 @@ struct table_column_info
|
||||
};
|
||||
|
||||
/// 'has string parameters containing tabular data' interface
|
||||
struct table_edit_iface
|
||||
struct table_metadata_iface
|
||||
{
|
||||
/// retrieve the table layout for specific parameter
|
||||
virtual const table_column_info *get_table_columns() const = 0;
|
||||
|
||||
/// return the current number of rows
|
||||
/// return the fixed number of rows, or 0 if the number of rows is variable
|
||||
virtual uint32_t get_table_rows() const = 0;
|
||||
|
||||
/// retrieve data item from the plugin
|
||||
virtual std::string get_cell(int row, int column) const;
|
||||
|
||||
/// set data item to the plugin
|
||||
virtual void set_cell(int row, int column, const std::string &src, std::string &error) { error.clear(); }
|
||||
|
||||
/// return a line graph interface for a specific parameter/column (unused for now)
|
||||
virtual const line_graph_iface *get_graph_iface(int column) const { return NULL; }
|
||||
|
||||
/// return an editor name for a specific grid cell (unused for now - I don't even know how editors be implemented)
|
||||
virtual const char *get_cell_editor(int column) const { return NULL; }
|
||||
|
||||
virtual ~table_edit_iface() {}
|
||||
virtual ~table_metadata_iface() {}
|
||||
};
|
||||
|
||||
/// 'may receive configure variables' interface
|
||||
@@ -331,6 +319,8 @@ struct plugin_metadata_iface
|
||||
virtual bool requires_configure() const = 0;
|
||||
/// obtain array of names of configure variables (or NULL is none needed)
|
||||
virtual const char *const *get_configure_vars() const { return NULL; }
|
||||
/// @return table_metadata_iface if any
|
||||
virtual const table_metadata_iface *get_table_metadata_iface(const char *key) const { return NULL; }
|
||||
|
||||
/// Do-nothing destructor to silence compiler warning
|
||||
virtual ~plugin_metadata_iface() {}
|
||||
@@ -365,8 +355,6 @@ struct plugin_ctl_iface
|
||||
virtual const plugin_metadata_iface *get_metadata_iface() const = 0;
|
||||
/// @return line_graph_iface if any
|
||||
virtual const line_graph_iface *get_line_graph_iface() const = 0;
|
||||
/// @return table_edit_iface if any
|
||||
virtual table_edit_iface *get_table_edit_iface(const char *key) = 0;
|
||||
/// Do-nothing destructor to silence compiler warning
|
||||
virtual ~plugin_ctl_iface() {}
|
||||
};
|
||||
@@ -447,8 +435,6 @@ struct audio_module_iface
|
||||
virtual uint32_t message_run(const void *valid_ports, void *output_ports) = 0;
|
||||
/// @return line_graph_iface if any
|
||||
virtual const line_graph_iface *get_line_graph_iface() const = 0;
|
||||
/// @return table_edit_iface if any for given parameter
|
||||
virtual table_edit_iface *get_table_edit_iface(const char *key) = 0;
|
||||
virtual ~audio_module_iface() {}
|
||||
};
|
||||
|
||||
@@ -548,8 +534,6 @@ public:
|
||||
}
|
||||
/// @return line_graph_iface if any
|
||||
virtual const line_graph_iface *get_line_graph_iface() const { return dynamic_cast<const line_graph_iface *>(this); }
|
||||
virtual table_edit_iface *get_table_edit_iface(const char *key) { const char *key_us = get_table_edit_iface_key(); return (key_us && !strcmp(key, key_us)) ? dynamic_cast<table_edit_iface *>(this) : NULL; }
|
||||
virtual const char *get_table_edit_iface_key() const { return NULL; }
|
||||
};
|
||||
|
||||
#if USE_EXEC_GUI || USE_DSSI
|
||||
@@ -625,7 +609,7 @@ public:
|
||||
};
|
||||
|
||||
#define CALF_PORT_NAMES(name) template<> const char *::plugin_metadata<name##_metadata>::port_names[]
|
||||
#define CALF_PORT_PROPS(name) template<> parameter_properties plugin_metadata<name##_metadata>::param_props[]
|
||||
#define CALF_PORT_PROPS(name) template<> parameter_properties plugin_metadata<name##_metadata>::param_props[name##_metadata::param_count + 1]
|
||||
#define CALF_PLUGIN_INFO(name) template<> calf_plugins::ladspa_plugin_info plugin_metadata<name##_metadata>::plugin_info
|
||||
#define PLUGIN_NAME_ID_LABEL(name, id, label) \
|
||||
static const char *impl_get_name() { return name; } \
|
||||
@@ -634,22 +618,22 @@ public:
|
||||
|
||||
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);
|
||||
bool get_freq_gridline(int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context, bool use_frequencies = true, float res = 256, float ofs = 0.4);
|
||||
|
||||
/// 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)
|
||||
/// convert amplitude value to normalized grid-ish value
|
||||
static inline float dB_grid(float amp, float res = 256, float ofs = 0.4)
|
||||
{
|
||||
return log(amp) * (1.0 / log(256.0)) + 0.4;
|
||||
return log(amp) * (1.0 / log(res)) + ofs;
|
||||
}
|
||||
|
||||
template<class Fx>
|
||||
static bool get_graph(Fx &fx, int subindex, float *data, int points)
|
||||
static bool get_graph(Fx &fx, int subindex, float *data, int points, float res = 256, float ofs = 0.4)
|
||||
{
|
||||
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));
|
||||
data[i] = dB_grid(fx.freq_gain(subindex, freq, fx.srate), res, ofs);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -678,8 +662,46 @@ struct preset_access_iface
|
||||
virtual ~preset_access_iface() {}
|
||||
};
|
||||
|
||||
/// Implementation of table_metadata_iface providing metadata for mod matrices
|
||||
class mod_matrix_metadata: public table_metadata_iface
|
||||
{
|
||||
public:
|
||||
/// Mapping modes
|
||||
enum mapping_mode {
|
||||
map_positive, ///< 0..100%
|
||||
map_bipolar, ///< -100%..100%
|
||||
map_negative, ///< -100%..0%
|
||||
map_squared, ///< x^2
|
||||
map_squared_bipolar, ///< x^2 scaled to -100%..100%
|
||||
map_antisquared, ///< 1-(1-x)^2 scaled to 0..100%
|
||||
map_antisquared_bipolar, ///< 1-(1-x)^2 scaled to -100..100%
|
||||
map_parabola, ///< inverted parabola (peaks at 0.5, then decreases to 0)
|
||||
map_type_count
|
||||
};
|
||||
const char **mod_src_names, **mod_dest_names;
|
||||
|
||||
mod_matrix_metadata(unsigned int _rows, const char **_src_names, const char **_dest_names);
|
||||
virtual const table_column_info *get_table_columns() const;
|
||||
virtual uint32_t get_table_rows() const;
|
||||
|
||||
protected:
|
||||
/// Column descriptions for table widget
|
||||
table_column_info table_columns[6];
|
||||
|
||||
unsigned int matrix_rows;
|
||||
};
|
||||
|
||||
/// Check if a given key is either prefix + rows or prefix + i2s(row) + "," + i2s(column)
|
||||
/// @arg key key to parse
|
||||
/// @arg prefix table prefix (e.g. "modmatrix:")
|
||||
/// @arg is_rows[out] set to true if key == prefix + "rows"
|
||||
/// @arg row[out] if key is of a form: prefix + row + "," + i2s(column), returns row, otherwise returns -1
|
||||
/// @arg column[out] if key is of a form: prefix + row + "," + i2s(column), returns row, otherwise returns -1
|
||||
/// @retval true if this is one of the recognized string forms
|
||||
extern bool parse_table_key(const char *key, const char *prefix, bool &is_rows, int &row, int &column);
|
||||
|
||||
#if USE_EXEC_GUI
|
||||
class table_via_configure: public table_edit_iface
|
||||
class table_via_configure
|
||||
{
|
||||
protected:
|
||||
typedef std::pair<int, int> coord;
|
||||
@@ -689,13 +711,6 @@ protected:
|
||||
public:
|
||||
table_via_configure();
|
||||
void configure(const char *key, const char *value);
|
||||
|
||||
virtual const table_column_info *get_table_columns() const;
|
||||
virtual uint32_t get_table_rows() const;
|
||||
virtual std::string get_cell(int row, int column) const;
|
||||
virtual void set_cell(int row, int column, const std::string &src, std::string &error);
|
||||
virtual const line_graph_iface *get_graph_iface(int column) const;
|
||||
virtual const char *get_cell_editor(int column) const;
|
||||
virtual ~table_via_configure();
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -48,7 +48,6 @@ struct ladspa_instance: public plugin_ctl_iface
|
||||
|
||||
ladspa_instance(audio_module_iface *_module, ladspa_plugin_metadata_set *_ladspa, int sample_rate);
|
||||
virtual const line_graph_iface *get_line_graph_iface() const { return module->get_line_graph_iface(); }
|
||||
virtual table_edit_iface *get_table_edit_iface(const char *key) { return module->get_table_edit_iface(key); }
|
||||
virtual float get_param_value(int param_no);
|
||||
virtual void set_param_value(int param_no, float value);
|
||||
virtual bool activate_preset(int bank, int program);
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include <lv2.h>
|
||||
#include <calf/giface.h>
|
||||
#include <calf/lv2_event.h>
|
||||
#include <calf/lv2_persist.h>
|
||||
#include <calf/lv2_persist2.h>
|
||||
#include <calf/lv2_progress.h>
|
||||
#include <calf/lv2_uri_map.h>
|
||||
#include <string.h>
|
||||
@@ -91,11 +91,15 @@ struct lv2_instance: public plugin_ctl_iface, public progress_report_iface
|
||||
const char *const *vars = module->get_metadata_iface()->get_configure_vars();
|
||||
if (!vars)
|
||||
return;
|
||||
assert(uri_map);
|
||||
uint32_t string_type = uri_map->uri_to_id(uri_map, NULL, "http://lv2plug.in/ns/ext/atom#String");
|
||||
assert(string_type);
|
||||
for (unsigned int i = 0; vars[i]; i++)
|
||||
{
|
||||
size_t len = 0;
|
||||
const void *ptr = (*retrieve)(callback_data, vars[i], &len);
|
||||
if (ptr)
|
||||
uint32_t type = 0;
|
||||
const void *ptr = (*retrieve)(callback_data, vars[i], &len, &type);
|
||||
if (ptr && type == string_type)
|
||||
{
|
||||
printf("Calling configure on %s\n", vars[i]);
|
||||
configure(vars[i], std::string((const char *)ptr, len).c_str());
|
||||
@@ -160,7 +164,6 @@ struct lv2_instance: public plugin_ctl_iface, public progress_report_iface
|
||||
}
|
||||
virtual const plugin_metadata_iface *get_metadata_iface() const { return metadata; }
|
||||
virtual const line_graph_iface *get_line_graph_iface() const { return module->get_line_graph_iface(); }
|
||||
virtual table_edit_iface *get_table_edit_iface(const char *key) { return module->get_table_edit_iface(key); }
|
||||
virtual int send_status_updates(send_updates_iface *sui, int last_serial) { return module->send_status_updates(sui, last_serial); }
|
||||
};
|
||||
|
||||
@@ -297,15 +300,20 @@ struct lv2_wrapper
|
||||
{
|
||||
LV2_Persist_Store_Function store;
|
||||
void *callback_data;
|
||||
uint32_t string_data_type;
|
||||
|
||||
virtual void send_configure(const char *key, const char *value)
|
||||
{
|
||||
(*store)(callback_data, key, value, strlen(value));
|
||||
(*store)(callback_data, key, value, strlen(value) + 1, string_data_type);
|
||||
}
|
||||
};
|
||||
// A host that supports a Persist extension should support an URI map extension as well.
|
||||
assert(inst->uri_map);
|
||||
store_state s;
|
||||
s.store = store;
|
||||
s.callback_data = callback_data;
|
||||
s.string_data_type = inst->uri_map->uri_to_id(inst->uri_map, NULL, "http://lv2plug.in/ns/ext/atom#String");
|
||||
|
||||
inst->send_configures(&s);
|
||||
}
|
||||
static void cb_persist_restore(LV2_Handle Instance, LV2_Persist_Retrieve_Function retrieve, void *callback_data)
|
||||
|
||||
@@ -118,6 +118,7 @@ struct monosynth_metadata: public plugin_metadata<monosynth_metadata>
|
||||
param_count };
|
||||
enum { in_count = 0, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = true, require_midi = true, rt_capable = true };
|
||||
enum { step_size = 64, step_shift = 6 };
|
||||
enum { mod_matrix_slots = 10 };
|
||||
enum {
|
||||
modsrc_none,
|
||||
modsrc_velocity,
|
||||
@@ -143,6 +144,12 @@ struct monosynth_metadata: public plugin_metadata<monosynth_metadata>
|
||||
moddest_count,
|
||||
};
|
||||
PLUGIN_NAME_ID_LABEL("monosynth", "monosynth", "Monosynth")
|
||||
|
||||
mod_matrix_metadata mm_metadata;
|
||||
|
||||
monosynth_metadata();
|
||||
/// Lookup of table edit interface
|
||||
virtual const table_metadata_iface *get_table_metadata_iface(const char *key) const { if (!strcmp(key, "mod_matrix")) return &mm_metadata; else return NULL; }
|
||||
};
|
||||
|
||||
/// Thor's compressor - metadata
|
||||
@@ -348,12 +355,8 @@ struct organ_enums
|
||||
par_bassgain,
|
||||
par_treblefreq,
|
||||
par_treblegain,
|
||||
par_var_mapcurve,
|
||||
param_count
|
||||
};
|
||||
enum {
|
||||
var_count = 1
|
||||
};
|
||||
enum organ_waveform {
|
||||
wave_sine,
|
||||
wave_sinepl1, wave_sinepl2, wave_sinepl3,
|
||||
@@ -412,7 +415,7 @@ public:
|
||||
/// FluidSynth - metadata
|
||||
struct fluidsynth_metadata: public plugin_metadata<fluidsynth_metadata>
|
||||
{
|
||||
enum { par_master, par_interpolation, par_reverb, par_chorus, par_soundfont, par_preset_key_set, param_count };
|
||||
enum { par_master, par_interpolation, par_reverb, par_chorus, param_count };
|
||||
enum { in_count = 0, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = true, require_midi = true, rt_capable = false };
|
||||
PLUGIN_NAME_ID_LABEL("fluidsynth", "fluidsynth", "Fluidsynth")
|
||||
|
||||
@@ -486,8 +489,14 @@ struct wavetable_metadata: public plugin_metadata<wavetable_metadata>
|
||||
par_pwhlrange,
|
||||
param_count };
|
||||
enum { in_count = 0, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = true, require_midi = true, rt_capable = true };
|
||||
enum { mod_matrix_slots = 10 };
|
||||
enum { step_size = 64 };
|
||||
PLUGIN_NAME_ID_LABEL("wavetable", "wavetable", "Wavetable")
|
||||
mod_matrix_metadata mm_metadata;
|
||||
|
||||
wavetable_metadata();
|
||||
/// Lookup of table edit interface
|
||||
virtual const table_metadata_iface *get_table_metadata_iface(const char *key) const { if (!strcmp(key, "mod_matrix")) return &mm_metadata; else return NULL; }
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
@@ -25,26 +25,13 @@
|
||||
|
||||
namespace dsp {
|
||||
|
||||
/// Mapping modes
|
||||
enum mapping_mode {
|
||||
map_positive, ///< 0..100%
|
||||
map_bipolar, ///< -100%..100%
|
||||
map_negative, ///< -100%..0%
|
||||
map_squared, ///< x^2
|
||||
map_squared_bipolar, ///< x^2 scaled to -100%..100%
|
||||
map_antisquared, ///< 1-(1-x)^2 scaled to 0..100%
|
||||
map_antisquared_bipolar, ///< 1-(1-x)^2 scaled to -100..100%
|
||||
map_parabola, ///< inverted parabola (peaks at 0.5, then decreases to 0)
|
||||
map_type_count
|
||||
};
|
||||
|
||||
/// Single entry in modulation matrix
|
||||
struct modulation_entry
|
||||
{
|
||||
/// Mapped source
|
||||
int src1;
|
||||
/// Source mapping mode
|
||||
mapping_mode mapping;
|
||||
calf_plugins::mod_matrix_metadata::mapping_mode mapping;
|
||||
/// Unmapped modulating source
|
||||
int src2;
|
||||
/// Modulation amount
|
||||
@@ -60,7 +47,7 @@ struct modulation_entry
|
||||
void reset() {
|
||||
src1 = 0;
|
||||
src2 = 0;
|
||||
mapping = map_positive;
|
||||
mapping = calf_plugins::mod_matrix_metadata::map_positive;
|
||||
amount = 0.f;
|
||||
dest = 0;
|
||||
}
|
||||
@@ -70,24 +57,17 @@ struct modulation_entry
|
||||
|
||||
namespace calf_plugins {
|
||||
|
||||
class mod_matrix: public table_edit_iface
|
||||
class mod_matrix_impl
|
||||
{
|
||||
protected:
|
||||
/// Polynomials for different scaling modes (1, x, x^2)
|
||||
static const float scaling_coeffs[dsp::map_type_count][3];
|
||||
/// Column descriptions for table widget
|
||||
table_column_info table_columns[6];
|
||||
|
||||
dsp::modulation_entry *matrix;
|
||||
mod_matrix_metadata *metadata;
|
||||
unsigned int matrix_rows;
|
||||
const char **mod_src_names, **mod_dest_names;
|
||||
/// Polynomials for different scaling modes (1, x, x^2)
|
||||
static const float scaling_coeffs[calf_plugins::mod_matrix_metadata::map_type_count][3];
|
||||
|
||||
mod_matrix(dsp::modulation_entry *_matrix, unsigned int _rows, const char **_src_names, const char **_dest_names);
|
||||
public:
|
||||
virtual const table_column_info *get_table_columns() const;
|
||||
virtual uint32_t get_table_rows() const;
|
||||
virtual std::string get_cell(int row, int column) const;
|
||||
virtual void set_cell(int row, int column, const std::string &src, std::string &error);
|
||||
mod_matrix_impl(dsp::modulation_entry *_matrix, calf_plugins::mod_matrix_metadata *_metadata);
|
||||
|
||||
/// Process modulation matrix, calculate outputs from inputs
|
||||
inline void calculate_modmatrix(float *moddest, int moddest_count, float *modsrc)
|
||||
@@ -105,8 +85,14 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
void send_configures(send_configure_iface *);
|
||||
char *configure(const char *key, const char *value);
|
||||
|
||||
private:
|
||||
std::string get_cell(int row, int column) const;
|
||||
void set_cell(int row, int column, const std::string &src, std::string &error);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -37,10 +37,9 @@ namespace calf_plugins {
|
||||
|
||||
/// Monosynth-in-making. Parameters may change at any point, so don't make songs with it!
|
||||
/// It lacks inertia for parameters, even for those that really need it.
|
||||
class monosynth_audio_module: public audio_module<monosynth_metadata>, public line_graph_iface, public mod_matrix
|
||||
class monosynth_audio_module: public audio_module<monosynth_metadata>, public line_graph_iface, public mod_matrix_impl
|
||||
{
|
||||
public:
|
||||
enum { mod_matrix_slots = 10 };
|
||||
uint32_t srate, crate;
|
||||
static dsp::waveform_family<MONOSYNTH_WAVE_BITS> *waves;
|
||||
dsp::waveform_oscillator<MONOSYNTH_WAVE_BITS> osc1, osc2;
|
||||
@@ -178,6 +177,9 @@ public:
|
||||
void apply_fadeout();
|
||||
/// Main processing function
|
||||
uint32_t process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask);
|
||||
/// Send all configure variables set within a plugin to given destination (which may be limited to only those that plugin understands)
|
||||
virtual void send_configures(send_configure_iface *sci) { return mod_matrix_impl::send_configures(sci); }
|
||||
virtual char *configure(const char *key, const char *value) { return mod_matrix_impl::configure(key, value); }
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
164
plugins/ladspa_effect/calf/src/calf/wavetable.h
Normal file
164
plugins/ladspa_effect/calf/src/calf/wavetable.h
Normal file
@@ -0,0 +1,164 @@
|
||||
#ifndef __CALF_WAVETABLE_H
|
||||
#define __CALF_WAVETABLE_H
|
||||
|
||||
#include <assert.h>
|
||||
#include "biquad.h"
|
||||
#include "onepole.h"
|
||||
#include "audio_fx.h"
|
||||
#include "inertia.h"
|
||||
#include "osc.h"
|
||||
#include "synth.h"
|
||||
#include "envelope.h"
|
||||
#include "modmatrix.h"
|
||||
|
||||
namespace calf_plugins {
|
||||
|
||||
#define WAVETABLE_WAVE_BITS 8
|
||||
|
||||
class wavetable_audio_module;
|
||||
|
||||
struct wavetable_oscillator: public dsp::simple_oscillator
|
||||
{
|
||||
enum { SIZE = 1 << 8, MASK = SIZE - 1, SCALE = 1 << (32 - 8) };
|
||||
int16_t (*tables)[256];
|
||||
inline float get(uint16_t slice)
|
||||
{
|
||||
float fracslice = (slice & 255) * (1.0 / 256.0);
|
||||
slice = slice >> 8;
|
||||
int16_t *waveform = tables[slice];
|
||||
int16_t *waveform2 = tables[slice + 1];
|
||||
float value1 = 0.f, value2 = 0.f;
|
||||
uint32_t cphase = phase, cphasedelta = phasedelta >> 3;
|
||||
for (int j = 0; j < 8; j++)
|
||||
{
|
||||
uint32_t wpos = cphase >> (32 - 8);
|
||||
uint32_t wpos2 = (wpos + 1) & MASK;
|
||||
float frac = (cphase & (SCALE - 1)) * (1.0f / SCALE);
|
||||
value1 += dsp::lerp((float)waveform[wpos], (float)waveform[wpos2], frac);
|
||||
value2 += dsp::lerp((float)waveform2[wpos], (float)waveform2[wpos2], frac);
|
||||
cphase += cphasedelta;
|
||||
}
|
||||
phase += phasedelta;
|
||||
return dsp::lerp(value1, value2, fracslice) * (1.0 / 8.0) * (1.0 / 32768.0);;
|
||||
}
|
||||
};
|
||||
|
||||
class wavetable_voice: public dsp::voice
|
||||
{
|
||||
public:
|
||||
enum { Channels = 2, BlockSize = 64, EnvCount = 3, OscCount = 2 };
|
||||
float output_buffer[BlockSize][Channels];
|
||||
protected:
|
||||
int note;
|
||||
wavetable_audio_module *parent;
|
||||
float **params;
|
||||
dsp::decay amp;
|
||||
wavetable_oscillator oscs[OscCount];
|
||||
dsp::adsr envs[EnvCount];
|
||||
/// Current MIDI velocity
|
||||
float velocity;
|
||||
/// Current calculated mod matrix outputs
|
||||
float moddest[wavetable_metadata::moddest_count];
|
||||
/// Last oscillator shift (wavetable index) of each oscillator
|
||||
float last_oscshift[OscCount];
|
||||
/// Last oscillator amplitude of each oscillator
|
||||
float last_oscamp[OscCount];
|
||||
/// Current osc amplitude
|
||||
float cur_oscamp[OscCount];
|
||||
public:
|
||||
wavetable_voice();
|
||||
void set_params_ptr(wavetable_audio_module *_parent, int _srate);
|
||||
void reset();
|
||||
void note_on(int note, int vel);
|
||||
void note_off(int /* vel */);
|
||||
void channel_pressure(int value);
|
||||
void steal();
|
||||
void render_block();
|
||||
virtual int get_current_note() {
|
||||
return note;
|
||||
}
|
||||
virtual bool get_active() {
|
||||
// printf("note %d getactive %d use_percussion %d pamp active %d\n", note, amp.get_active(), use_percussion(), pamp.get_active());
|
||||
return (note != -1) && (amp.get_active()) && !envs[0].stopped();
|
||||
}
|
||||
inline void calc_derived_dests() {
|
||||
float cv = dsp::clip<float>(0.5f + moddest[wavetable_metadata::moddest_oscmix], 0.f, 1.f);
|
||||
cur_oscamp[0] = (cv) * *params[wavetable_metadata::par_o1level];
|
||||
cur_oscamp[1] = (1 - cv) * *params[wavetable_metadata::par_o2level];
|
||||
}
|
||||
};
|
||||
|
||||
class wavetable_audio_module: public audio_module<wavetable_metadata>, public dsp::basic_synth, public mod_matrix_impl
|
||||
{
|
||||
public:
|
||||
using dsp::basic_synth::note_on;
|
||||
using dsp::basic_synth::note_off;
|
||||
using dsp::basic_synth::control_change;
|
||||
using dsp::basic_synth::pitch_bend;
|
||||
|
||||
protected:
|
||||
uint32_t crate;
|
||||
bool panic_flag;
|
||||
|
||||
public:
|
||||
int16_t tables[wt_count][129][256]; // one dummy level for interpolation
|
||||
/// Rows of the modulation matrix
|
||||
dsp::modulation_entry mod_matrix_data[mod_matrix_slots];
|
||||
/// Smoothed cutoff value
|
||||
dsp::inertia<dsp::exponential_ramp> inertia_cutoff;
|
||||
/// Smoothed pitch bend value
|
||||
dsp::inertia<dsp::exponential_ramp> inertia_pitchbend;
|
||||
/// Smoothed channel pressure value
|
||||
dsp::inertia<dsp::linear_ramp> inertia_pressure;
|
||||
/// Unsmoothed mod wheel value
|
||||
float modwheel_value;
|
||||
|
||||
public:
|
||||
wavetable_audio_module();
|
||||
|
||||
dsp::voice *alloc_voice() {
|
||||
dsp::block_voice<wavetable_voice> *v = new dsp::block_voice<wavetable_voice>();
|
||||
v->set_params_ptr(this, sample_rate);
|
||||
return v;
|
||||
}
|
||||
|
||||
/// process function copied from Organ (will probably need some adjustments as well as implementing the panic flag elsewhere
|
||||
uint32_t process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
|
||||
float *o[2] = { outs[0] + offset, outs[1] + offset };
|
||||
if (panic_flag)
|
||||
{
|
||||
control_change(120, 0); // stop all sounds
|
||||
control_change(121, 0); // reset all controllers
|
||||
panic_flag = false;
|
||||
}
|
||||
float buf[4096][2];
|
||||
dsp::zero(&buf[0][0], 2 * nsamples);
|
||||
basic_synth::render_to(buf, nsamples);
|
||||
float gain = 1.0f;
|
||||
for (uint32_t i=0; i<nsamples; i++) {
|
||||
o[0][i] = gain*buf[i][0];
|
||||
o[1][i] = gain*buf[i][1];
|
||||
}
|
||||
return 3;
|
||||
}
|
||||
|
||||
void set_sample_rate(uint32_t sr) {
|
||||
setup(sr);
|
||||
crate = sample_rate / wavetable_voice::BlockSize;
|
||||
inertia_cutoff.ramp.set_length(crate / 30); // 1/30s
|
||||
inertia_pitchbend.ramp.set_length(crate / 30); // 1/30s
|
||||
inertia_pressure.ramp.set_length(crate / 30); // 1/30s - XXXKF monosynth needs that too
|
||||
}
|
||||
/// Handle MIDI Channel Pressure
|
||||
void channel_pressure(int value);
|
||||
/// Handle pitch bend message.
|
||||
inline void pitch_bend(int value)
|
||||
{
|
||||
inertia_pitchbend.set_inertia(pow(2.0, (value * *params[par_pwhlrange]) / (1200.0 * 8192.0)));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -214,7 +214,7 @@ const char *calf_plugins::load_gui_xml(const std::string &plugin_id)
|
||||
}
|
||||
}
|
||||
|
||||
bool calf_plugins::get_freq_gridline(int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context, bool use_frequencies)
|
||||
bool calf_plugins::get_freq_gridline(int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context, bool use_frequencies, float res, float ofs)
|
||||
{
|
||||
if (subindex < 0 )
|
||||
return false;
|
||||
@@ -247,7 +247,7 @@ bool calf_plugins::get_freq_gridline(int subindex, float &pos, bool &vertical, s
|
||||
if (subindex >= 32)
|
||||
return false;
|
||||
float gain = 16.0 / (1 << subindex);
|
||||
pos = dB_grid(gain);
|
||||
pos = dB_grid(gain, res, ofs);
|
||||
if (pos < -1)
|
||||
return false;
|
||||
if (subindex != 4)
|
||||
@@ -319,11 +319,67 @@ const plugin_metadata_iface *calf_plugins::plugin_registry::get_by_id(const char
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string table_edit_iface::get_cell(int row, int column) const
|
||||
bool calf_plugins::parse_table_key(const char *key, const char *prefix, bool &is_rows, int &row, int &column)
|
||||
{
|
||||
return calf_utils::i2s(row)+":"+calf_utils::i2s(column);
|
||||
is_rows = false;
|
||||
row = -1;
|
||||
column = -1;
|
||||
if (0 != strncmp(key, prefix, strlen(prefix)))
|
||||
return false;
|
||||
|
||||
key += strlen(prefix);
|
||||
|
||||
if (!strcmp(key, "rows"))
|
||||
{
|
||||
is_rows = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
const char *comma = strchr(key, ',');
|
||||
if (comma)
|
||||
{
|
||||
row = atoi(string(key, comma - key).c_str());
|
||||
column = atoi(comma + 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
printf("Unknown key %s under prefix %s", key, prefix);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const char *mod_mapping_names[] = { "0..1", "-1..1", "-1..0", "x^2", "2x^2-1", "ASqr", "ASqrBip", "Para", NULL };
|
||||
|
||||
mod_matrix_metadata::mod_matrix_metadata(unsigned int _rows, const char **_src_names, const char **_dest_names)
|
||||
: mod_src_names(_src_names)
|
||||
, mod_dest_names(_dest_names)
|
||||
, matrix_rows(_rows)
|
||||
{
|
||||
table_column_info tci[6] = {
|
||||
{ "Source", TCT_ENUM, 0, 0, 0, mod_src_names },
|
||||
{ "Mapping", TCT_ENUM, 0, 0, 0, mod_mapping_names },
|
||||
{ "Modulator", TCT_ENUM, 0, 0, 0, mod_src_names },
|
||||
{ "Amount", TCT_FLOAT, 0, 1, 1, NULL},
|
||||
{ "Destination", TCT_ENUM, 0, 0, 0, mod_dest_names },
|
||||
{ NULL }
|
||||
};
|
||||
assert(sizeof(table_columns) == sizeof(tci));
|
||||
memcpy(table_columns, tci, sizeof(table_columns));
|
||||
}
|
||||
|
||||
const table_column_info *mod_matrix_metadata::get_table_columns() const
|
||||
{
|
||||
return table_columns;
|
||||
}
|
||||
|
||||
uint32_t mod_matrix_metadata::get_table_rows() const
|
||||
{
|
||||
return matrix_rows;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -435,45 +491,6 @@ table_via_configure::table_via_configure()
|
||||
rows = 0;
|
||||
}
|
||||
|
||||
const table_column_info *table_via_configure::get_table_columns() const
|
||||
{
|
||||
return &columns[0];
|
||||
}
|
||||
|
||||
uint32_t table_via_configure::get_table_rows() const
|
||||
{
|
||||
return rows;
|
||||
}
|
||||
|
||||
string table_via_configure::get_cell(int row, int column) const
|
||||
{
|
||||
if (row >= rows)
|
||||
return string();
|
||||
coord c = make_pair(row, column);
|
||||
std::map<coord, std::string>::const_iterator i = values.find(c);
|
||||
if (i == values.end())
|
||||
return std::string();
|
||||
else
|
||||
return i->second;
|
||||
}
|
||||
|
||||
void table_via_configure::set_cell(int row, int column, const std::string &src, std::string &error)
|
||||
{
|
||||
coord c = make_pair(row, column);
|
||||
values[c] = src;
|
||||
error = "";
|
||||
}
|
||||
|
||||
const line_graph_iface *table_via_configure::get_graph_iface(int column) const
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *table_via_configure::get_cell_editor(int column) const
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
table_via_configure::~table_via_configure()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ CALF_PORT_PROPS(flanger) = {
|
||||
{ 0, 0, 1, 2, PF_BOOL | PF_CTL_BUTTON , NULL, "reset", "Reset" },
|
||||
{ 1, 0, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "amount", "Amount" },
|
||||
{ 1.0, 0, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "dry", "Dry Amount" },
|
||||
{}
|
||||
};
|
||||
|
||||
CALF_PLUGIN_INFO(flanger) = { 0x847d, "Flanger", "Calf Flanger", "Krzysztof Foltman", calf_plugins::calf_copyright_info, "FlangerPlugin" };
|
||||
@@ -82,6 +83,7 @@ CALF_PORT_PROPS(reverb) = {
|
||||
{ 0, 0, 50, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "predelay", "Pre Delay" },
|
||||
{ 300, 20, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "bass_cut", "Bass Cut" },
|
||||
{ 5000, 20, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "treble_cut", "Treble Cut" },
|
||||
{}
|
||||
};
|
||||
|
||||
CALF_PLUGIN_INFO(reverb) = { 0x847e, "Reverb", "Calf Reverb", "Krzysztof Foltman", calf_plugins::calf_copyright_info, "ReverbPlugin" };
|
||||
@@ -129,7 +131,8 @@ CALF_PORT_PROPS(filterclavier) = {
|
||||
biquad_filter_module::mode_12db_lp,
|
||||
biquad_filter_module::mode_count - 1,
|
||||
1, PF_ENUM | PF_CTL_COMBO | PF_PROP_GRAPH, filter_choices, "mode", "Mode" },
|
||||
{ 20, 1, 2000, 20, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "inertia", "Portamento time"}
|
||||
{ 20, 1, 2000, 20, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "inertia", "Portamento time"},
|
||||
{}
|
||||
};
|
||||
|
||||
CALF_PLUGIN_INFO(filterclavier) = { 0x849f, "Filterclavier", "Calf Filterclavier", "Krzysztof Foltman / Hans Baier", calf_plugins::calf_copyright_info, "FilterclavierPlugin" };
|
||||
@@ -162,6 +165,7 @@ CALF_PORT_PROPS(vintage_delay) = {
|
||||
{ 1, 0, 2, 0, PF_ENUM | PF_CTL_COMBO, vintage_delay_fbmodes, "medium", "Medium" },
|
||||
{ 1.0, 0, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "dry", "Dry Amount" },
|
||||
{ 1.0, -1, 1, 0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB , NULL, "width", "Stereo Width" },
|
||||
{}
|
||||
};
|
||||
|
||||
CALF_PLUGIN_INFO(vintage_delay) = { 0x8482, "VintageDelay", "Calf Vintage Delay", "Krzysztof Foltman", calf_plugins::calf_copyright_info, "DelayPlugin" };
|
||||
@@ -183,6 +187,7 @@ CALF_PORT_PROPS(rotary_speaker) = {
|
||||
{ 0.3, 0, 1, 101, PF_FLOAT | PF_CTL_KNOB | PF_SCALE_PERC, NULL, "reflection", "Reflection" },
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_l", "Low rotor" },
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_h", "High rotor" },
|
||||
{}
|
||||
};
|
||||
|
||||
CALF_PLUGIN_INFO(rotary_speaker) = { 0x8483, "RotarySpeaker", "Calf Rotary Speaker", "Krzysztof Foltman", calf_plugins::calf_copyright_info, "SimulatorPlugin" };
|
||||
@@ -231,6 +236,7 @@ CALF_PORT_PROPS(compressor) = {
|
||||
{ 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, compressor_detection_names, "detection", "Detection" },
|
||||
{ 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, compressor_stereo_link_names, "stereo_link", "Stereo Link" },
|
||||
{ 0, 0.03125, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "compression", "Reduction" },
|
||||
{}
|
||||
};
|
||||
|
||||
CALF_PLUGIN_INFO(compressor) = { 0x8502, "Compressor", "Calf Compressor", "Thor Harald Johansen", calf_plugins::calf_copyright_info, "CompressorPlugin" };
|
||||
@@ -278,6 +284,7 @@ CALF_PORT_PROPS(sidechaincompressor) = {
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "sc_listen", "S/C-Listen" },
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "f1_active", "F1 Active" },
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "f2_active", "F2 Active" },
|
||||
{}
|
||||
};
|
||||
|
||||
CALF_PLUGIN_INFO(sidechaincompressor) = { 0x8517, "Sidechaincompressor", "Calf Sidechain Compressor", "Markus Schmidt / Thor Harald Johansen", calf_plugins::calf_copyright_info, "CompressorPlugin" };
|
||||
@@ -364,6 +371,7 @@ CALF_PORT_PROPS(multibandcompressor) = {
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "output3", "Output 4" },
|
||||
{ 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass3", "Bypass 4" },
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "mute3", "Mute 4" },
|
||||
{}
|
||||
};
|
||||
|
||||
CALF_PLUGIN_INFO(multibandcompressor) = { 0x8516, "Multibandcompressor", "Calf Multiband Compressor", "Markus Schmidt / Thor Harald Johansen", calf_plugins::calf_copyright_info, "CompressorPlugin" };
|
||||
@@ -395,6 +403,7 @@ CALF_PORT_PROPS(deesser) = {
|
||||
{ 4, 0.0625, 16, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "f2_level", "Level" },
|
||||
{ 1, 0.1, 100,1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "f2_q", "Peak Q" },
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "sc_listen", "S/C-Listen" },
|
||||
{}
|
||||
};
|
||||
|
||||
CALF_PLUGIN_INFO(deesser) = { 0x8515, "Deesser", "Calf Deesser", "Markus Schmidt / Thor Harald Johansen", calf_plugins::calf_copyright_info, "CompressorPlugin" };
|
||||
@@ -423,6 +432,7 @@ CALF_PORT_PROPS(gate) = {
|
||||
{ 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, gate_detection_names, "detection", "Detection" },
|
||||
{ 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, gate_stereo_link_names, "stereo_link", "Stereo Link" },
|
||||
{ 0, 0.03125, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "gating", "Gating" },
|
||||
{}
|
||||
};
|
||||
|
||||
CALF_PLUGIN_INFO(gate) = { 0x8503, "Gate", "Calf Gate", "Damien Zammit / Thor Harald Johansen", calf_plugins::calf_copyright_info, "ExpanderPlugin" };
|
||||
@@ -471,6 +481,7 @@ CALF_PORT_PROPS(sidechaingate) = {
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "sc_listen", "S/C-Listen" },
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "f1_active", "F1 Active" },
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "f2_active", "F2 Active" },
|
||||
{}
|
||||
};
|
||||
|
||||
CALF_PLUGIN_INFO(sidechaingate) = { 0x8504, "Sidechaingate", "Calf Sidechain Gate", "Markus Schmidt / Damien Zammit / Thor Harald Johansen", calf_plugins::calf_copyright_info, "ExpanderPlugin" };
|
||||
@@ -527,6 +538,7 @@ CALF_PORT_PROPS(equalizer5band) = {
|
||||
EQ_BAND_PARAMS(1, 250)
|
||||
EQ_BAND_PARAMS(2, 1000)
|
||||
EQ_BAND_PARAMS(3, 2500)
|
||||
{}
|
||||
};
|
||||
|
||||
CALF_PLUGIN_INFO(equalizer5band) = { 0x8511, "Equalizer5Band", "Calf Equalizer 5 Band", "Markus Schmidt", calf_plugins::calf_copyright_info, "EqualizerPlugin" };
|
||||
@@ -546,6 +558,7 @@ CALF_PORT_PROPS(equalizer8band) = {
|
||||
EQ_BAND_PARAMS(2, 1000)
|
||||
EQ_BAND_PARAMS(3, 2500)
|
||||
EQ_BAND_PARAMS(4, 5000)
|
||||
{}
|
||||
};
|
||||
|
||||
CALF_PLUGIN_INFO(equalizer8band) = { 0x8512, "Equalizer8Band", "Calf Equalizer 8 Band", "Markus Schmidt", calf_plugins::calf_copyright_info, "EqualizerPlugin" };
|
||||
@@ -567,6 +580,7 @@ CALF_PORT_PROPS(equalizer12band) = {
|
||||
EQ_BAND_PARAMS(6, 2500)
|
||||
EQ_BAND_PARAMS(7, 4000)
|
||||
EQ_BAND_PARAMS(8, 6000)
|
||||
{}
|
||||
};
|
||||
|
||||
CALF_PLUGIN_INFO(equalizer12band) = { 0x8513, "Equalizer12Band", "Calf Equalizer 12 Band", "Markus Schmidt", calf_plugins::calf_copyright_info, "EqualizerPlugin" };
|
||||
@@ -586,6 +600,7 @@ CALF_PORT_PROPS(pulsator) = {
|
||||
{ 0.5, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "offset", "Offset L/R" },
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "mono", "Mono-in" },
|
||||
{ 0, 0, 1, 2, PF_BOOL | PF_CTL_BUTTON , NULL, "reset", "Reset" },
|
||||
{}
|
||||
};
|
||||
|
||||
CALF_PLUGIN_INFO(pulsator) = { 0x8514, "Pulsator", "Calf Pulsator", "Markus Schmidt", calf_plugins::calf_copyright_info, "ModulationPlugin" };
|
||||
@@ -617,6 +632,7 @@ CALF_PORT_PROPS(saturator) = {
|
||||
{ 2000, 80, 8000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "p_freq", "Tone" },
|
||||
{ 1, 0.0625, 16, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "p_level", "Amount" },
|
||||
{ 1, 0.1, 10, 1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "p_q", "Gradient" },
|
||||
{}
|
||||
};
|
||||
|
||||
CALF_PLUGIN_INFO(saturator) = { 0x8530, "Saturator", "Calf Saturator", "Markus Schmidt / Krzysztof Foltman", calf_plugins::calf_copyright_info, "DistortionPlugin" };
|
||||
@@ -641,6 +657,7 @@ CALF_PORT_PROPS(exciter) = {
|
||||
|
||||
{ 6000, 2000, 12000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "freq", "Scope" },
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "listen", "Listen" },
|
||||
{}
|
||||
};
|
||||
|
||||
CALF_PLUGIN_INFO(exciter) = { 0x8531, "Exciter", "Calf Exciter", "Markus Schmidt / Krzysztof Foltman", calf_plugins::calf_copyright_info, "DistortionPlugin" };
|
||||
@@ -665,6 +682,7 @@ CALF_PORT_PROPS(bassenhancer) = {
|
||||
|
||||
{ 120, 10, 250, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "freq", "Scope" },
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "listen", "Listen" },
|
||||
{}
|
||||
};
|
||||
|
||||
CALF_PLUGIN_INFO(bassenhancer) = { 0x8532, "BassEnhancer", "Calf Bass Enhancer", "Markus Schmidt / Krzysztof Foltman", calf_plugins::calf_copyright_info, "DistortionPlugin" };
|
||||
@@ -756,8 +774,40 @@ CALF_PORT_PROPS(monosynth) = {
|
||||
{ 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, monosynth_lfotrig_names, "lfo2_trig", "LFO2 Trigger Mode" },
|
||||
{ 5, 0.01, 20, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "lfo2_rate", "LFO1 Rate" },
|
||||
{ 0.5, 0.1, 5, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_SEC, NULL, "lfo2_delay", "LFO1 Delay" },
|
||||
{}
|
||||
};
|
||||
|
||||
static const char *monosynth_mod_src_names[] = {
|
||||
"None",
|
||||
"Velocity",
|
||||
"Pressure",
|
||||
"ModWheel",
|
||||
"Envelope 1",
|
||||
"Envelope 2",
|
||||
"LFO 1",
|
||||
"LFO 2",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *monosynth_mod_dest_names[] = {
|
||||
"None",
|
||||
"Attenuation",
|
||||
"Osc Mix Ratio (%)",
|
||||
"Cutoff [ct]",
|
||||
"Resonance",
|
||||
"O1: Detune [ct]",
|
||||
"O2: Detune [ct]",
|
||||
"O1: PW (%)",
|
||||
"O2: PW (%)",
|
||||
"O1: Stretch",
|
||||
NULL
|
||||
};
|
||||
|
||||
monosynth_metadata::monosynth_metadata()
|
||||
: mm_metadata(mod_matrix_slots, monosynth_mod_src_names, monosynth_mod_dest_names)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CALF_PLUGIN_INFO(organ) = { 0x8481, "Organ", "Calf Organ", "Krzysztof Foltman", calf_plugins::calf_copyright_info, "SynthesizerPlugin" };
|
||||
@@ -1018,7 +1068,29 @@ const char *wavetable_names[] = {
|
||||
"Multi 2",
|
||||
};
|
||||
|
||||
const char *wavetable_init_soundfont = "";
|
||||
static const char *wavetable_mod_src_names[] = {
|
||||
"None",
|
||||
"Velocity",
|
||||
"Pressure",
|
||||
"ModWheel",
|
||||
"Env 1",
|
||||
"Env 2",
|
||||
"Env 3",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *wavetable_mod_dest_names[] = {
|
||||
"None",
|
||||
"Attenuation",
|
||||
"Osc Mix Ratio (%)",
|
||||
"Cutoff [ct]",
|
||||
"Resonance",
|
||||
"O1: Shift (%)",
|
||||
"O2: Shift (%)",
|
||||
"O1: Detune [ct]",
|
||||
"O2: Detune [ct]",
|
||||
NULL
|
||||
};
|
||||
|
||||
CALF_PORT_NAMES(wavetable) = {
|
||||
"Out L", "Out R",
|
||||
@@ -1061,8 +1133,14 @@ CALF_PORT_PROPS(wavetable) = {
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "adsr3_v", "EG3 VelMod" },
|
||||
|
||||
{ 200, 0, 2400, 25, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "pbend_range", "PBend Range" },
|
||||
{}
|
||||
};
|
||||
|
||||
wavetable_metadata::wavetable_metadata()
|
||||
: mm_metadata(mod_matrix_slots, wavetable_mod_src_names, wavetable_mod_dest_names)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
calf_plugins::plugin_registry::plugin_registry()
|
||||
|
||||
@@ -26,10 +26,18 @@
|
||||
using namespace std;
|
||||
using namespace dsp;
|
||||
using namespace calf_plugins;
|
||||
using namespace calf_utils;
|
||||
|
||||
const char *mod_mapping_names[] = { "0..1", "-1..1", "-1..0", "x^2", "2x^2-1", "ASqr", "ASqrBip", "Para", NULL };
|
||||
mod_matrix_impl::mod_matrix_impl(dsp::modulation_entry *_matrix, mod_matrix_metadata *_metadata)
|
||||
: matrix(_matrix)
|
||||
, metadata(_metadata)
|
||||
{
|
||||
matrix_rows = metadata->get_table_rows();
|
||||
for (unsigned int i = 0; i < matrix_rows; i++)
|
||||
matrix[i].reset();
|
||||
}
|
||||
|
||||
const float mod_matrix::scaling_coeffs[dsp::map_type_count][3] = {
|
||||
const float mod_matrix_impl::scaling_coeffs[mod_matrix_metadata::map_type_count][3] = {
|
||||
{ 0, 1, 0 },
|
||||
{ -1, 2, 0 },
|
||||
{ -1, 1, 0 },
|
||||
@@ -40,66 +48,33 @@ const float mod_matrix::scaling_coeffs[dsp::map_type_count][3] = {
|
||||
{ 0, 4, -4 },
|
||||
};
|
||||
|
||||
mod_matrix::mod_matrix(modulation_entry *_matrix, unsigned int _rows, const char **_src_names, const char **_dest_names)
|
||||
: matrix(_matrix)
|
||||
, matrix_rows(_rows)
|
||||
, mod_src_names(_src_names)
|
||||
, mod_dest_names(_dest_names)
|
||||
{
|
||||
table_column_info tci[6] = {
|
||||
{ "Source", TCT_ENUM, 0, 0, 0, mod_src_names },
|
||||
{ "Mapping", TCT_ENUM, 0, 0, 0, mod_mapping_names },
|
||||
{ "Modulator", TCT_ENUM, 0, 0, 0, mod_src_names },
|
||||
{ "Amount", TCT_FLOAT, 0, 1, 1, NULL},
|
||||
{ "Destination", TCT_ENUM, 0, 0, 0, mod_dest_names },
|
||||
{ NULL }
|
||||
};
|
||||
assert(sizeof(table_columns) == sizeof(tci));
|
||||
memcpy(table_columns, tci, sizeof(table_columns));
|
||||
for (unsigned int i = 0; i < matrix_rows; i++)
|
||||
matrix[i].reset();
|
||||
}
|
||||
|
||||
const table_column_info *mod_matrix::get_table_columns() const
|
||||
{
|
||||
return table_columns;
|
||||
}
|
||||
|
||||
uint32_t mod_matrix::get_table_rows() const
|
||||
{
|
||||
return matrix_rows;
|
||||
}
|
||||
|
||||
std::string mod_matrix::get_cell(int row, int column) const
|
||||
std::string mod_matrix_impl::get_cell(int row, int column) const
|
||||
{
|
||||
assert(row >= 0 && row < (int)matrix_rows);
|
||||
modulation_entry &slot = matrix[row];
|
||||
const char **arr = metadata->get_table_columns()[column].values;
|
||||
switch(column) {
|
||||
case 0: // source 1
|
||||
return mod_src_names[slot.src1];
|
||||
return arr[slot.src1];
|
||||
case 1: // mapping mode
|
||||
return mod_mapping_names[slot.mapping];
|
||||
return arr[slot.mapping];
|
||||
case 2: // source 2
|
||||
return mod_src_names[slot.src2];
|
||||
return arr[slot.src2];
|
||||
case 3: // amount
|
||||
return calf_utils::f2s(slot.amount);
|
||||
case 4: // destination
|
||||
return mod_dest_names[slot.dest];
|
||||
return arr[slot.dest];
|
||||
default:
|
||||
assert(0);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
void mod_matrix::set_cell(int row, int column, const std::string &src, std::string &error)
|
||||
void mod_matrix_impl::set_cell(int row, int column, const std::string &src, std::string &error)
|
||||
{
|
||||
assert(row >= 0 && row < (int)matrix_rows);
|
||||
modulation_entry &slot = matrix[row];
|
||||
const char **arr = mod_src_names;
|
||||
if (column == 1)
|
||||
arr = mod_mapping_names;
|
||||
if (column == 4)
|
||||
arr = mod_dest_names;
|
||||
const char **arr = metadata->get_table_columns()[column].values;
|
||||
switch(column) {
|
||||
case 0:
|
||||
case 1:
|
||||
@@ -113,7 +88,7 @@ void mod_matrix::set_cell(int row, int column, const std::string &src, std::stri
|
||||
if (column == 0)
|
||||
slot.src1 = i;
|
||||
else if (column == 1)
|
||||
slot.mapping = (mapping_mode)i;
|
||||
slot.mapping = (mod_matrix_metadata::mapping_mode)i;
|
||||
else if (column == 2)
|
||||
slot.src2 = i;
|
||||
else if (column == 4)
|
||||
@@ -135,3 +110,33 @@ void mod_matrix::set_cell(int row, int column, const std::string &src, std::stri
|
||||
}
|
||||
}
|
||||
|
||||
void mod_matrix_impl::send_configures(send_configure_iface *sci)
|
||||
{
|
||||
for (int i = 0; i < (int)matrix_rows; i++)
|
||||
{
|
||||
for (int j = 0; j < 5; j++)
|
||||
{
|
||||
string key = "mod_matrix:" + i2s(i) + "," + i2s(j);
|
||||
sci->send_configure(key.c_str(), get_cell(i, j).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char *mod_matrix_impl::configure(const char *key, const char *value)
|
||||
{
|
||||
bool is_rows;
|
||||
int row, column;
|
||||
if (!parse_table_key(key, "mod_matrix:", is_rows, row, column))
|
||||
return NULL;
|
||||
if (is_rows)
|
||||
return strdup("Unexpected key");
|
||||
|
||||
if (row != -1 && column != -1)
|
||||
{
|
||||
string error;
|
||||
set_cell(row, column, value, error);
|
||||
if (!error.empty())
|
||||
return strdup(error.c_str());
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -189,6 +189,7 @@ static inline void delayline_impl(int age, int deltime, float dry_value, const f
|
||||
// if the buffer hasn't been cleared yet (after activation), pretend we've read zeros
|
||||
if (age <= deltime) {
|
||||
out = 0;
|
||||
del = dry_value;
|
||||
amt.step();
|
||||
fb.step();
|
||||
}
|
||||
@@ -206,6 +207,7 @@ static inline void delayline2_impl(int age, int deltime, float dry_value, const
|
||||
{
|
||||
if (age <= deltime) {
|
||||
out = 0;
|
||||
del = dry_value;
|
||||
amt.step();
|
||||
fb.step();
|
||||
}
|
||||
|
||||
@@ -248,7 +248,7 @@ bool equalizerNband_audio_module<BaseClass, has_lphp>::get_graph(int index, int
|
||||
return false;
|
||||
if (index == AM::param_p1_freq && !subindex) {
|
||||
context->set_line_width(1.5);
|
||||
return ::get_graph(*this, subindex, data, points);
|
||||
return ::get_graph(*this, subindex, data, points, 32, 0);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -259,7 +259,7 @@ bool equalizerNband_audio_module<BaseClass, has_lphp>::get_gridline(int index, i
|
||||
if (!is_active) {
|
||||
return false;
|
||||
} else {
|
||||
return get_freq_gridline(subindex, pos, vertical, legend, context);
|
||||
return get_freq_gridline(subindex, pos, vertical, legend, context, true, 32, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,34 +27,8 @@ using namespace std;
|
||||
|
||||
float silence[4097];
|
||||
|
||||
static const char *monosynth_mod_src_names[] = {
|
||||
"None",
|
||||
"Velocity",
|
||||
"Pressure",
|
||||
"ModWheel",
|
||||
"Envelope 1",
|
||||
"Envelope 2",
|
||||
"LFO 1",
|
||||
"LFO 2",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *monosynth_mod_dest_names[] = {
|
||||
"None",
|
||||
"Attenuation",
|
||||
"Osc Mix Ratio (%)",
|
||||
"Cutoff [ct]",
|
||||
"Resonance",
|
||||
"O1: Detune [ct]",
|
||||
"O2: Detune [ct]",
|
||||
"O1: PW (%)",
|
||||
"O2: PW (%)",
|
||||
"O1: Stretch",
|
||||
NULL
|
||||
};
|
||||
|
||||
monosynth_audio_module::monosynth_audio_module()
|
||||
: mod_matrix(mod_matrix_data, mod_matrix_slots, monosynth_mod_src_names, monosynth_mod_dest_names)
|
||||
: mod_matrix_impl(mod_matrix_data, &mm_metadata)
|
||||
, inertia_cutoff(1)
|
||||
, inertia_pitchbend(1)
|
||||
, inertia_pressure(64)
|
||||
|
||||
@@ -62,7 +62,7 @@ uint32_t organ_audio_module::process(uint32_t offset, uint32_t nsamples, uint32_
|
||||
}
|
||||
|
||||
void organ_audio_module::params_changed() {
|
||||
for (int i = 0; i < param_count - var_count; i++)
|
||||
for (int i = 0; i < param_count; i++)
|
||||
((float *)&par_values)[i] = *params[i];
|
||||
|
||||
unsigned int old_poly = polyphony_limit;
|
||||
|
||||
@@ -116,7 +116,7 @@ void ladspa_instance::run_synth(unsigned long SampleCount, snd_seq_event_t *Even
|
||||
|
||||
char *ladspa_instance::configure(const char *key, const char *value)
|
||||
{
|
||||
#if USE_DSSI
|
||||
#if USE_DSSI_GUI
|
||||
if (!strcmp(key, "OSC:FEEDBACK_URI"))
|
||||
{
|
||||
const line_graph_iface *lgi = dynamic_cast<const line_graph_iface *>(metadata);
|
||||
|
||||
552
plugins/ladspa_effect/calf/src/wavetable.cpp
Normal file
552
plugins/ladspa_effect/calf/src/wavetable.cpp
Normal file
@@ -0,0 +1,552 @@
|
||||
/* Calf DSP Library
|
||||
* Example audio modules - wavetable synthesizer
|
||||
*
|
||||
* Copyright (C) 2009 Krzysztof Foltman
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this program; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#if ENABLE_EXPERIMENTAL
|
||||
|
||||
#include <calf/giface.h>
|
||||
#include <calf/modules_synths.h>
|
||||
#include <iostream>
|
||||
|
||||
using namespace dsp;
|
||||
using namespace calf_plugins;
|
||||
|
||||
wavetable_voice::wavetable_voice()
|
||||
{
|
||||
sample_rate = -1;
|
||||
}
|
||||
|
||||
void wavetable_voice::set_params_ptr(wavetable_audio_module *_parent, int _srate)
|
||||
{
|
||||
parent = _parent;
|
||||
params = parent->params;
|
||||
sample_rate = _srate;
|
||||
}
|
||||
|
||||
void wavetable_voice::reset()
|
||||
{
|
||||
note = -1;
|
||||
}
|
||||
|
||||
void wavetable_voice::note_on(int note, int vel)
|
||||
{
|
||||
typedef wavetable_metadata md;
|
||||
this->note = note;
|
||||
velocity = vel / 127.0;
|
||||
amp.set(1.0);
|
||||
for (int i = 0; i < OscCount; i++) {
|
||||
oscs[i].reset();
|
||||
oscs[i].set_freq(note_to_hz(note, 0), sample_rate);
|
||||
last_oscshift[i] = 0;
|
||||
}
|
||||
int cr = sample_rate / BlockSize;
|
||||
for (int i = 0; i < EnvCount; i++) {
|
||||
envs[i].set(0.01, 0.1, 0.5, 1, cr);
|
||||
envs[i].note_on();
|
||||
}
|
||||
float modsrc[wavetable_metadata::modsrc_count] = { 1, velocity, parent->inertia_pressure.get_last(), parent->modwheel_value, envs[0].value, envs[1].value, envs[2].value};
|
||||
parent->calculate_modmatrix(moddest, md::moddest_count, modsrc);
|
||||
calc_derived_dests();
|
||||
|
||||
float oscshift[2] = { moddest[md::moddest_o1shift], moddest[md::moddest_o2shift] };
|
||||
memcpy(last_oscshift, oscshift, sizeof(oscshift));
|
||||
memcpy(last_oscamp, cur_oscamp, sizeof(cur_oscamp));
|
||||
}
|
||||
|
||||
void wavetable_voice::note_off(int vel)
|
||||
{
|
||||
for (int i = 0; i < EnvCount; i++)
|
||||
envs[i].note_off();
|
||||
}
|
||||
|
||||
void wavetable_voice::steal()
|
||||
{
|
||||
}
|
||||
|
||||
void wavetable_voice::render_block()
|
||||
{
|
||||
typedef wavetable_metadata md;
|
||||
|
||||
const float step = 1.f / BlockSize;
|
||||
|
||||
float s = 0.001;
|
||||
float scl[EnvCount];
|
||||
int espc = md::par_eg2attack - md::par_eg1attack;
|
||||
for (int j = 0; j < EnvCount; j++) {
|
||||
int o = j*espc;
|
||||
envs[j].set(*params[md::par_eg1attack + o] * s, *params[md::par_eg1decay + o] * s, *params[md::par_eg1sustain + o], *params[md::par_eg1release + o] * s, sample_rate / BlockSize, *params[md::par_eg1fade + o] * s);
|
||||
scl[j] = dsp::lerp(1.f, velocity, *params[md::par_eg1velscl + o]);;
|
||||
}
|
||||
|
||||
for (int i = 0; i < EnvCount; i++)
|
||||
envs[i].advance();
|
||||
|
||||
float modsrc[wavetable_metadata::modsrc_count] = { 1, velocity, parent->inertia_pressure.get_last(), parent->modwheel_value, envs[0].value, envs[1].value, envs[2].value};
|
||||
parent->calculate_modmatrix(moddest, md::moddest_count, modsrc);
|
||||
calc_derived_dests();
|
||||
|
||||
int ospc = md::par_o2level - md::par_o1level;
|
||||
for (int j = 0; j < OscCount; j++) {
|
||||
oscs[j].tables = parent->tables[(int)*params[md::par_o1wave + j * ospc]];
|
||||
oscs[j].set_freq(note_to_hz(note, *params[md::par_o1transpose + j * ospc] * 100+ *params[md::par_o1detune + j * ospc] + moddest[md::moddest_o1detune]), sample_rate);
|
||||
}
|
||||
|
||||
float oscshift[2] = { moddest[md::moddest_o1shift], moddest[md::moddest_o2shift] };
|
||||
float osstep[2] = { (oscshift[0] - last_oscshift[0]) * step, (oscshift[1] - last_oscshift[1]) * step };
|
||||
float oastep[2] = { (cur_oscamp[0] - last_oscamp[0]) * step, (cur_oscamp[1] - last_oscamp[1]) * step };
|
||||
for (int i = 0; i < BlockSize; i++) {
|
||||
float value = 0.f;
|
||||
|
||||
for (int j = 0; j < OscCount; j++) {
|
||||
float o = last_oscshift[j] * 0.01;
|
||||
value += last_oscamp[j] * oscs[j].get(dsp::clip(fastf2i_drm((o + *params[md::par_o1offset + j * ospc]) * 127.0 * 256), 0, 127 * 256));
|
||||
last_oscshift[j] += osstep[j];
|
||||
last_oscamp[j] += oastep[j];
|
||||
}
|
||||
|
||||
output_buffer[i][0] = output_buffer[i][1] = value;
|
||||
}
|
||||
if (envs[0].stopped())
|
||||
released = true;
|
||||
memcpy(last_oscshift, oscshift, sizeof(oscshift));
|
||||
memcpy(last_oscamp, cur_oscamp, sizeof(cur_oscamp));
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static inline float sincl(float x, float clip)
|
||||
{
|
||||
if (fabs(x) > clip)
|
||||
return 0;
|
||||
return sin(M_PI * x);
|
||||
}
|
||||
|
||||
static inline float blip(float x, float center, float range)
|
||||
{
|
||||
if (x < center - range || x > center + range)
|
||||
return 0;
|
||||
return 1 - fabs(x - center)/range;
|
||||
}
|
||||
|
||||
static void interpolate_wt(int16_t table[129][256], int step)
|
||||
{
|
||||
for (int i = 0; i < 128; i++)
|
||||
{
|
||||
if (!(i % step))
|
||||
continue;
|
||||
int prev = i - i % step;
|
||||
int next = prev + step;
|
||||
for (int j = 0; j < 256; j++)
|
||||
{
|
||||
table[i][j] = table[prev][j] + (i - prev) * (table[next][j] - table[prev][j]) / step;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wavetable_audio_module::wavetable_audio_module()
|
||||
: mod_matrix_impl(mod_matrix_data, &mm_metadata)
|
||||
, inertia_cutoff(1)
|
||||
, inertia_pitchbend(1)
|
||||
, inertia_pressure(64)
|
||||
{
|
||||
panic_flag = false;
|
||||
modwheel_value = 0.;
|
||||
for (int i = 0; i < 129; i += 8)
|
||||
{
|
||||
for (int j = 0; j < 256; j++)
|
||||
{
|
||||
float ph = j * 2 * M_PI / 256;
|
||||
int harm = 1 + 2 * (i / 8);
|
||||
float ii = i / 128.0;
|
||||
float rezo1 = sin(harm * ph) * sin(ph);
|
||||
float rezo2 = sin((harm+1) * ph) * sin(ph * 2);
|
||||
float rezo3 = sin((harm+3) * ph) * sin(ph * 4);
|
||||
float rezo = (rezo1 + rezo2 + rezo3) / 3;
|
||||
float v = (sin (ph) + ii * ii * rezo) / 2;
|
||||
tables[0][i][j] = 32767 * v;
|
||||
}
|
||||
}
|
||||
interpolate_wt(tables[0], 8);
|
||||
for (int i = 0; i < 129; i += 4)
|
||||
{
|
||||
for (int j = 0; j < 256; j++)
|
||||
{
|
||||
float ph = j * 2 * M_PI / 256;
|
||||
int harm = 1 + (i / 4);
|
||||
float ii = i / 128.0;
|
||||
float h = sin(harm * ph);
|
||||
float rezo1 = h * sin(ph);
|
||||
float rezo2 = h * sin(ph * 2)/2;
|
||||
float rezo3 = h * sin(ph * 3)/3;
|
||||
float rezo4 = h * sin(ph * 4)/4;
|
||||
float rezo5 = h * sin(ph * 5)/5;
|
||||
float rezo = (rezo1 + rezo2 + rezo3 + rezo4 + rezo5) / 3;
|
||||
float v = sin (ph + ii * rezo);
|
||||
tables[1][i][j] = 32767 * v;
|
||||
}
|
||||
}
|
||||
interpolate_wt(tables[1], 4);
|
||||
for (int i = 0; i < 129; i++)
|
||||
{
|
||||
for (int j = 0; j < 256; j++)
|
||||
{
|
||||
float ph = j * 2 * M_PI / 256;
|
||||
float ii = (i & ~3) / 128.0;
|
||||
float ii2 = ((i & ~3) + 4) / 128.0;
|
||||
float peak = (32 * ii);
|
||||
float rezo1 = sin(floor(peak) * ph);
|
||||
float rezo2 = sin(floor(peak + 1) * ph);
|
||||
float widener = (0.5 + 0.3 * sin(ph) + 0.2 * sin (3 * ph));
|
||||
float v1 = 0.5 * sin (ph) + 0.5 * ii * ii * rezo1 * widener;
|
||||
float v2 = 0.5 * sin (ph) + 0.5 * ii2 * ii2 * rezo2 * widener;
|
||||
tables[wavetable_metadata::wt_rezo][i][j] = 32767 * lerp(v1, v2, (i & 3) / 4.0);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 129; i++)
|
||||
{
|
||||
for (int j = 0; j < 256; j++)
|
||||
{
|
||||
float ph = j * 2 * M_PI / 256;
|
||||
float ii = i / 128.0;
|
||||
float v = (sin(ph) + ii * sin(ph + 2 * ii * sin(ph)) + ii * ii * sin(ph + 6 * ii * ii * sin(6 * ph)) + ii * ii * ii * ii * sin(ph + 11 * ii * ii * ii * ii * sin(11 * ph))) / 4;
|
||||
tables[wavetable_metadata::wt_metal][i][j] = 32767 * v;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 129; i++)
|
||||
{
|
||||
for (int j = 0; j < 256; j++)
|
||||
{
|
||||
float ph = j * 2 * M_PI / 256;
|
||||
float ii = i / 128.0;
|
||||
float v = (sin(ph) + ii * sin(ph - 3 * ii * sin(ph)) + ii * ii * sin(5 * ph - 5 * ii * ii * ii * ii * sin(11 * ph))) / 3;
|
||||
tables[wavetable_metadata::wt_bell][i][j] = 32767 * v;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 129; i++)
|
||||
{
|
||||
for (int j = 0; j < 256; j++)
|
||||
{
|
||||
float ph = j * 2 * M_PI / 256;
|
||||
float ii = i / 128.0;
|
||||
//float v = (sin(ph) + ii * sin(ph + 2 * ii * sin(ph)) + ii * ii * sin(ph + 3 * ii * ii * sin(3 * ph)) + ii * ii * ii * sin(ph + 5 * ii * ii * ii * sin(5 * ph))) / 4;
|
||||
float v = (sin(ph) + sin(ph - 3 * sin(ii * 5 - 2) * sin(ph)) + sin(ii * 4 - 1.3) * sin(5 * ph + 3 * ii * ii * sin(6 * ph))) / 3;
|
||||
tables[wavetable_metadata::wt_blah][i][j] = 32767 * v;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
tables[wavetable_metadata::wt_pluck][128][i] = (i < 128) ? 32000 * fabs(sin(i / 32.0 * M_PI) * sin(i / 13.0 * M_PI) * sin(i / 19.0 * M_PI)) : 0;
|
||||
}
|
||||
for (int i = 127; i >= 0; i--)
|
||||
{
|
||||
int16_t *parent = tables[wavetable_metadata::wt_pluck][i + 1];
|
||||
float damp = 0.05;
|
||||
for (int j = 0; j < 256; j++)
|
||||
{
|
||||
tables[wavetable_metadata::wt_pluck][i][j] = (1 - 2*damp) * parent[j] + damp * parent[(j+1)&255] + damp * parent[(j+2)&255];// + 0.1 * parent[(j-1)&255]+ 0.1 * parent[(j-2)&255];
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 129; i++)
|
||||
{
|
||||
for (int j = 0; j < 256; j++)
|
||||
{
|
||||
float ph = j / 128.0 - 1.0;
|
||||
float ii = i / 128.0;
|
||||
float v = sincl(ph * (1 + 15 * ii), 1);
|
||||
tables[wavetable_metadata::wt_stretch][i][j] = 32767 * v;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 129; i++)
|
||||
{
|
||||
for (int j = 0; j < 256; j++)
|
||||
{
|
||||
float ph = j / 128.0 - 1.0;
|
||||
float ii = i / 128.0;
|
||||
float v = sincl(ph * (1 + 15 * ii), 4) * sincl(j / 256.0, 1);
|
||||
tables[wavetable_metadata::wt_stretch2][i][j] = 32000 * v;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 129; i++)
|
||||
{
|
||||
for (int j = 0; j < 256; j++)
|
||||
{
|
||||
float ph = j / 128.0 - 1.0;
|
||||
float ii = i / 128.0;
|
||||
float w = sincl(ph * (1 + 15 * ii), 4);
|
||||
float v = pow(w, 9) * sincl(j / 256.0, 1);
|
||||
tables[wavetable_metadata::wt_hardsync][i][j] = 32000 * v;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 129; i++)
|
||||
{
|
||||
for (int j = 0; j < 256; j++)
|
||||
{
|
||||
float ph = j / 128.0 - 1.0;
|
||||
float ii = i / 128.0;
|
||||
float w = sincl(ph * (1 + 31 * ii), 3);
|
||||
float v = pow(w, 5) * sincl(j / 256.0, 1);
|
||||
tables[wavetable_metadata::wt_hardsync2][i][j] = 32000 * v;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 129; i++)
|
||||
{
|
||||
for (int j = 0; j < 256; j++)
|
||||
{
|
||||
float ph = j / 128.0 - 1.0;
|
||||
float ii = i / 128.0;
|
||||
float w = sincl(ph * ph * (1 + 15 * ii), 2);
|
||||
float v = pow(w, 4) * sincl(j / 256.0, 1);
|
||||
tables[wavetable_metadata::wt_softsync][i][j] = 32000 * v;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 129; i++)
|
||||
{
|
||||
for (int j = 0; j < 256; j++)
|
||||
{
|
||||
float ph = j * 2 * M_PI / 256;
|
||||
float ii = i / 128.0;
|
||||
float v = (sin(ph) + ii * sin(ph - 3 * ii * sin(ph)) + ii * ii * ii * sin(7 * ph - 2 * ii * ii * ii * ii * sin(13 * ph))) / 3;
|
||||
tables[wavetable_metadata::wt_bell2][i][j] = 32767 * v;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 129; i++)
|
||||
{
|
||||
for (int j = 0; j < 256; j++)
|
||||
{
|
||||
float ph = j * 2 * M_PI / 256;
|
||||
float ii = i / 128.0;
|
||||
float v = (sin(ph) + ii * sin(ph - 3 * ii * sin(ph)) + ii * ii * ii * sin(9 * ph - ii * ii * sin(11 * ph))) / 3;
|
||||
tables[wavetable_metadata::wt_bell3][i][j] = 32767 * v;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 129; i++)
|
||||
{
|
||||
for (int j = 0; j < 256; j++)
|
||||
{
|
||||
float ph = j * 2 * M_PI / 256;
|
||||
float ii = i / 128.0;
|
||||
float v = (sin(ph + ii * sin(ph - 3 * ii * sin(ph) + ii * ii * ii * sin(5 * ph - ii * ii * sin(7 * ph)))));
|
||||
tables[wavetable_metadata::wt_tine][i][j] = 32767 * v;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 129; i++)
|
||||
{
|
||||
for (int j = 0; j < 256; j++)
|
||||
{
|
||||
float ph = j * 2 * M_PI / 256;
|
||||
float ii = i / 128.0;
|
||||
float v = (sin(ph + ii * sin(ph - 2 * ii * sin(ph) + ii * ii * ii * sin(3 * ph - ii * ii * sin(4 * ph)))));
|
||||
tables[wavetable_metadata::wt_tine2][i][j] = 32767 * v;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 129; i++)
|
||||
{
|
||||
for (int j = 0; j < 256; j++)
|
||||
{
|
||||
float ph = j * 2 * M_PI / 256;
|
||||
float ph2 = j / 128.0 - 1;
|
||||
float ii = i / 128.0;
|
||||
float w = sincl(ph2 * (1 + 7 * ii * ii), 4) * pow(sincl(j / 256.0, 1), 2);
|
||||
float v = sin(ph + ii * sin(ph - 2 * ii * w));
|
||||
tables[wavetable_metadata::wt_clav][i][j] = 32767 * v;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 129; i++)
|
||||
{
|
||||
for (int j = 0; j < 256; j++)
|
||||
{
|
||||
float ph = j * 2 * M_PI / 256;
|
||||
float ph2 = j / 128.0 - 1;
|
||||
float ii = i / 128.0;
|
||||
float w = sincl(ph2 * (1 + 7 * ii * ii), 6) * sincl(j / 256.0, 1);
|
||||
float v = sin(ph + ii * sin(3 * ph - 2 * ii * w));
|
||||
tables[wavetable_metadata::wt_clav2][i][j] = 32767 * v;
|
||||
}
|
||||
}
|
||||
/*
|
||||
for (int i = 0; i < 129; i++)
|
||||
{
|
||||
for (int j = 0; j < 256; j++)
|
||||
{
|
||||
float ph = j * 2 * M_PI / 256;
|
||||
float ph2 = j / 128.0 - 1;
|
||||
float ii = i / 128.0;
|
||||
float w = sincl(ph2 * (1 + 7 * ii * ii), 6) * pow(sincl(j / 256.0, 1), 1);
|
||||
float v = sin(ph + ii * ii * ii * sin(3 * ph - ii * ii * ii * w));
|
||||
tables[wavetable_metadata::wt_gtr][i][j] = 32767 * v;
|
||||
}
|
||||
}
|
||||
*/
|
||||
for (int i = 0; i < 129; i++)
|
||||
{
|
||||
for (int j = 0; j < 256; j++)
|
||||
{
|
||||
float ph = j * 2 * M_PI / 256;
|
||||
float ii = i / 128.0;
|
||||
float ii2 = ii;
|
||||
float w = pow(sincl(j / 256.0, 1), 1);
|
||||
float v = sin(ph + ii2 * ii2 * ii2 * sin(3 * ph - ii2 * ii2 * ii2 * w * sin(ph + sin(3 * ph) + ii * sin(11 * ph) + ii * ii * sin(25 * ph))));
|
||||
tables[wavetable_metadata::wt_gtr][i][j] = 32767 * v;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 129; i++)
|
||||
{
|
||||
for (int j = 0; j < 256; j++)
|
||||
{
|
||||
float ph = j * 2 * M_PI / 256;
|
||||
float ii = i / 128.0;
|
||||
float ii2 = dsp::clip(ii - 0.5, 0.0, 1.0);
|
||||
float w = pow(sincl(j / 256.0, 1), 1);
|
||||
float v = sin(ph + ii * ii * ii * sin(3 * ph - ii * ii * ii * w * sin(ph + sin(3 * ph + ii2 * sin(13 * ph)))));
|
||||
tables[wavetable_metadata::wt_gtr2][i][j] = 32767 * v;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 129; i++)
|
||||
{
|
||||
for (int j = 0; j < 256; j++)
|
||||
{
|
||||
float ph = j * 2 * M_PI / 256;
|
||||
float ii = i / 128.0;
|
||||
float ii2 = dsp::clip(2 * (ii - 0.5), 0.0, 1.0);
|
||||
//float w = sincl(ph2 * (1 + 15 * ii2 * ii2), 4) * pow(sincl(j / 256.0, 1), 1);
|
||||
float w = pow(sincl(j / 256.0, 1), 1);
|
||||
float v = sin(ph + ii * sin(3 * ph - ii * w * sin(ph + sin(3 * ph + 0.5 * ii2 * sin(13 * ph + 0.5 * sin(4 * ph))))));
|
||||
tables[wavetable_metadata::wt_gtr3][i][j] = 32767 * v;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 129; i++)
|
||||
{
|
||||
for (int j = 0; j < 256; j++)
|
||||
{
|
||||
float ph = j * 2 * M_PI / 256;
|
||||
float ii = i / 128.0;
|
||||
float ii2 = dsp::clip(2 * (ii - 0.5), 0.0, 1.0);
|
||||
//float w = sincl(ph2 * (1 + 15 * ii2 * ii2), 4) * pow(sincl(j / 256.0, 1), 1);
|
||||
float w = pow(sincl(j / 256.0, 1), 1);
|
||||
float v = sin(ph + ii * sin(3 * ph - ii * w * sin(2 * ph + sin(5 * ph + 0.5 * ii2 * sin(13 * ph + 0.5 * sin(4 * ph))))));
|
||||
tables[wavetable_metadata::wt_gtr4][i][j] = 32767 * v;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 129; i++)
|
||||
{
|
||||
for (int j = 0; j < 256; j++)
|
||||
{
|
||||
float ph = j * 2 * M_PI / 256;
|
||||
float ii = i / 128.0;
|
||||
float ii2 = dsp::clip((ii - 0.25)/0.75, 0.0, 1.0);
|
||||
//float w = sincl(ph2 * (1 + 15 * ii2 * ii2), 4) * pow(sincl(j / 256.0, 1), 1);
|
||||
float w = pow(sincl(j / 256.0, 1), 3);
|
||||
float v = sin(ph + (ii + 0.05) * sin(3 * ph - 2 * ii * w * sin(5 * ph + sin(7 * ph + 0.5 * ii2 * sin(13 * ph + 0.5 * sin(11 * ph))))));
|
||||
tables[wavetable_metadata::wt_gtr5][i][j] = 32767 * v;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 129; i++)
|
||||
{
|
||||
for (int j = 0; j < 256; j++)
|
||||
{
|
||||
float ph = j * 2 * M_PI / 256;
|
||||
float ii = i / 128.0;
|
||||
float w = pow(sincl(2 * (j / 256.0), 2), 3);
|
||||
float v = sin(ph + (ii + 0.05) * sin(7 * ph - 2 * ii * w * sin(11 * ph)));
|
||||
tables[wavetable_metadata::wt_reed][i][j] = 32767 * v;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 129; i++)
|
||||
{
|
||||
for (int j = 0; j < 256; j++)
|
||||
{
|
||||
float ph = j * 2 * M_PI / 256;
|
||||
float ii = i / 128.0;
|
||||
float ii2 = dsp::clip((ii - 0.25)/0.75, 0.0, 1.0);
|
||||
float ii3 = dsp::clip((ii - 0.5)/0.5, 0.0, 1.0);
|
||||
float v = sin(ph + (ii + 0.05) * sin(ii * sin(2 * ph) - 2 * ii2 * sin(2 * ph + ii2 * sin(3 * ph)) + 3 * ii3 * sin(3 * ph)));
|
||||
tables[wavetable_metadata::wt_reed2][i][j] = 32767 * v;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 129; i++)
|
||||
{
|
||||
for (int j = 0; j < 256; j++)
|
||||
{
|
||||
float ph = j * 2 * M_PI / 256;
|
||||
float ii = i / 128.0;
|
||||
float mod = 0;
|
||||
for (int k = 0; k < 13; k++)
|
||||
{
|
||||
mod += blip(i, k * 10, 30) * sin (ph * (5 + 3 * k) + ii * cos(ph * (2 + 2 * k)));
|
||||
}
|
||||
float v = sin(ph + ii * mod);
|
||||
tables[wavetable_metadata::wt_silver][i][j] = 32767 * v;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 129; i++)
|
||||
{
|
||||
for (int j = 0; j < 256; j++)
|
||||
{
|
||||
float ph = j * 2 * M_PI / 256;
|
||||
float ii = i / 128.0;
|
||||
float mod = 0;
|
||||
for (int k = 0; k < 16; k++)
|
||||
{
|
||||
mod += 2 * blip(i, k * 8, k * 4 + 10) * cos (ph * (k + 1));
|
||||
}
|
||||
float v = sin(ph + ii * mod);
|
||||
tables[wavetable_metadata::wt_brass][i][j] = 32767 * v;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 129; i++)
|
||||
{
|
||||
for (int j = 0; j < 256; j++)
|
||||
{
|
||||
float ph = j * 2 * M_PI / 256;
|
||||
float ii = i / 128.0;
|
||||
float mod = 0;
|
||||
for (int k = 0; k < 16; k++)
|
||||
{
|
||||
mod += 2 * blip(i, k * 8, 16) * cos (ph * (2 * k + 1));
|
||||
}
|
||||
float v = (sin(ph + ii * mod) + ii * sin(2 * ph + ii * mod)) / 2;
|
||||
tables[wavetable_metadata::wt_multi][i][j] = 32767 * v;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 129; i ++)
|
||||
{
|
||||
float h = 1 + i / 16.0;
|
||||
for (int j = 0; j < 256; j++)
|
||||
{
|
||||
float ph = j * 2 * M_PI / 256;
|
||||
float v = sin(ph), tv = 1;
|
||||
for (int k = 1; k < 24; k++) {
|
||||
float amp = blip(i, k * 6, 20) / k;
|
||||
v += amp * sin((k + 1) * ph + h * sin(ph));
|
||||
tv += amp;
|
||||
}
|
||||
tables[wavetable_metadata::wt_multi2][i][j] = 32767 * v / tv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void wavetable_audio_module::channel_pressure(int value)
|
||||
{
|
||||
inertia_pressure.set_inertia(value * (1.0 / 127.0));
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user