Preformatted text
Hi list,
More than ten years ago I made an FFT kind of matrix thing, using Instr and Patch. In the meantime, life happened and since up until a couple of months ago I barely touched SC3. I’m slowly getting used to Supercollider these days, and I’m loving it all over again.
I managed to refractor the barebones of my code using Synthdef.wrap instead of using felix’s crucial library. I remember even back in the day having problems with order of execution and integrating it with vanilla sc3, witch is a pity because it worked like a charm otherwise.
The idea of the patch is to have just one FFT and IFFT process, but with interchangeable PV ugens in between, to facilitate experimentation: FFT --> PV_ugen --> PV Ugen --> IFFT, where the PV_ugens are selectable from a list.
So far the refractor is kinda working, but with these caveats:
-
The first time I press Play on a clean server, it complains with a Synthdef not found message.
-
I press Stop. I press Play again, and this time it sounds.
-
I click Stop. Change some ugen in the chain.
-
I click Play. The process sounds, but with the old pv ugen in the chain.
-
I click Stop. I don’t change anything. I click play, and this time the correct ugen in the chain sounds.
-
etc.
So far I have been {}.defer ing blocks of stuff more or less at random with no results. I understand there is a mismatch with what the server has vs. what I’m sending from the language, but I can’t see it at this point… Please help!
This is the patch. Please note that it takes its stereo input from channels 4 and 5:
(
var pvProcess, makeEffect;
var win;
var synth, btnPlay, sldMagstretch, sldMagshift;
var sldBinstretch, sldBinshift;
var sldWipe, sldWidth, btnTrigger;
var btnChain1, btnChain2;
~fxgroup = Group.tail(s);
pvProcess = [
{{ arg chain, whatever, magstretch, magshift;
chain = PV_MagShift( chain, magstretch, magshift )
}},
{{ arg chain, whatever, binstretch, binshift;
chain = PV_BinShift( chain, binstretch, binshift )
}},
{{arg chain, whatever, wipe, width=0.1, trigger;
chain = PV_BinScramble( chain, wipe, width, trigger )
}}
];
makeEffect = { |name, func, func2, lags, numChannels = 2|
SynthDef(name, { | i_bus = 0, gate = 1, inbus=4, hopsize=0.25, wintype=0, out=0 |
var in, chain, output;
in = In.ar( inbus, 2);
chain = FFT({LocalBuf(2048, 1)}.dup, in, hopsize, wintype);
chain = SynthDef.wrap(func, lags, [chain, chain]);
chain = SynthDef.wrap(func2, lags, [chain, chain]);
output = Out.ar(out, 0.1 * IFFT(chain));
} ).add;
};
// GUI
win = Window("FTT Matrix", Rect(580, 450, 460, 150)).front.alwaysOnTop_(true);
btnPlay = Button().states_([["Play"], ["Stop"]]);
btnChain1 = PopUpMenu().items_([ "magshift", "binshift", "Scramble" ]).valueAction_(0);
btnChain2 = PopUpMenu().items_([ "magshift", "binshift", "Scramble" ]).valueAction_(1);
sldMagstretch = LayoutValueSlider(nil, nil, 1, [0.1, 4]);
sldMagshift = LayoutValueSlider(nil, nil, 0, [0, 100]);
sldBinstretch = LayoutValueSlider(nil, nil, 1, [0.1, 4]);
sldBinshift = LayoutValueSlider(nil, nil, 0, [0, 100]);
sldWipe = LayoutValueSlider(nil, nil, 1, [0, 1]);
sldWidth = LayoutValueSlider(nil, nil, 0.1, [0, 1]);
btnTrigger = Button().states_([["Trigger"]]);
win.layout = VLayout(
btnPlay, 10,
btnChain1,
btnChain2, 20,
StaticText().string_("MagShift"),
HLayout(
sldMagstretch.asView, StaticText().string_("Stretch"), 20,
sldMagshift.asView, StaticText().string_("Shift"),
), 10,
StaticText().string_("BinShift"),
HLayout(
sldBinstretch.asView, StaticText().string_("Stretch"), 20,
sldBinshift.asView, StaticText().string_("Shift"),
), 10,
StaticText().string_("Scramble"),
HLayout(
sldWipe.asView,
sldWidth.asView,
btnTrigger,
),
);
btnPlay.action_{
if (btnPlay.value == 1) {
{makeEffect.value(\fftMatrix,
pvProcess[btnChain1.value].value,
pvProcess[btnChain2.value].value,
nil,
2
)}.defer;
synth = Synth(\fftMatrix, [
magstretch: sldMagstretch.value,
magshift: sldMagshift.value,
binstretch: sldBinstretch.value,
binshift: sldBinshift.value,
wipe: sldWipe.value,
width: sldWidth.value,
trigger: btnTrigger.value,
], ~fxgroup, \addToTail) }
{ synth.free }
};
sldMagstretch.action_{
if (btnPlay.value==1, {synth.set(\magstretch, sldMagstretch.value)})
};
sldMagshift.action_{
if (btnPlay.value==1, {synth.set(\magshift, sldMagshift.value)})
};
sldBinstretch.action_{
if (btnPlay.value==1, {synth.set(\binstretch, sldBinstretch.value)})
};
sldBinshift.action_{
if (btnPlay.value==1, {synth.set(\binshift, sldBinshift.value)})
};
sldWipe.action_{
if (btnPlay.value==1, {synth.set(\wipe, sldWipe.value)})
};
sldWidth.action_{
if (btnPlay.value==1, {synth.set(\width, sldWidth.value)})
};
btnTrigger.action_{
{synth.set(\trigger, btnTrigger.value)}
};
)
Kindest regards, Mario.