150 lines
3.2 KiB
Racket
150 lines
3.2 KiB
Racket
#lang scribble/manual
|
|
@(require (for-label racket))
|
|
|
|
@title{LocalIn}
|
|
Define and read from buses local to a synth.@section{related}
|
|
Classes/LocalOut
|
|
@section{categories}
|
|
UGens>InOut
|
|
|
|
@section{description}
|
|
|
|
|
|
LocalIn defines buses that are local to the enclosing synth. These are
|
|
like the global buses, but are more convenient if you want to implement a
|
|
self contained effect that uses a feedback processing loop.
|
|
|
|
There can only be one audio rate and one control rate LocalIn per
|
|
SynthDef. The audio can be written to the bus using
|
|
link::Classes/LocalOut:: .
|
|
|
|
@section{warning}
|
|
|
|
Audio written to a link::Classes/LocalOut:: will not be read by a
|
|
corresponding LocalIn until the next cycle, i.e. one block size of
|
|
samples later. Because of this it is important to take this additional
|
|
delay into account when using LocalIn to create feedback delays with
|
|
delay times shorter than the threshold of pitch (i. e. < 0.05
|
|
seconds or > 20Hz), or where sample accurate alignment is required.
|
|
See the resonator example below.
|
|
::
|
|
|
|
@section{classmethods}
|
|
|
|
|
|
@section{method}
|
|
ar, kr
|
|
|
|
@section{argument}
|
|
numChannels
|
|
|
|
The number of channels (i.e. adjacent buses) to read in. You
|
|
cannot modulate this number by assigning it to an argument in a
|
|
SynthDef.
|
|
|
|
@section{argument}
|
|
default
|
|
|
|
The initial value written to the bus once, so that it can be used before overwriting it with LocalOut. An array can be passed in to specify different values for each channel.
|
|
|
|
|
|
@section{Examples}
|
|
|
|
|
|
|
|
@racketblock[
|
|
(
|
|
{
|
|
var source, local;
|
|
|
|
source = Decay.ar(Impulse.ar(0.3), 0.1) * WhiteNoise.ar(0.2);
|
|
local = LocalIn.ar(2) + [source, 0]; // read feedback, add to source
|
|
local = DelayN.ar(local, 0.2, 0.2); // delay sound
|
|
|
|
// reverse channels to give ping pong effect, apply decay factor
|
|
LocalOut.ar(local.reverse * 0.8);
|
|
|
|
local
|
|
}.play;
|
|
)
|
|
|
|
(
|
|
{
|
|
var local, in;
|
|
|
|
in = Mix.fill(12, {
|
|
Pan2.ar(
|
|
Decay2.ar(Dust.ar(0.05), 0.1, 0.5, 0.1)
|
|
* FSinOsc.ar(IRand(36,84).midicps).cubed.max(0),
|
|
Rand(-1,1))
|
|
});
|
|
in = in + Pan2.ar(Decay2.ar(Dust.ar(0.03), 0.04, 0.3) * BrownNoise.ar, 0);
|
|
|
|
4.do { in = AllpassN.ar(in, 0.03, {Rand(0.005,0.02)}.dup, 1); };
|
|
|
|
local = LocalIn.ar(2) * 0.98;
|
|
local = OnePole.ar(local, 0.5);
|
|
|
|
local = Rotate2.ar(local[0], local[1], 0.23);
|
|
local = AllpassN.ar(local, 0.05, {Rand(0.01,0.05)}.dup, 2);
|
|
|
|
local = DelayN.ar(local, 0.3, [0.19,0.26]);
|
|
local = AllpassN.ar(local, 0.05, {Rand(0.03,0.15)}.dup, 2);
|
|
|
|
local = LeakDC.ar(local);
|
|
local = local + in;
|
|
|
|
LocalOut.ar(local);
|
|
|
|
local
|
|
|
|
}.play;
|
|
)
|
|
|
|
(
|
|
{
|
|
var local, in, amp;
|
|
|
|
in = SoundIn.ar([0, 1]);
|
|
|
|
amp = Amplitude.kr(Mix.ar(in));
|
|
in = in * (amp > 0.02); // noise gate
|
|
|
|
local = LocalIn.ar(2);
|
|
local = OnePole.ar(local, 0.4);
|
|
local = OnePole.ar(local, -0.08);
|
|
|
|
local = Rotate2.ar(local[0], local[1], 0.2);
|
|
|
|
local = DelayN.ar(local, 0.25, 0.25);
|
|
|
|
local = LeakDC.ar(local);
|
|
local = ((local + in) * 1.25).softclip;
|
|
|
|
LocalOut.ar(local);
|
|
local * 0.1;
|
|
}.play;
|
|
)
|
|
|
|
// Resonator, must subtract blockSize for correct tuning
|
|
(
|
|
{
|
|
var in, imp, sound;
|
|
|
|
in = LocalIn.ar(1);
|
|
imp = Impulse.ar(1);
|
|
sound = DelayC.ar(imp + (in * 0.995), 1, 440.reciprocal - ControlRate.ir.reciprocal);
|
|
LocalOut.ar(sound); // for feedback
|
|
in
|
|
}.play;
|
|
|
|
// compare pitch
|
|
{
|
|
SinOsc.ar(440, 0, 0.2)
|
|
}.play(s, 1);
|
|
)
|
|
::
|
|
|
|
]
|
|
|
|
|