From 65f14260d6e70264651fcfe82173ad0a96e155fc Mon Sep 17 00:00:00 2001 From: moon2 <moon2protonmail@protonmail.com> Date: Tue, 21 Nov 2023 04:16:19 +0100 Subject: [PATCH] bl00mbox updates --- .../bl00mbox/micropython/bl00mbox/_patches.py | 25 ++-- .../bl00mbox/micropython/bl00mbox/_plugins.py | 122 ++++++++++++++---- .../radspa/standard_plugin_lib/delay.c | 2 +- .../radspa/standard_plugin_lib/distortion.c | 37 ++++-- .../radspa/standard_plugin_lib/filter.c | 90 +++++++------ .../radspa/standard_plugin_lib/flanger.c | 26 ++-- .../radspa/standard_plugin_lib/mixer.c | 4 +- 7 files changed, 203 insertions(+), 103 deletions(-) diff --git a/components/bl00mbox/micropython/bl00mbox/_patches.py b/components/bl00mbox/micropython/bl00mbox/_patches.py index 34f76868c7..794e340e3e 100644 --- a/components/bl00mbox/micropython/bl00mbox/_patches.py +++ b/components/bl00mbox/micropython/bl00mbox/_patches.py @@ -242,10 +242,7 @@ class sampler(_Patch): class sequencer(_Patch): def __init__(self, chan, num_tracks, num_steps): super().__init__(chan) - self.num_steps = num_steps - self.num_tracks = num_tracks - init_var = (self.num_steps * 256) + (self.num_tracks) # magic - self.plugins.seq = chan.new(bl00mbox.plugins.sequencer, init_var) + self.plugins.seq = chan.new(bl00mbox.plugins.sequencer, num_tracks, num_steps) self.signals.bpm = self.plugins.seq.signals.bpm self.signals.beat_div = self.plugins.seq.signals.beat_div @@ -254,6 +251,8 @@ class sequencer(_Patch): self.signals.step_start = self.plugins.seq.signals.step_start self.signals.sync_in = self.plugins.seq.signals.sync_in + self.num_tracks = num_tracks + self.num_steps = num_steps tracktable = [-32767] + ([0] * self.num_steps) self.plugins.seq.table = tracktable * self.num_tracks @@ -380,28 +379,28 @@ class karplus_strong(_Patch): self.plugins.flanger = chan._new_plugin(bl00mbox.plugins.flanger) - self.plugins.flanger.signals.resonance = 32500 + self.plugins.flanger.signals.resonance = 0 + self.plugins.flanger.signals.decay = 1000 self.plugins.flanger.signals.manual.tone = "A2" self.plugins.flanger.signals.input = self.plugins.noise.signals.output self.signals.trigger = self.plugins.noise.signals.trigger + self.signals.trigger_length = self.plugins.noise.signals.length self.signals.pitch = self.plugins.flanger.signals.manual self.signals.output = self.plugins.flanger.signals.output self.signals.level = self.plugins.flanger.signals.level self.signals.decay = self.plugins.flanger.signals.decay - self.decay = 1000 + self.signals.resonance = self.plugins.flanger.signals.resonance @property def decay(self): - return self._decay + # deprecated + return self.plugins.flanger.signals.decay.value @decay.setter def decay(self, val): - tone = self.plugins.flanger.signals.manual.tone - loss = (50 * (2 ** (-tone / 12))) // (val / 1000) - if loss < 2: - loss = 2 - self.plugins.flanger.signals.resonance = 32767 - loss - self._decay = val + # deprecated + self.plugins.flanger.signals.resonance = -2 + self.plugins.flanger.signals.decay = int(val) diff --git a/components/bl00mbox/micropython/bl00mbox/_plugins.py b/components/bl00mbox/micropython/bl00mbox/_plugins.py index c3eb2b41b8..edfb7edd00 100644 --- a/components/bl00mbox/micropython/bl00mbox/_plugins.py +++ b/components/bl00mbox/micropython/bl00mbox/_plugins.py @@ -39,10 +39,12 @@ def _fill(): for name, value in plugins_list.items(): setattr(plugins, name, _PluginDescriptor(value)) # legacy - if name == "sequencer": + if name == "sequencer" or name == "distortion": setattr(plugins, "_" + name, _PluginDescriptor(value)) - if name == "sampler": + elif name == "sampler": setattr(plugins, "_sampler_ram", _PluginDescriptor(value)) + elif name == "delay_static": + setattr(plugins, "delay", _PluginDescriptor(value)) _fill() @@ -431,12 +433,12 @@ class _Sampler(_Plugin): table[self._SAMPLE_RATE] = int(val) -""" @_plugin_set_subclass(9000) class _Distortion(_Plugin): - def symmetric_power(self, power=2, volume=32767, gate=0): - table = list(range(129)) - for num in table: + def curve_set_power(self, power=2, volume=32767, gate=0): + volume = min(max(volume, -32767), 32767) + table = [0] * 129 + for num in range(len(table)): if num < 64: ret = num / 64 # scale to [0..1[ range ret = ret**power @@ -447,25 +449,60 @@ class _Distortion(_Plugin): ret = (128 - num) / 64 # scale to [0..1] range ret = ret**power table[num] = int(volume * (1 - ret)) - gate = int(gate) >> 9 + gate = min(abs(int(gate)), 32767) >> 9 for i in range(64 - gate, 64 + gate): table[i] = 0 self.table = table + @property + def _secret_sauce(self): + table = self.table_int16_array + return table[129] + + @_secret_sauce.setter + def _secret_sauce(self, val): + val = min(max(int(val), 0), 7) + table = self.table_int16_array + table[129] = val + + @property + def curve(self): + return self.table[:129] + + @curve.setter + def curve(self, points): + # interpolation only implemented for len(points) <= 129, + # for longer lists data may be dropped. + points_size = len(points) + if not points_size: + return + table = [0] * 129 + for x, num in enumerate(table): + position = x * points_size / 129 + lower = int(position) + lerp = position - lower + if position < points_size - 1: + table[x] = int( + (1 - lerp) * points[position] + lerp * points[position + 1] + ) + else: + table[x] = int(points[points_size - 1]) + self.table = table + def __repr__(self): ret = super().__repr__() wave = self.table[:129] ret += "\n curve:\n" - ret += " " + "_"*67 + "\n" - ret += " |" + " "*67 + "|\n" + ret += " " + "_" * 67 + "\n" + ret += " |" + " " * 67 + "|\n" symbols = "UW" symbol_counter = 0 for i in range(15, -1, -1): line = " | " for k in range(63): - vals = wave[2*k:2*k+4] - upper = ((max(vals)>>8) + 128) >> 4 - lower = ((min(vals)>>8) + 128) >> 4 + vals = wave[2 * k : 2 * k + 4] + upper = ((max(vals) >> 8) + 128) >> 4 + lower = ((min(vals) >> 8) + 128) >> 4 if (i >= lower) and (i <= upper): line += symbols[symbol_counter] symbol_counter = (symbol_counter + 1) % len(symbols) @@ -473,9 +510,20 @@ class _Distortion(_Plugin): line += " " line += " |\n" ret += line - ret += " |" + "_"*67 + "|" + ret += " |" + "_" * 67 + "|" return ret -""" + + +@_plugin_set_subclass(172) +class _PolySqueeze(_Plugin): + def __init__(self, channel, plugin_id, bud_num, num_outputs=3, num_inputs=10): + if bud_num is None: + outs = min(max(num_outputs, 16), 1) + ins = min(max(num_inputs, 32), num_outputs) + init_var = outs + (ins * 256) + super().__init__(channel, plugin_id, init_var=init_var) + else: + super().__init__(channel, plugin_id, bud_num=bud_num) @_plugin_set_subclass(420) @@ -516,15 +564,11 @@ class _Osc(_Plugin): @_plugin_set_subclass(56709) class _Sequencer(_Plugin): - def __init__(self, channel, plugin_id, bud_num, init_var=None, tracks=4, steps=16): + def __init__(self, channel, plugin_id, bud_num, num_tracks=4, num_steps=16): if bud_num is None: - if init_var is None: - self.num_steps = steps % 256 - self.num_tracks = tracks % 256 - init_var = (self.num_steps * 256) + (self.num_tracks) - else: - self.num_tracks = init_var % 256 - self.num_steps = (init_var // 256) % 256 + self.num_steps = num_steps % 256 + self.num_tracks = num_tracks % 256 + init_var = (self.num_steps * 256) + (self.num_tracks) super().__init__(channel, plugin_id, init_var=init_var) @@ -593,3 +637,37 @@ class _Sequencer(_Plugin): self.trigger_start(track, step) else: self.trigger_clear(track, step) + + def save_track_pattern(self, track_index): + start = track_index * (self.num_steps + 1) + stop = start + self.num_steps + 1 + track = {} + table = self.table + if self.table[start] == -32767: + track["type"] = "trigger" + else: + track["type"] = "value" + track["steps"] = list(table[start + 1 : stop]) + return track + + def load_track_pattern(self, track, track_index): + start = track_index * (self.num_steps + 1) + table = self.table_int16_array + stop = start + 1 + min(self.num_steps, len(track["steps"])) + for i in range(start + 1, stop): + x = track["steps"][i - start - 1] + assert (x < 32768) and (x > -32768) + table[i] = x + if track["type"] == "trigger": + table[start] = -32767 + else: + table[start] = 32767 + + def save_pattern(self): + beat = {} + beat["tracks"] = [self.save_track_pattern(i) for i in range(self.num_tracks)] + return beat + + def load_pattern(self, beat): + num_tracks = min(len(beat["tracks"]), self.num_tracks) + [self.load_track_pattern(beat["tracks"][i], i) for i in range(num_tracks)] diff --git a/components/bl00mbox/radspa/standard_plugin_lib/delay.c b/components/bl00mbox/radspa/standard_plugin_lib/delay.c index 099dd82fae..f6521569bb 100644 --- a/components/bl00mbox/radspa/standard_plugin_lib/delay.c +++ b/components/bl00mbox/radspa/standard_plugin_lib/delay.c @@ -2,7 +2,7 @@ radspa_t * delay_create(uint32_t init_var); radspa_descriptor_t delay_desc = { - .name = "delay", + .name = "delay_static", .id = 42069, .description = "simple delay with ms input and feedback\n" "init_var: delay buffer length in ms, default 500", diff --git a/components/bl00mbox/radspa/standard_plugin_lib/distortion.c b/components/bl00mbox/radspa/standard_plugin_lib/distortion.c index 60625c959d..e5a9cc68b7 100644 --- a/components/bl00mbox/radspa/standard_plugin_lib/distortion.c +++ b/components/bl00mbox/radspa/standard_plugin_lib/distortion.c @@ -2,7 +2,7 @@ radspa_t * distortion_create(uint32_t init_var); radspa_descriptor_t distortion_desc = { - .name = "_distortion", + .name = "distortion", .id = 9000, .description = "distortion with linear interpolation between int16 values in plugin_table[129]", .create_plugin_instance = distortion_create, @@ -13,28 +13,36 @@ radspa_descriptor_t distortion_desc = { #define DISTORTION_OUTPUT 0 #define DISTORTION_INPUT 1 +static inline int32_t distort(int32_t input, int16_t * dist, uint8_t lerp_glitch){ + // lerp glitch is a legacy feature from a math error of the 0th gen + // pass 9 normally, pass 7 for legacy glitch + input += 32768; + uint8_t index = input >> 9; + int32_t blend = input & ((1<<lerp_glitch)-1); + int32_t ret = dist[index]*((1<<lerp_glitch)-blend) + dist[index+1]*blend; + return ret >> lerp_glitch; +} + void distortion_run(radspa_t * distortion, uint16_t num_samples, uint32_t render_pass_id){ radspa_signal_t * output_sig = radspa_signal_get_by_index(distortion, DISTORTION_OUTPUT); if(output_sig->buffer == NULL) return; int16_t * dist = distortion->plugin_table; radspa_signal_t * input_sig = radspa_signal_get_by_index(distortion, DISTORTION_INPUT); - - static int32_t ret = 0; - - for(uint16_t i = 0; i < num_samples; i++){ - - int32_t input = radspa_signal_get_value(input_sig, i, render_pass_id); - input += 32768; - uint8_t index = input>>9; - int32_t blend = input & ((1<<7)-1); - ret = dist[index]*((1<<7)-blend) + dist[index+1]*blend; - ret = ret >> 7; - radspa_signal_set_value(output_sig, i, ret); + int32_t input = radspa_signal_get_const_value(input_sig, render_pass_id); + uint8_t lerp_glitch = 9 - ((dist[129]) & 7); // legacy glitch + if(input != RADSPA_SIGNAL_NONCONST){ + radspa_signal_set_const_value(output_sig, distort(input, dist, lerp_glitch)); + } else { + for(uint16_t i = 0; i < num_samples; i++){ + int32_t input = radspa_signal_get_value(input_sig, i, render_pass_id); + radspa_signal_set_value(output_sig, i, distort(input, dist, lerp_glitch)); + } } + } radspa_t * distortion_create(uint32_t init_var){ - radspa_t * distortion = radspa_standard_plugin_create(&distortion_desc, DISTORTION_NUM_SIGNALS, 0, (1<<7) + 1); + radspa_t * distortion = radspa_standard_plugin_create(&distortion_desc, DISTORTION_NUM_SIGNALS, 0, (1<<7) + 2); if(distortion == NULL) return NULL; distortion->render = distortion_run; radspa_signal_set(distortion, DISTORTION_OUTPUT, "output", RADSPA_SIGNAL_HINT_OUTPUT, 0); @@ -49,6 +57,7 @@ radspa_t * distortion_create(uint32_t init_var){ dist[i] = -((128-i)*(128-i)*32767>>12) + 32767; } } + dist[129] = 0; return distortion; } diff --git a/components/bl00mbox/radspa/standard_plugin_lib/filter.c b/components/bl00mbox/radspa/standard_plugin_lib/filter.c index 7096e52786..b821b827b1 100644 --- a/components/bl00mbox/radspa/standard_plugin_lib/filter.c +++ b/components/bl00mbox/radspa/standard_plugin_lib/filter.c @@ -22,6 +22,8 @@ radspa_descriptor_t filter_desc = { #define FILTER_MODE_BANDPASS 1 #define FILTER_MODE_HIGHPASS 2 +#define INV_NORM_BOOST 5 + static inline int32_t approx_cos(uint32_t x){ // x: full circle: 1<<32 // return val: 1<<30 <=> 1 @@ -37,17 +39,17 @@ static inline int32_t approx_cos(uint32_t x){ static inline void get_mode_coeffs(uint8_t mode, filter_data_t * data, int32_t * coeffs){ switch(mode){ case FILTER_MODE_LOWPASS: - coeffs[1] = ((1L<<21) - data->cos_omega) * data->inv_norm; - coeffs[0] = coeffs[1]/2; + coeffs[1] = ((((1L<<21) - data->cos_omega)>>INV_NORM_BOOST) * data->inv_norm)>>1; + coeffs[0] = coeffs[1]>>1; coeffs[2] = coeffs[0]; break; case FILTER_MODE_BANDPASS: - coeffs[0] = data->alpha * data->inv_norm; + coeffs[0] = (data->alpha>>INV_NORM_BOOST) * data->inv_norm; coeffs[1] = 0; coeffs[2] = -coeffs[0]; break; case FILTER_MODE_HIGHPASS: - coeffs[1] = -((1L<<21) + data->cos_omega) * data->inv_norm; + coeffs[1] = ((-((1L<<21) + data->cos_omega)>>INV_NORM_BOOST) * data->inv_norm)>>1; coeffs[0] = -coeffs[1]/2; coeffs[2] = coeffs[0]; break; @@ -64,48 +66,56 @@ static inline void get_coeffs(filter_data_t * data, int16_t pitch, int16_t reso, if(freq > (3UL<<29)) freq = 3UL<<29; // unit: 1<<21 <=> 1, range: [0..1<<21] - data->cos_omega = approx_cos(freq)>>9; + int32_t cos_omega = approx_cos(freq)>>9; // unit: 1<<21 <=> 1, range: [0..3<<21] - data->alpha = approx_cos(freq + (3UL<<30))/mqi; - // unit transform from 1<<21 to 1<<29 <=> 1 - data->inv_norm = (1L<<29)/((1L<<21) + data->alpha); + int32_t alpha = approx_cos(freq + (3UL<<30))/mqi; + // unit transform from 1<<21 to 1<<30 <=> 1 + int32_t inv_norm = (1L<<30)/(((1L<<(21)) + alpha)>>INV_NORM_BOOST); + + data->cos_omega = cos_omega; + data->alpha = alpha; + data->inv_norm = inv_norm; - data->pitch_prev = pitch; - data->reso_prev = reso; } if((pitch != data->pitch_prev) || (reso != data->reso_prev) || (mode != data->mode_prev)){ // unit for {in/out}_coeffs: 1<<29 <=> 1, range: full - data->out_coeffs[1] = -2*data->cos_omega * data->inv_norm; - data->out_coeffs[2] = ((1<<21) - data->alpha) * data->inv_norm; + data->out_coeffs[1] = (-data->cos_omega>>INV_NORM_BOOST) * data->inv_norm; + data->out_coeffs[2] = ((((1<<21) - data->alpha)>>INV_NORM_BOOST) * data->inv_norm) >> 1; if(mode == -32767){ get_mode_coeffs(FILTER_MODE_LOWPASS, data, data->in_coeffs); - return; } else if(mode == 0){ get_mode_coeffs(FILTER_MODE_BANDPASS, data, data->in_coeffs); - return; } else if(mode == 32767){ get_mode_coeffs(FILTER_MODE_HIGHPASS, data, data->in_coeffs); - return; - } - int32_t a[3]; - int32_t b[3]; - int32_t blend = mode; - if(mode < 0){ - get_mode_coeffs(FILTER_MODE_LOWPASS, data, a); - get_mode_coeffs(FILTER_MODE_BANDPASS, data, b); - blend += 32767; } else { - get_mode_coeffs(FILTER_MODE_BANDPASS, data, a); - get_mode_coeffs(FILTER_MODE_HIGHPASS, data, b); - } - blend = blend << 16; - for(uint8_t i = 0; i<3; i++){ - data->in_coeffs[i] = ((int64_t) b[i] * blend) >> 32; - data->in_coeffs[i] += ((int64_t) a[i] * ((1L<<31) - blend)) >> 32; - data->in_coeffs[i] = data->in_coeffs[i] << 1; + int32_t a[3]; + int32_t b[3]; + int32_t blend = mode; + if(mode < 0){ + get_mode_coeffs(FILTER_MODE_LOWPASS, data, a); + get_mode_coeffs(FILTER_MODE_BANDPASS, data, b); + blend += 32767; + } else { + get_mode_coeffs(FILTER_MODE_BANDPASS, data, a); + get_mode_coeffs(FILTER_MODE_HIGHPASS, data, b); + } + blend = blend << 16; + for(uint8_t i = 0; i<3; i++){ + data->in_coeffs[i] = ((int64_t) b[i] * blend) >> 32; + data->in_coeffs[i] += ((int64_t) a[i] * ((1L<<31) - blend)) >> 32; + data->in_coeffs[i] = data->in_coeffs[i] << 1; + } + data->const_output = RADSPA_SIGNAL_NONCONST; } - data->const_output = RADSPA_SIGNAL_NONCONST; + /* + printf("cos_omega: %ld alpha: %ld inv_norm: %ld\n",data->cos_omega, data->alpha, data->inv_norm); + printf("in_coeffs: %ld %ld %ld\n",data->in_coeffs[0], data->in_coeffs[1], data->in_coeffs[2]); + printf("out_coeffs: %ld %ld\n", data->out_coeffs[1], data->out_coeffs[2]); + */ } + data->pitch_prev = pitch; + data->reso_prev = reso; + data->mode_prev = mode; } void filter_run(radspa_t * filter, uint16_t num_samples, uint32_t render_pass_id){ @@ -131,7 +141,7 @@ void filter_run(radspa_t * filter, uint16_t num_samples, uint32_t render_pass_id int16_t reso = reso_const; int16_t mode = mode_const; int16_t mix = mix_const; - int16_t input = input_const; + int32_t input = input_const; bool always_update_coeffs = true; if((pitch_const != RADSPA_SIGNAL_NONCONST) && (reso_const != RADSPA_SIGNAL_NONCONST) && (mode_const != RADSPA_SIGNAL_NONCONST)){ @@ -159,16 +169,15 @@ void filter_run(radspa_t * filter, uint16_t num_samples, uint32_t render_pass_id } if(input_const == RADSPA_SIGNAL_NONCONST) input = radspa_signal_get_value(input_sig, i, render_pass_id); - int32_t in = radspa_clip(radspa_gain(input, gain)); data->pos++; if(data->pos >= 3) data->pos = 0; - data->in_history[data->pos] = in << 12; + data->in_history[data->pos] = input << 12; int32_t ret = ((int64_t) data->in_coeffs[0] * data->in_history[data->pos]) >> 32; - for(int8_t i = 1; i<3; i++){ + for(int8_t i = 1; i < 3; i++){ int8_t pos = data->pos - i; if(pos < 0) pos += 3; ret += ((int64_t) data->in_history[pos] * data->in_coeffs[i]) >> 32; @@ -179,10 +188,9 @@ void filter_run(radspa_t * filter, uint16_t num_samples, uint32_t render_pass_id } else if(ret <= -(1L<<28)){ ret = 1-(1L<<28); } - ret = ret << 3; - data->out_history[data->pos] = ret; + data->out_history[data->pos] = ret << 3; - ret = ret >> 12; + ret = ret >> 9; if(reso < 0) ret = input - (ret<<1); //allpass mode if(mix == -32767){ @@ -192,10 +200,10 @@ void filter_run(radspa_t * filter, uint16_t num_samples, uint32_t render_pass_id } else if(mix != 32767){ ret *= mix; int32_t dry_vol = mix > 0 ? 32767 - mix : 32767 + mix; - ret += radspa_gain(dry_vol, gain) * input; + ret += dry_vol * input; ret = ret >> 15; } - out[i] = radspa_clip(ret); + out[i] = radspa_clip(radspa_gain(ret, gain)); } if(input_const == RADSPA_SIGNAL_NONCONST){ diff --git a/components/bl00mbox/radspa/standard_plugin_lib/flanger.c b/components/bl00mbox/radspa/standard_plugin_lib/flanger.c index 44b21543f3..40dee9c70e 100644 --- a/components/bl00mbox/radspa/standard_plugin_lib/flanger.c +++ b/components/bl00mbox/radspa/standard_plugin_lib/flanger.c @@ -22,13 +22,13 @@ radspa_descriptor_t flanger_desc = { #define FLANGER_LEVEL 5 #define FLANGER_MIX 6 -static inline int16_t fixed_point_list_access(int32_t * buf, uint32_t fp_index, uint32_t buf_len){ - uint32_t index = (fp_index) >> (FIXED_POINT_DIGITS); +static inline int32_t fixed_point_list_access(int32_t * buf, int32_t fp_index, uint32_t buf_len){ + int32_t index = (fp_index) >> (FIXED_POINT_DIGITS); while(index >= buf_len) index -= buf_len; - uint32_t next_index = index + 1; + int32_t next_index = index + 1; while(next_index >= buf_len) next_index -= buf_len; - uint32_t subindex = (fp_index) & ((1<<(FIXED_POINT_DIGITS)) - 1); + int32_t subindex = (fp_index) & ((1<<(FIXED_POINT_DIGITS)) - 1); int32_t ret = buf[index] * ((1<<(FIXED_POINT_DIGITS)) - subindex); ret += (buf[next_index]) * subindex; ret = ret >> (FIXED_POINT_DIGITS); @@ -61,7 +61,7 @@ void flanger_run(radspa_t * flanger, uint16_t num_samples, uint32_t render_pass_ radspa_signal_t * mix_sig = radspa_signal_get_by_index(flanger, FLANGER_MIX); int32_t reso = radspa_signal_get_value(reso_sig, 0, render_pass_id); - reso = reso << 16; + reso = reso << 14; int32_t level = radspa_signal_get_value(level_sig, 0, render_pass_id); int32_t mix = radspa_signal_get_value(mix_sig, 0, render_pass_id); int32_t decay = radspa_signal_get_value(decay_sig, 0, render_pass_id); @@ -78,9 +78,9 @@ void flanger_run(radspa_t * flanger, uint16_t num_samples, uint32_t render_pass_ int32_t sgn_decay = decay > 0 ? 1 : -1; int32_t abs_decay = decay * sgn_decay; if((abs_decay != data->abs_decay_prev) || (manual != data->manual_prev)){ - int32_t decay_invert = - ((data->read_head_offset * 50) >> FIXED_POINT_DIGITS)/decay; - decay_invert += 34614; // magic number - data->decay_reso = radspa_sct_to_rel_freq(radspa_clip(decay_invert), 0) >> 1; + int32_t decay_invert = - ((data->read_head_offset * 50) >> FIXED_POINT_DIGITS)/abs_decay; + decay_invert += 34614 - 4800 - 2400; // magic number + data->decay_reso = radspa_sct_to_rel_freq(radspa_clip(decay_invert), 0); } int32_t tmp = reso + sgn_decay * data->decay_reso; if((sgn_decay == 1) && (tmp < reso)){ @@ -103,8 +103,14 @@ void flanger_run(radspa_t * flanger, uint16_t num_samples, uint32_t render_pass_ while(data->read_head_position < 0) data->read_head_position += VARIABLE_NAME; //underflow buf[data->write_head_position] = dry; - int32_t wet = fixed_point_list_access(buf, data->read_head_position, FLANGER_BUFFER_SIZE) << 1; - buf[data->write_head_position] += ((int64_t) wet * reso) >> 32; + int32_t wet = fixed_point_list_access(buf, data->read_head_position, FLANGER_BUFFER_SIZE) << 3; + bool sgn_wet = wet > 0; + bool sgn_reso = reso > 0; + if(sgn_wet != sgn_reso){ + buf[data->write_head_position] -= ((int64_t) (-wet) * reso) >> 32; + } else { + buf[data->write_head_position] += ((int64_t) wet * reso) >> 32; + } int32_t ret = radspa_add_sat(radspa_mult_shift(dry, dry_vol), radspa_mult_shift(radspa_clip(wet), mix)); ret = radspa_clip(radspa_gain(ret, level)); diff --git a/components/bl00mbox/radspa/standard_plugin_lib/mixer.c b/components/bl00mbox/radspa/standard_plugin_lib/mixer.c index 1b07a26147..4dcd5011d9 100644 --- a/components/bl00mbox/radspa/standard_plugin_lib/mixer.c +++ b/components/bl00mbox/radspa/standard_plugin_lib/mixer.c @@ -86,7 +86,7 @@ void mixer_run(radspa_t * mixer, uint16_t num_samples, uint32_t render_pass_id){ for(uint16_t i = 0; i < num_samples; i++){ bool invert = data->dc < 0; if(invert) data->dc = -data->dc; - data->dc = ((uint64_t) data->dc * (((1<<12) - 1)<<20)) >> 32; + data->dc = ((uint64_t) data->dc * (((1UL<<12) - 1)<<20)) >> 32; if(invert) data->dc = -data->dc; data->dc += ret[i]; ret[i] -= (data->dc >> 12); @@ -96,7 +96,7 @@ void mixer_run(radspa_t * mixer, uint16_t num_samples, uint32_t render_pass_id){ for(uint16_t i = 0; i < num_samples; i++){ bool invert = data->dc < 0; if(invert) data->dc = -data->dc; - data->dc = ((uint64_t) data->dc * (((1<<12) - 1)<<20)) >> 32; + data->dc = ((uint64_t) data->dc * (((1UL<<12) - 1)<<20)) >> 32; if(invert) data->dc = -data->dc; ret[i] = -(data->dc >> 12); ret_init = true; -- GitLab