Skip to content

Commit

Permalink
Create autopan.dsp
Browse files Browse the repository at this point in the history
  • Loading branch information
DBraun authored and sletz committed Apr 17, 2023
1 parent aa3f4ed commit 4b26c32
Showing 1 changed file with 59 additions and 0 deletions.
59 changes: 59 additions & 0 deletions examples/misc/autopan.dsp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//--------------------------autopan----------------------------
//
// For a stereo input, adjust the left and right gains
// according to rate-synced sine oscillators. This example is
// reverse-engineered from Ableton Live's "Auto Pan" audio
// effect. We don't implement the "spin" feature in which
// the two LFOs could have different frequencies.
// We also don't use other LFOs such as triangle/square/noise.
//
// #### Usage
//
// ```
// si.bus(2) : autopan(amount, rate, phase, shape) : si.bus(2)
// ```
//
// Where:
//
// * `amount`: Adjusts the amount of LFO modulation that is
// applied to incoming signals
// * `rate`: Sets the frequency of the LFO in Hertz.
// * `phase`: Adjusts the amount of the offset between the
// waveforms for the left and right channel. At 180,
// the LFOs will be perfectly out of phase. For other
// values, you will hear more moments where the the
// overall volume is reduced.
// * `shape`: Turning `shape` up pushes the waveforms to their
// upper and lower limits, "hardening" their shape.
//------------------------------------------------------------
import("stdfaust.lib");

autopan(amount, rate, phase, shape) = _*gainLeft, _*gainRight
with {

// A saturator
// Assume `x` is a signal between -1 and 1. This function
// pushes the output towards -1 and 1. As the shape
// parameter goes from 0 to 1, an input sine will become
// closer to a square. If `shape` is zero, then the
// function doesn't change the input signal.
saturator(shape, x) = result
with {
// It's ok to replace tanh with another saturator
result = x, ma.tanh(x*10.) : it.interpolate_linear(shape);
};

phase2Gain(phase) = os.oscp(rate, phase)
: saturator(shape) // comment out this line to remove the saturator
: it.remap(-1., 1., 1.-amount, 1.);

gainLeft = 0. : phase2Gain;
gainRight = phase : ma.deg2rad : phase2Gain;
};

amount = hslider("[0]Amount[style:knob]", 0., 0., 1., .001);
rate = hslider("[1]Rate[style:knob][unit:Hz][scale:log]", 1., .05, 90., .001);
phase = hslider("[2]Phase[style:knob][unit:°]", 180., 0., 360., 15) : si.smoo;
shape = hslider("[3]Shape[style:knob]", 0., 0., 1., 0.001) : si.smoo;

process = hgroup("Auto Pan", autopan(amount, rate, phase, shape));

0 comments on commit 4b26c32

Please sign in to comment.