fixed the one sided pverb, make it auto expand one channel to two
This commit is contained in:
parent
a1964b048e
commit
74068fae1c
3 changed files with 59 additions and 6 deletions
|
@ -269,6 +269,31 @@ pub fn crossfade<F: Flt>(v1: F, v2: F, mix: F) -> F {
|
||||||
v1 * (f::<F>(1.0) - mix) + v2 * mix
|
v1 * (f::<F>(1.0) - mix) + v2 * mix
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Linear crossfade with clipping the `v2` result.
|
||||||
|
///
|
||||||
|
/// This crossfade actually does clip the `v2` signal to the -1.0 to 1.0
|
||||||
|
/// range. This is useful for Dry/Wet of plugins that might go beyond the
|
||||||
|
/// normal signal range.
|
||||||
|
///
|
||||||
|
/// * `v1` - signal 1, range -1.0 to 1.0
|
||||||
|
/// * `v2` - signal 2, range -1.0 to 1.0
|
||||||
|
/// * `mix` - mix position, range 0.0 to 1.0, mid is at 0.5
|
||||||
|
#[inline]
|
||||||
|
pub fn crossfade_clip<F: Flt>(v1: F, v2: F, mix: F) -> F {
|
||||||
|
v1 * (f::<F>(1.0) - mix) + (v2 * mix).min(f::<F>(1.0)).max(f::<F>(-1.0))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Linear (f32) crossfade with driving the `v2` result through a tanh().
|
||||||
|
///
|
||||||
|
/// * `v1` - signal 1, range -1.0 to 1.0
|
||||||
|
/// * `v2` - signal 2, range -1.0 to 1.0
|
||||||
|
/// * `mix` - mix position, range 0.0 to 1.0, mid is at 0.5
|
||||||
|
#[inline]
|
||||||
|
pub fn crossfade_drive_tanh(v1: f32, v2: f32, mix: f32) -> f32 {
|
||||||
|
v1 * (1.0 - mix) + tanh_approx_drive(v2 * mix * 0.111, 0.95) * 0.9999
|
||||||
|
}
|
||||||
|
|
||||||
/// Constant power crossfade.
|
/// Constant power crossfade.
|
||||||
///
|
///
|
||||||
/// * `v1` - signal 1, range -1.0 to 1.0
|
/// * `v1` - signal 1, range -1.0 to 1.0
|
||||||
|
@ -479,6 +504,26 @@ pub fn quick_tanh(v: f32) -> f32 {
|
||||||
num / den
|
num / den
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Taken from ValleyAudio
|
||||||
|
// Copyright Dale Johnson
|
||||||
|
// https://github.dev/ValleyAudio/ValleyRackFree/tree/v2.0
|
||||||
|
// Under GPLv3 license
|
||||||
|
pub fn tanh_approx_drive(v: f32, drive: f32) -> f32 {
|
||||||
|
let x = v * drive;
|
||||||
|
|
||||||
|
if x < -1.25 {
|
||||||
|
-1.0
|
||||||
|
} else if x < -0.75 {
|
||||||
|
1.0 - (x * (-2.5 - x) - 0.5625) - 1.0
|
||||||
|
} else if x > 1.25 {
|
||||||
|
1.0
|
||||||
|
} else if x > 0.75 {
|
||||||
|
x * (2.5 - x) - 0.5625
|
||||||
|
} else {
|
||||||
|
x
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A helper function for exponential envelopes.
|
/// A helper function for exponential envelopes.
|
||||||
/// It's a bit faster than calling the `pow` function of Rust.
|
/// It's a bit faster than calling the `pow` function of Rust.
|
||||||
///
|
///
|
||||||
|
|
|
@ -104,7 +104,7 @@ impl DspNode for CQnt {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn process<T: NodeAudioContext>(
|
fn process<T: NodeAudioContext>(
|
||||||
&mut self, ctx: &mut T, _ectx: &mut NodeExecContext,
|
&mut self, ctx: &mut T, _ectx: &mut NodeExecContext,
|
||||||
nctx: &NodeContext,
|
_nctx: &NodeContext,
|
||||||
atoms: &[SAtom], inputs: &[ProcBuf],
|
atoms: &[SAtom], inputs: &[ProcBuf],
|
||||||
outputs: &mut [ProcBuf], ctx_vals: LedPhaseVals)
|
outputs: &mut [ProcBuf], ctx_vals: LedPhaseVals)
|
||||||
{
|
{
|
||||||
|
|
|
@ -200,14 +200,24 @@ impl DspNode for PVerb {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn process<T: NodeAudioContext>(
|
fn process<T: NodeAudioContext>(
|
||||||
&mut self, ctx: &mut T, _ectx: &mut NodeExecContext,
|
&mut self, ctx: &mut T, _ectx: &mut NodeExecContext,
|
||||||
_nctx: &NodeContext,
|
nctx: &NodeContext,
|
||||||
_atoms: &[SAtom], inputs: &[ProcBuf],
|
_atoms: &[SAtom], inputs: &[ProcBuf],
|
||||||
outputs: &mut [ProcBuf], ctx_vals: LedPhaseVals)
|
outputs: &mut [ProcBuf], ctx_vals: LedPhaseVals)
|
||||||
{
|
{
|
||||||
use crate::dsp::{inp, out_idx};
|
use crate::dsp::{inp, out_idx};
|
||||||
|
|
||||||
let in_l = inp::PVerb::in_l(inputs);
|
let mut in_l = inp::PVerb::in_l(inputs);
|
||||||
let in_r = inp::PVerb::in_r(inputs);
|
let mut in_r = inp::PVerb::in_r(inputs);
|
||||||
|
|
||||||
|
if (nctx.in_connected & 0x03) != 0x03 {
|
||||||
|
if nctx.in_connected & 0x01 == 0x01 {
|
||||||
|
println!("ONLY L");
|
||||||
|
in_r = in_l;
|
||||||
|
} else if nctx.in_connected & 0x02 == 0x02 {
|
||||||
|
println!("ONLY R");
|
||||||
|
in_l = in_r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let mut params = DatParams {
|
let mut params = DatParams {
|
||||||
frame: 0,
|
frame: 0,
|
||||||
|
@ -226,8 +236,6 @@ impl DspNode for PVerb {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mix = inp::PVerb::mix(inputs);
|
let mix = inp::PVerb::mix(inputs);
|
||||||
// let out_l = out::PVerb::sig_l(outputs);
|
|
||||||
// let out_r = out::PVerb::sig_r(outputs);
|
|
||||||
let out_i = out_idx::PVerb::sig_r();
|
let out_i = out_idx::PVerb::sig_r();
|
||||||
let (out_l, out_r) = outputs.split_at_mut(out_i);
|
let (out_l, out_r) = outputs.split_at_mut(out_i);
|
||||||
let out_l = &mut out_l[0];
|
let out_l = &mut out_l[0];
|
||||||
|
|
Loading…
Reference in a new issue