Skip to content

Commit

Permalink
BiquadFilter: implement logarithmic scale for frequency (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
attilammagyar committed May 17, 2023
1 parent 1223dc4 commit 0961a03
Show file tree
Hide file tree
Showing 16 changed files with 457 additions and 33 deletions.
3 changes: 2 additions & 1 deletion scripts/perf_math.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ main()

if [[ "$platform" = "" ]]
then
platform="x86_64-w64-mingw32"
platform="x86_64-gpp"
fi

executable=./build/"$platform"/perf_math

if [[ ! -x "$executable" ]]
then
echo "Unable to find $executable, run \"make check\" first" >&2
echo "or pass a platform name in the first argument." >&2
return 1
fi

Expand Down
13 changes: 13 additions & 0 deletions src/gui/gui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,13 @@ char const* const GUI::PARAMS[] = {
[Synth::ParamId::L8SYN] = "LFO 8 Tempo Synchronization",

[Synth::ParamId::EESYN] = "Echo Tempo Sync",

[Synth::ParamId::MF1LOG] = "Modulator Filter 1 Logarithmic Frequency",
[Synth::ParamId::MF2LOG] = "Modulator Filter 2 Logarithmic Frequency",
[Synth::ParamId::CF1LOG] = "Carrier Filter 1 Logarithmic Frequency",
[Synth::ParamId::CF2LOG] = "Carrier Filter 2 Logarithmic Frequency",
[Synth::ParamId::EF1LOG] = "Effects Filter 1 Logarithmic Frequency",
[Synth::ParamId::EF2LOG] = "Effects Filter 2 Logarithmic Frequency",
};


Expand Down Expand Up @@ -974,11 +981,13 @@ void GUI::build_effects_body(ParamEditorKnobStates* knob_states)
PE(effects_body, 385 + PE_W * 1, 57, Synth::ParamId::EF1FRQ, LFO_CTLS, "%.1f", 1.0, knob_states);
PE(effects_body, 385 + PE_W * 2, 57, Synth::ParamId::EF1Q, LFO_CTLS, "%.2f", 1.0, knob_states);
PE(effects_body, 385 + PE_W * 3, 57, Synth::ParamId::EF1G, LFO_CTLS, "%.2f", 1.0, knob_states);
TS(effects_body, 459, 29, 90, 0, Synth::ParamId::EF1LOG);

PE(effects_body, 690 + PE_W * 0, 57, Synth::ParamId::EF2TYP, MIDI_CTLS, ft, ftc, knob_states);
PE(effects_body, 690 + PE_W * 1, 57, Synth::ParamId::EF2FRQ, LFO_CTLS, "%.1f", 1.0, knob_states);
PE(effects_body, 690 + PE_W * 2, 57, Synth::ParamId::EF2Q, LFO_CTLS, "%.2f", 1.0, knob_states);
PE(effects_body, 690 + PE_W * 3, 57, Synth::ParamId::EF2G, LFO_CTLS, "%.2f", 1.0, knob_states);
TS(effects_body, 764, 29, 90, 0, Synth::ParamId::EF2LOG);

PE(effects_body, 258 + PE_W * 0, 242, Synth::ParamId::EEDEL, LFO_CTLS, "%.3f", 1.0, knob_states);
PE(effects_body, 258 + PE_W * 1, 242, Synth::ParamId::EEFB, LFO_CTLS, "%.2f", 100.0, knob_states);
Expand Down Expand Up @@ -1220,6 +1229,7 @@ void GUI::build_synth_body(ParamEditorKnobStates* knob_states)
PE(synth_body, 735 + PE_W * 1, 36, Synth::ParamId::MF1FRQ, ALL_CTLS, "%.1f", 1.0, knob_states);
PE(synth_body, 735 + PE_W * 2, 36, Synth::ParamId::MF1Q, ALL_CTLS, "%.2f", 1.0, knob_states);
PE(synth_body, 735 + PE_W * 3, 36, Synth::ParamId::MF1G, ALL_CTLS, "%.2f", 1.0, knob_states);
TS(synth_body, 811, 13, 90, 0, Synth::ParamId::MF1LOG);

PE(synth_body, 116 + PE_W * 0, 168, Synth::ParamId::MC1, FLEX_CTLS, "%.2f", 100.0, knob_states);
PE(synth_body, 116 + PE_W * 1, 168, Synth::ParamId::MC2, FLEX_CTLS, "%.2f", 100.0, knob_states);
Expand All @@ -1236,6 +1246,7 @@ void GUI::build_synth_body(ParamEditorKnobStates* knob_states)
PE(synth_body, 735 + PE_W * 1, 168, Synth::ParamId::MF2FRQ, ALL_CTLS, "%.1f", 1.0, knob_states);
PE(synth_body, 735 + PE_W * 2, 168, Synth::ParamId::MF2Q, ALL_CTLS, "%.2f", 1.0, knob_states);
PE(synth_body, 735 + PE_W * 3, 168, Synth::ParamId::MF2G, ALL_CTLS, "%.2f", 1.0, knob_states);
TS(synth_body, 811, 145, 90, 0, Synth::ParamId::MF2LOG);

PE(synth_body, 87 + PE_W * 0, 316, Synth::ParamId::CWAV, MIDI_CTLS, wf, wfc, knob_states);
PE(synth_body, 87 + PE_W * 1, 316, Synth::ParamId::CPRT, FLEX_CTLS, "%.3f", 1.0, knob_states);
Expand All @@ -1253,6 +1264,7 @@ void GUI::build_synth_body(ParamEditorKnobStates* knob_states)
PE(synth_body, 735 + PE_W * 1, 316, Synth::ParamId::CF1FRQ, ALL_CTLS, "%.1f", 1.0, knob_states);
PE(synth_body, 735 + PE_W * 2, 316, Synth::ParamId::CF1Q, ALL_CTLS, "%.2f", 1.0, knob_states);
PE(synth_body, 735 + PE_W * 3, 316, Synth::ParamId::CF1G, ALL_CTLS, "%.2f", 1.0, knob_states);
TS(synth_body, 811, 293, 90, 0, Synth::ParamId::CF1LOG);

PE(synth_body, 116 + PE_W * 0, 448, Synth::ParamId::CC1, FLEX_CTLS, "%.2f", 100.0, knob_states);
PE(synth_body, 116 + PE_W * 1, 448, Synth::ParamId::CC2, FLEX_CTLS, "%.2f", 100.0, knob_states);
Expand All @@ -1269,6 +1281,7 @@ void GUI::build_synth_body(ParamEditorKnobStates* knob_states)
PE(synth_body, 735 + PE_W * 1, 448, Synth::ParamId::CF2FRQ, ALL_CTLS, "%.1f", 1.0, knob_states);
PE(synth_body, 735 + PE_W * 2, 448, Synth::ParamId::CF2Q, ALL_CTLS, "%.2f", 1.0, knob_states);
PE(synth_body, 735 + PE_W * 3, 448, Synth::ParamId::CF2G, ALL_CTLS, "%.2f", 1.0, knob_states);
TS(synth_body, 811, 425, 90, 0, Synth::ParamId::CF2LOG);

synth_body->show();
}
Expand Down
49 changes: 46 additions & 3 deletions src/synth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ Synth::Synth() noexcept
: SignalProducer(
OUT_CHANNELS,
6 // MODE + MIX + PM + FM + AM + bus
+ 29 * 2 // Modulator::Params + Carrier::Params
+ 31 * 2 // Modulator::Params + Carrier::Params
+ POLYPHONY * 2 // modulators + carriers
+ 1 // effects
+ FLEXIBLE_CONTROLLERS * 6
Expand Down Expand Up @@ -148,6 +148,13 @@ Synth::Synth() noexcept
create_envelopes();
create_lfos();

modulator_params.filter_1_log_scale.set_value(ToggleParam::ON);
modulator_params.filter_2_log_scale.set_value(ToggleParam::ON);
carrier_params.filter_1_log_scale.set_value(ToggleParam::ON);
carrier_params.filter_2_log_scale.set_value(ToggleParam::ON);
effects.filter_1_log_scale.set_value(ToggleParam::ON);
effects.filter_2_log_scale.set_value(ToggleParam::ON);

update_param_states();
}

Expand Down Expand Up @@ -273,13 +280,15 @@ void Synth::register_modulator_params() noexcept
register_param_as_child<Modulator::Filter1::TypeParam>(
ParamId::MF1TYP, modulator_params.filter_1_type
);
register_param_as_child<ToggleParam>(ParamId::MF1LOG, modulator_params.filter_1_log_scale);
register_float_param_as_child(ParamId::MF1FRQ, modulator_params.filter_1_frequency);
register_float_param_as_child(ParamId::MF1Q, modulator_params.filter_1_q);
register_float_param_as_child(ParamId::MF1G, modulator_params.filter_1_gain);

register_param_as_child<Modulator::Filter2::TypeParam>(
ParamId::MF2TYP, modulator_params.filter_2_type
);
register_param_as_child<ToggleParam>(ParamId::MF2LOG, modulator_params.filter_2_log_scale);
register_float_param_as_child(ParamId::MF2FRQ, modulator_params.filter_2_frequency);
register_float_param_as_child(ParamId::MF2Q, modulator_params.filter_2_q);
register_float_param_as_child(ParamId::MF2G, modulator_params.filter_2_gain);
Expand Down Expand Up @@ -316,13 +325,15 @@ void Synth::register_carrier_params() noexcept
register_param_as_child<Carrier::Filter1::TypeParam>(
ParamId::CF1TYP, carrier_params.filter_1_type
);
register_param_as_child<ToggleParam>(ParamId::CF1LOG, carrier_params.filter_1_log_scale);
register_float_param_as_child(ParamId::CF1FRQ, carrier_params.filter_1_frequency);
register_float_param_as_child(ParamId::CF1Q, carrier_params.filter_1_q);
register_float_param_as_child(ParamId::CF1G, carrier_params.filter_1_gain);

register_param_as_child<Carrier::Filter2::TypeParam>(
ParamId::CF2TYP, carrier_params.filter_2_type
);
register_param_as_child<ToggleParam>(ParamId::CF2LOG, carrier_params.filter_2_log_scale);
register_float_param_as_child(ParamId::CF2FRQ, carrier_params.filter_2_frequency);
register_float_param_as_child(ParamId::CF2Q, carrier_params.filter_2_q);
register_float_param_as_child(ParamId::CF2G, carrier_params.filter_2_gain);
Expand All @@ -335,12 +346,14 @@ void Synth::register_effects_params() noexcept

register_float_param(ParamId::EDG, effects.distortion.level);

register_param<Effects::Filter1<Bus>::TypeParam>(EF1TYP, effects.filter_1_type);
register_param<Effects::Filter1<Bus>::TypeParam>(ParamId::EF1TYP, effects.filter_1_type);
register_param<ToggleParam>(ParamId::EF1LOG, effects.filter_1_log_scale);
register_float_param(ParamId::EF1FRQ, effects.filter_1.frequency);
register_float_param(ParamId::EF1Q, effects.filter_1.q);
register_float_param(ParamId::EF1G, effects.filter_1.gain);

register_param<Effects::Filter2<Bus>::TypeParam>(EF2TYP, effects.filter_2_type);
register_param<Effects::Filter2<Bus>::TypeParam>(ParamId::EF2TYP, effects.filter_2_type);
register_param<ToggleParam>(ParamId::EF2LOG, effects.filter_2_log_scale);
register_float_param(ParamId::EF2FRQ, effects.filter_2.frequency);
register_float_param(ParamId::EF2Q, effects.filter_2.q);
register_float_param(ParamId::EF2G, effects.filter_2.gain);
Expand Down Expand Up @@ -827,6 +840,12 @@ Number Synth::get_param_default_ratio(ParamId const param_id) const noexcept
case ParamId::L7SYN: return lfos_rw[6]->tempo_sync.get_default_ratio();
case ParamId::L8SYN: return lfos_rw[7]->tempo_sync.get_default_ratio();
case ParamId::EESYN: return effects.echo.tempo_sync.get_default_ratio();
case ParamId::MF1LOG: return modulator_params.filter_1_log_scale.get_default_ratio();
case ParamId::MF2LOG: return modulator_params.filter_2_log_scale.get_default_ratio();
case ParamId::CF1LOG: return carrier_params.filter_1_log_scale.get_default_ratio();
case ParamId::CF2LOG: return carrier_params.filter_2_log_scale.get_default_ratio();
case ParamId::EF1LOG: return effects.filter_1_log_scale.get_default_ratio();
case ParamId::EF2LOG: return effects.filter_2_log_scale.get_default_ratio();
default: return 0.0; // This should neacver be reached.
}
}
Expand Down Expand Up @@ -865,6 +884,12 @@ Number Synth::get_param_max_value(ParamId const param_id) const noexcept
case ParamId::L7SYN: return lfos_rw[6]->tempo_sync.get_max_value();
case ParamId::L8SYN: return lfos_rw[7]->tempo_sync.get_max_value();
case ParamId::EESYN: return effects.echo.tempo_sync.get_max_value();
case ParamId::MF1LOG: return modulator_params.filter_1_log_scale.get_max_value();
case ParamId::MF2LOG: return modulator_params.filter_2_log_scale.get_max_value();
case ParamId::CF1LOG: return carrier_params.filter_1_log_scale.get_max_value();
case ParamId::CF2LOG: return carrier_params.filter_2_log_scale.get_max_value();
case ParamId::EF1LOG: return effects.filter_1_log_scale.get_max_value();
case ParamId::EF2LOG: return effects.filter_2_log_scale.get_max_value();
default: return 0.0; // This should neacver be reached.
}
}
Expand Down Expand Up @@ -913,6 +938,12 @@ Byte Synth::int_param_ratio_to_display_value(
case ParamId::L7SYN: return lfos_rw[6]->tempo_sync.ratio_to_value(ratio);
case ParamId::L8SYN: return lfos_rw[7]->tempo_sync.ratio_to_value(ratio);
case ParamId::EESYN: return effects.echo.tempo_sync.ratio_to_value(ratio);
case ParamId::MF1LOG: return modulator_params.filter_1_log_scale.ratio_to_value(ratio);
case ParamId::MF2LOG: return modulator_params.filter_2_log_scale.ratio_to_value(ratio);
case ParamId::CF1LOG: return carrier_params.filter_1_log_scale.ratio_to_value(ratio);
case ParamId::CF2LOG: return carrier_params.filter_2_log_scale.ratio_to_value(ratio);
case ParamId::EF1LOG: return effects.filter_1_log_scale.ratio_to_value(ratio);
case ParamId::EF2LOG: return effects.filter_2_log_scale.ratio_to_value(ratio);
default: return 0; // This should never be reached.
}
}
Expand Down Expand Up @@ -1019,6 +1050,12 @@ void Synth::handle_set_param(ParamId const param_id, Number const ratio) noexcep
case ParamId::L7SYN: lfos_rw[6]->tempo_sync.set_ratio(ratio); break;
case ParamId::L8SYN: lfos_rw[7]->tempo_sync.set_ratio(ratio); break;
case ParamId::EESYN: effects.echo.tempo_sync.set_ratio(ratio); break;
case ParamId::MF1LOG: modulator_params.filter_1_log_scale.set_ratio(ratio); break;
case ParamId::MF2LOG: modulator_params.filter_2_log_scale.set_ratio(ratio); break;
case ParamId::CF1LOG: carrier_params.filter_1_log_scale.set_ratio(ratio); break;
case ParamId::CF2LOG: carrier_params.filter_2_log_scale.set_ratio(ratio); break;
case ParamId::EF1LOG: effects.filter_1_log_scale.set_ratio(ratio); break;
case ParamId::EF2LOG: effects.filter_2_log_scale.set_ratio(ratio); break;
default: break; // This should never be reached.
}
}
Expand Down Expand Up @@ -1203,6 +1240,12 @@ Number Synth::get_param_ratio(ParamId const param_id) const noexcept
case ParamId::L7SYN: return lfos_rw[6]->tempo_sync.get_ratio();
case ParamId::L8SYN: return lfos_rw[7]->tempo_sync.get_ratio();
case ParamId::EESYN: return effects.echo.tempo_sync.get_ratio();
case ParamId::MF1LOG: return modulator_params.filter_1_log_scale.get_ratio();
case ParamId::MF2LOG: return modulator_params.filter_2_log_scale.get_ratio();
case ParamId::CF1LOG: return carrier_params.filter_1_log_scale.get_ratio();
case ParamId::CF2LOG: return carrier_params.filter_2_log_scale.get_ratio();
case ParamId::EF1LOG: return effects.filter_1_log_scale.get_ratio();
case ParamId::EF2LOG: return effects.filter_2_log_scale.get_ratio();
default: return 0.0; // This should never be reached.
}
}
Expand Down
10 changes: 8 additions & 2 deletions src/synth.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -404,8 +404,14 @@ class Synth : public Midi::EventHandler, public SignalProducer
L7SYN = 278, ///< LFO 7 Tempo Synchronization
L8SYN = 279, ///< LFO 8 Tempo Synchronization
EESYN = 280, ///< Effects Echo Tempo Synchronization

MAX_PARAM_ID = 281
MF1LOG = 281, ///< Modulator Filter 1 Logarithmic Frequency
MF2LOG = 282, ///< Modulator Filter 2 Logarithmic Frequency
CF1LOG = 283, ///< Carrier Filter 1 Logarithmic Frequency
CF2LOG = 284, ///< Carrier Filter 2 Logarithmic Frequency
EF1LOG = 285, ///< Effects Filter 1 Logarithmic Frequency
EF2LOG = 286, ///< Effects Filter 2 Logarithmic Frequency

MAX_PARAM_ID = 287
};

static constexpr Integer FLOAT_PARAMS = ParamId::MODE;
Expand Down
39 changes: 39 additions & 0 deletions src/synth/biquad_filter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,45 @@ void BiquadFilter<InputSignalProducerClass>::update_helper_variables() noexcept
}


template<class InputSignalProducerClass>
BiquadFilter<InputSignalProducerClass>::BiquadFilter(
std::string const name,
InputSignalProducerClass& input,
TypeParam& type,
ToggleParam const& log_scale_toggle
) noexcept
: Filter<InputSignalProducerClass>(input, 3),
frequency(
name + "FRQ",
Constants::BIQUAD_FILTER_FREQUENCY_MIN,
Constants::BIQUAD_FILTER_FREQUENCY_MAX,
Constants::BIQUAD_FILTER_FREQUENCY_DEFAULT,
0.0,
&log_scale_toggle,
Math::log_biquad_filter_freq_table(),
Math::log_biquad_filter_freq_inv_table(),
Math::LOG_BIQUAD_FILTER_FREQ_TABLE_MAX_INDEX,
Math::LOG_BIQUAD_FILTER_FREQ_SCALE,
Math::LOG_BIQUAD_FILTER_FREQ_INV_SCALE
),
q(
name + "Q",
Constants::BIQUAD_FILTER_Q_MIN,
Constants::BIQUAD_FILTER_Q_MAX,
Constants::BIQUAD_FILTER_Q_DEFAULT
),
gain(
name + "G",
Constants::BIQUAD_FILTER_GAIN_MIN,
Constants::BIQUAD_FILTER_GAIN_MAX,
Constants::BIQUAD_FILTER_GAIN_DEFAULT
),
type(type),
shared_cache(NULL)
{
initialize_instance();
}


template<class InputSignalProducerClass>
BiquadFilter<InputSignalProducerClass>::BiquadFilter(
Expand Down
18 changes: 12 additions & 6 deletions src/synth/biquad_filter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,14 @@ class BiquadFilter : public Filter<InputSignalProducerClass>
TypeParam& type,
BiquadFilterSharedCache* shared_cache = NULL
) noexcept;

BiquadFilter(
std::string const name,
InputSignalProducerClass& input,
TypeParam& type,
ToggleParam const& log_scale_toggle
) noexcept;

BiquadFilter(
InputSignalProducerClass& input,
TypeParam& type,
Expand All @@ -91,14 +99,12 @@ class BiquadFilter : public Filter<InputSignalProducerClass>
FloatParam& gain_leader,
BiquadFilterSharedCache* shared_cache = NULL
) noexcept;

virtual ~BiquadFilter();

virtual void set_sample_rate(
Frequency const new_sample_rate
) noexcept override;
virtual void set_block_size(
Integer const new_block_size
) noexcept override;
virtual void set_sample_rate(Frequency const new_sample_rate) noexcept override;

virtual void set_block_size(Integer const new_block_size) noexcept override;

virtual void reset() noexcept override;

Expand Down
10 changes: 7 additions & 3 deletions src/synth/effects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,24 @@ template<class InputSignalProducerClass>
Effects<InputSignalProducerClass>::Effects(
std::string const name,
InputSignalProducerClass& input
) : Filter< Reverb<InputSignalProducerClass> >(reverb, 8, input.get_channels()),
) : Filter< Reverb<InputSignalProducerClass> >(reverb, 10, input.get_channels()),
overdrive(name + "O", 3.0, input),
distortion(name + "D", 10.0, overdrive),
filter_1_type(name + "F1TYP"),
filter_2_type(name + "F2TYP"),
filter_1(name + "F1", distortion, filter_1_type),
filter_2(name + "F2", filter_1, filter_2_type),
filter_1_log_scale(name + "F1LOG", ToggleParam::OFF),
filter_2_log_scale(name + "F2LOG", ToggleParam::OFF),
filter_1(name + "F1", distortion, filter_1_type, filter_1_log_scale),
filter_2(name + "F2", filter_1, filter_2_type, filter_2_log_scale),
echo(name + "E", filter_2),
reverb(name + "R", echo)
{
this->register_child(overdrive);
this->register_child(distortion);
this->register_child(filter_1_type);
this->register_child(filter_2_type);
this->register_child(filter_1_log_scale);
this->register_child(filter_2_log_scale);
this->register_child(filter_1);
this->register_child(filter_2);
this->register_child(echo);
Expand Down
2 changes: 2 additions & 0 deletions src/synth/effects.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ class Effects : public Filter< Reverb<InputSignalProducerClass> >
Distortion<InputSignalProducerClass> distortion;
typename Filter1<InputSignalProducerClass>::TypeParam filter_1_type;
typename Filter2<InputSignalProducerClass>::TypeParam filter_2_type;
ToggleParam filter_1_log_scale;
ToggleParam filter_2_log_scale;
Filter1<InputSignalProducerClass> filter_1;
Filter2<InputSignalProducerClass> filter_2;
Echo<InputSignalProducerClass> echo;
Expand Down

0 comments on commit 0961a03

Please sign in to comment.