A OFX_OutputFX can apply effects to the main output channels of a server. One can only make a single OFX_OutputFX for each server. Each OFX_OutputFX contains a OFX_Chain which handles the named effects slots and their state.
First examples:
(
s.boot;
// define which FX are going to be used.
// As OFX_OutputFX is based on OFX_Chain, these FX are the same as in OFX_Chain.
OFX_Chain.add3(
\leakDC, \filter -> { |in, leak=0.99| LeakDC.ar(in, leak) },
1,
(\leak: [0.5, 0.999, \exp])
);
OFX_Chain.add3(
\rollClip, \filter -> { |in, clip=0.99, pole=0.2|
OnePole.ar(in.clip2(clip), pole ** 0.7);
},
1,
(
\clip: [0.0, 1, \amp],
\pole: [0, 0.95, \lin]
)
);
OFX_Chain.add3(
\krush, \filter -> { |in, bits=16, downsamp=2|
var krushStep = 0.5 ** (bits + 1);
var down = Latch.ar(in, Impulse.ar(SampleRate.ir / downsamp.max(2)));
// below 1/2 downsamp, do xfade:
blend(in, down, (downsamp - 1).clip(0, 1))
.round(krushStep);
},
1,
(
\bits: [16, 1],
\downsamp: [1, 100, \exp]
)
);
OFX_Chain.add3(
\slap, \filterIn -> { |in, dtl = 0.25, dtr = 0.375, decay = 3|
CombL.ar(in, 1.0, [dtl, dtr], decay)
},
0.2,
(dtl: [0, 1], dtr: [0, 1], decay: [1, 200, \exp])
);
OFX_Chain.add3(
\comb, \filterIn -> { |in, decay = 3| CombL.ar(in * 0.3, 0.02, [0.03, 0.042], decay) },
0.2,
(decay: [0.2, 200, \exp])
);
OFX_Chain.add3(
\ampFin, \filter -> { |in, drive=1, ampLimit=0.8 |
Limiter.ar(in * drive, ampLimit);
},
1,
(
\drive: [1, 10, \exp],
\ampLimit: \amp
)
);
);
(
// An 8-channel OFX_OutputFX on server s.
// The order in slotNames determines order of execution of the efx.
m = OFX_OutputFX.new(server: s,
numChannels: 8,
slotNames: [\leakDC, \krush, \rollClip, \ampFin],
busIndex: 0
);
s.scope(8);
)
// a test signal
x = { PinkNoise.ar(0.5) + SinOsc.ar([220, 330]) * LFNoise2.kr([5, 8, 13, 21]).max(0); }.play;
// all OFX_OutputFX live here:
OFX_OutputFX.all;
// kick in predefined effects (at full wet level)
m.add(\leakDC, 1);
m.set(\leak, 0.8); // filter lows
m.add(\krush, 1); // bitcrush, downsample
m.set(\bits, 5, \downsamp, 6);
m.add(\ampFin, 1); // limit output
m.set(\drive, 10, 0.3);
// kick out predefined effects (at full wet level)
m.remove(\leakDC);
m.remove(\rollClip);
m.remove(\krush);
m.remove(\ampFin);
// remove currently unused settings
m.proxy.cleanNodeMap;
// change slotNames - only while slots are off :
m.slotNames;
// this is -> Order[\leakDC, \krush, \rollClip, \ampFin]
// drop rollClip from the list:
m.slotNames = [\leakDC, \krush, \ampFin];
// remove a OFX_OutputFX by server name
OFX_OutputFX.clear(\localhost); // clear one specific mainFX
// or simply by
m.clear
// or clear all OFX_OutputFX
OFX_OutputFX.clear;
OFX_OutputFX.all;
dictionary for all mainFX, one per server.
the OFX_OutputFX instance for the default server.
the maximum number of channels supported. (currently unused)
clear the mainFX at name
name |
server |
the server on which the OFX_OutputFX chain will run; default is server.numOutputBusChannels |
numChannels |
the number of channels it will work on |
slotNames |
the names of the filters/functions to be used, in order of execution; |
busIndex |
the bus index where it will process audio. |
the key at which the mainFX is stored; usually this is the server name.
the OFX_Chain that has the order of the effects that can be used
the NodeProxy inside the the proxyChain.
kick in effect
key |
name of effect |
wet |
wet-level of effect |
func |
an optional func that can locally replace the global func with that name. |
kick out effect
key |
name of effect |
set named parameters of the active slots
get the currently used slots of the proxyChain
get and set the slotNames of the proxyChain
the server on which this OFX_OutputFX operates
the number of output channels of the OFX_OutputFX
the index of the bus on which the OFX_OutputFX operates
the group in which this mainFX proxy runs. this is after the default group.
flag whether the mainFX is checking the final output for bad values. see also CheckBadValues
set flag whether to check final output, and if needed start the synth
the synth that does the bad value checking.
Wake up the OFX_OutputFX proxy. This happens automatically after CmdPeriod.
clear this OFX_OutputFX; usually so one can remake it.
alias for the proxyChain (the proxyChain inst var was called pxChain earlier).
show or hide the OFX_OutputFX proxy in Ndef.all for that server. the proxy is hidden by default.
Not implemented yet
name |
the name the gui will show |
numItems |
the number of buttons / sliders for parameters the gui will have |
buttonList |
an optional list of buttons. by default, this is the list of slotNames. |
parent |
the parent view or window on which to place the gui |
bounds |
the bounds of the gui |
makeSkip |
a flag whether to make and start a skipjack for the gui update mechanism. |
xxxxxxxxxx
// An example for setting up shared controls between slots:
// volume levels of both a slap delay and a comb reverb are scaled by \globalwet.
(
// first, add global spec for \globalwet:
Spec.add(\globalwet, [0, 4, \amp]);
// then make a dummy first slot function that has all global controls,
OFX_Chain.add3(
\globalz, { |globalwet = 1|
// but does not add any sound to the proxychain:
Silent.ar
}
);
// add slap delay that uses globalwet scaler
OFX_Chain.add3(
\slap, \filterIn -> { |in, globalwet = 1, dtl = 0.25, dtr = 0.3333|
DelayN.ar(in.reverse * globalwet, 1.0, [dtl, dtr])
},
0.38,
(dtl: [0, 1], dtr: [0, 1], decay: [1, 200, \exp])
);
// add simple comb reverb that uses globalwet scaler
OFX_Chain.add3(
\comb, \filterIn -> { |in, globalwet = 1, decay = 3|
CombL.ar(in * (0.3 * globalwet), 0.02, LFDNoise3.kr(0.1!2).range(0.01, 0.03), decay)
},
0.38,
(decay: [0.2, 200, \exp])
);
// make a OFX_OutputFX that uses globals
OFX_OutputFX.clear('localhost');
m = OFX_OutputFX.new(server: s,
numChannels: 2,
slotNames: [\globalz, \something, \slap, \other, \comb, \final],
busIndex: 0
);
///// add globalz by default!
m.add(\globalz);
)
// NOW, test globalwet control:
// run a simple test sound
x = { Splay.ar(Ringz.ar(Impulse.ar(0.3 * [2, 3, 5]), [2, 3, 5] * 300, 0.5/[2, 3, 5])) }.play;
m.add(\slap, 0.38); // turn on slapback
m.set(\globalwet, 0.5); // drier
m.set(\globalwet, 2); // wetter
m.set(\globalwet, 1); // normal
m.add(\comb, 0.38); // turn on comb
m.set(\globalwet, 0.25); // much drier, slap and comb!
m.set(\globalwet, 2); // wetter
m.set(\globalwet, 1); // normal again