Skip to content

Commit

Permalink
Fix a crash in SiEffectStereoChorus when changing parameters on the fly
Browse files Browse the repository at this point in the history
Also rework effects in the example project to
remove reallocation every time something
changes. Which is what uncovered the bug.
  • Loading branch information
YuriSizov committed Dec 2, 2024
1 parent b037d0f commit 613f689
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 37 deletions.
77 changes: 41 additions & 36 deletions example/globals/MusicPlayer.gd
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ const AVAILABLE_FILTERS := [
var _driver: SiONDriver = null
var _active_instrument: Instrument = null
var _active_instrument_index: int = 0
var _effects: Array[SiEffectBase] = []
var _active_effect: SiEffectBase = null

var _active_filter_index: int = 0
var _active_filter_power: int = 0
Expand All @@ -66,6 +68,15 @@ func initialize() -> void:
_update_instrument()
instrument_changed.emit()

_effects.resize(AVAILABLE_FILTERS.size())
_effects[0] = SiEffectStereoDelay.new();
_effects[1] = SiEffectStereoChorus.new()
_effects[2] = SiEffectStereoReverb.new()
_effects[3] = SiEffectDistortion.new()
_effects[4] = SiFilterLowBoost.new()
_effects[5] = SiEffectCompressor.new()
_effects[6] = SiControllableFilterHighPass.new()


func _update_instrument() -> void:
_active_instrument.clear()
Expand All @@ -89,45 +100,39 @@ func _update_instrument() -> void:


func _update_filter() -> void:
_driver.get_effector().clear_slot_effects(0)
if _active_filter_power <= 5:
_active_effect = null
_driver.get_effector().clear_slot_effects(0)
return

match _active_filter_index:
0:
var effect_delay := SiEffectStereoDelay.new()
effect_delay.set_params((300.0 * _active_filter_power) / 100.0, 0.1, false)
_driver.get_effector().add_slot_effect(0, effect_delay);

1:
var effect_chorus := SiEffectStereoChorus.new()
effect_chorus.set_params(20, 0.2, 4, 10 + ((50.0 * _active_filter_power) / 100.0))
_driver.get_effector().add_slot_effect(0, effect_chorus);

2:
var effect_reverb := SiEffectStereoReverb.new()
effect_reverb.set_params(0.7, 0.4 + ((0.5 * _active_filter_power) / 100.0), 0.8, 0.3)
_driver.get_effector().add_slot_effect(0, effect_reverb);

3:
var effect_distortion := SiEffectDistortion.new()
effect_distortion.set_params(-20 - ((80.0 * _active_filter_power) / 100.0), 18, 2400, 1)
_driver.get_effector().add_slot_effect(0, effect_distortion);

4:
var effect_lowboost := SiFilterLowBoost.new()
effect_lowboost.set_params(3000, 1, 4 + ((6.0 * _active_filter_power) / 100.0))
_driver.get_effector().add_slot_effect(0, effect_lowboost);

5:
var effect_compressor := SiEffectCompressor.new()
effect_compressor.set_params(0.7, 50, 20, 20, -6, 0.2 + ((0.6 * _active_filter_power) / 100.0))
_driver.get_effector().add_slot_effect(0, effect_compressor);

6:
var effect_highpass := SiControllableFilterHighPass.new()
effect_highpass.set_params_manually(((1.0 * _active_filter_power) / 100.0), 0.9)
_driver.get_effector().add_slot_effect(0, effect_highpass);
var next_effect := _effects[_active_filter_index]
if next_effect != _active_effect:
_active_effect = next_effect
_driver.get_effector().clear_slot_effects(0)
_driver.get_effector().add_slot_effect(0, _active_effect)

# Most of the values set here are default values for the corresponding arguments.

if _active_effect is SiEffectStereoDelay:
_active_effect.set_params((300.0 * _active_filter_power) / 100.0, 0.1, false)

elif _active_effect is SiEffectStereoChorus:
_active_effect.set_params(20, 0.2, 4, 10 + ((50.0 * _active_filter_power) / 100.0))

elif _active_effect is SiEffectStereoReverb:
_active_effect.set_params(0.7, 0.4 + ((0.5 * _active_filter_power) / 100.0), 0.8, 0.3)

elif _active_effect is SiEffectDistortion:
_active_effect.set_params(-20 - ((80.0 * _active_filter_power) / 100.0), 18, 2400, 1)

elif _active_effect is SiFilterLowBoost:
_active_effect.set_params(3000, 1, 4 + ((6.0 * _active_filter_power) / 100.0))

elif _active_effect is SiEffectCompressor:
_active_effect.set_params(0.7, 50, 20, 20, -6, 0.2 + ((0.6 * _active_filter_power) / 100.0))

elif _active_effect is SiControllableFilterHighPass:
_active_effect.set_params_manually(((1.0 * _active_filter_power) / 100.0), 0.9)


# Configuration.
Expand Down
6 changes: 5 additions & 1 deletion src/effector/effects/si_effect_stereo_chorus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ void SiEffectStereoChorus::set_params(double p_delay_time, double p_feedback, do
}
_phase_table.resize_zeroed(table_size);

if (_lfo_phase >= _phase_table.size()) {
_lfo_phase = 0;
}

double depth_step = 6.283185307179586 / table_size;
double depth_value = 0;
for (int i = 0; i < table_size; i++) {
Expand Down Expand Up @@ -94,7 +98,7 @@ int SiEffectStereoChorus::process(int p_channels, Vector<double> *r_buffer, int
_process_lfo(r_buffer, i, step);

_lfo_phase++;
if (_lfo_phase == _phase_table.size()) {
if (_lfo_phase >= _phase_table.size()) {
_lfo_phase = 0;
}

Expand Down

0 comments on commit 613f689

Please sign in to comment.