christophe lengelé
2014-10-08 14:44:45 UTC
Hello,
By trying to build a spectral filter with GUI, I've found a problem with Plotter,
by specifying e.g. an exponential domainSpecs (\freq.asSpec) and trying to edit the values :
a = (0..200).scramble.plot;
a.editMode_(true);
a.domainSpecs = \freq.asSpec; a.refresh; // the edition does not match with the representation
Below is the spectral filter code with GUI reworked, coming from an example of a previous post :
http://new-supercollider-mailing-lists-forums-use-these.2681727.n2.nabble.com/Choosing-specific-FFT-bins-td5423719.html#a5424690
How to get an exponential representation (and correct edition) of domainSpecs with \freq.asSpec instead of linear bin representation ?
Thanks for the help,
Christophe
(
var w, loader;
s = Server.local;
~fftsize = 1024; // FFTsize containing for each bin -> magnitude and phase
~nbOfBins = ~fftsize / 2;
loader = {
SynthDef(\fftEQ, { arg out=0, fftsize= ~fftsize, bufnum=1;
var in, filtered, chain;
in = WhiteNoise.ar(0.3);
chain = FFT(LocalBuf(fftsize), in);
filtered = PV_MagMul(chain, bufnum);
Out.ar(out, Pan2.ar(IFFT(filtered), 0.0));
}).add;
~eqbuf = Buffer.alloc(s, ~fftsize, 1);
~eqBufValues = 0 ! ~fftsize; // initialize FFT buffer values
~eqbuf.loadCollection(~eqBufValues); // initialize FFT-buffer
~magValues = 0 ! ~nbOfBins; // // initialize magnitude values
s.sync;
~binResolution = (s.sampleRate / ~fftsize).postln;
w = Window("SpecEQ", Rect(200, 450, 10+(~nbOfBins), 250), false).alwaysOnTop_(true).front;
w.view.decorator = FlowLayout(w.view.bounds);
// Plotter
~plotterView = Plotter("FFT Filtering", Rect(0, 0, (~nbOfBins), 180), w)
.value_(~magValues)
.editMode_(true)
.resolution_(0.1)
.plotMode_(\levels)
.specs_([0, 1, \lin, 0.001 ].asSpec)
// .domainSpecs_(\freq.asSpec);
.editFunc = { |plotter, plotIndex, i, val|
("Bin index: "++ i ++" --- from "++ (~binResolution * i).asInt ++ " to " ++ (~binResolution * i + i).asInt ++ " Hz ::: "++ val).postln;
~magValues[i] = val;
~eqBufValues = [~magValues, (0 ! (~nbOfBins))].flop.flat;
~eqbuf.setn(0, ~eqBufValues);
// ~eqbuf.set(i * 2, val); // why set is not sufficient and compulsory to use setn to act "correctly" ?
};
// Clear button
~eqClearView = Button(w, Rect(200, 220, 50, 20));
~eqClearView.states = [["clear", Color.black, Color.grey]];
~eqClearView.action = {
~magValues = 0 ! ~nbOfBins;
~plotterView.value_(~magValues);
~plotterView.specs_([0, 1, \lin, 0.001 ].asSpec);
~eqBufValues = 0 ! ~fftsize;
~eqbuf.loadCollection(~eqBufValues);
};
StaticText(w,***@20).string_("FFT bins--->");
// start synth
~syn = Synth(\fftEQ, [\out, 0, \fftsize, ~fftsize, \bufnum, ~eqbuf.bufnum ]);
~syn.run(true);
w.onClose = { ~syn.free; ~eqbuf.free };
};
// load the whole thing, when server booted
s.waitForBoot(loader);
)
~plotterView.domainSpecs = \freq.asSpec; ~plotterView.refresh;
~plotterView.domainSpecs = [0, 511, 'linear', 1, 0, ""].asSpec; ~plotterView.refresh;
By trying to build a spectral filter with GUI, I've found a problem with Plotter,
by specifying e.g. an exponential domainSpecs (\freq.asSpec) and trying to edit the values :
a = (0..200).scramble.plot;
a.editMode_(true);
a.domainSpecs = \freq.asSpec; a.refresh; // the edition does not match with the representation
Below is the spectral filter code with GUI reworked, coming from an example of a previous post :
http://new-supercollider-mailing-lists-forums-use-these.2681727.n2.nabble.com/Choosing-specific-FFT-bins-td5423719.html#a5424690
How to get an exponential representation (and correct edition) of domainSpecs with \freq.asSpec instead of linear bin representation ?
Thanks for the help,
Christophe
(
var w, loader;
s = Server.local;
~fftsize = 1024; // FFTsize containing for each bin -> magnitude and phase
~nbOfBins = ~fftsize / 2;
loader = {
SynthDef(\fftEQ, { arg out=0, fftsize= ~fftsize, bufnum=1;
var in, filtered, chain;
in = WhiteNoise.ar(0.3);
chain = FFT(LocalBuf(fftsize), in);
filtered = PV_MagMul(chain, bufnum);
Out.ar(out, Pan2.ar(IFFT(filtered), 0.0));
}).add;
~eqbuf = Buffer.alloc(s, ~fftsize, 1);
~eqBufValues = 0 ! ~fftsize; // initialize FFT buffer values
~eqbuf.loadCollection(~eqBufValues); // initialize FFT-buffer
~magValues = 0 ! ~nbOfBins; // // initialize magnitude values
s.sync;
~binResolution = (s.sampleRate / ~fftsize).postln;
w = Window("SpecEQ", Rect(200, 450, 10+(~nbOfBins), 250), false).alwaysOnTop_(true).front;
w.view.decorator = FlowLayout(w.view.bounds);
// Plotter
~plotterView = Plotter("FFT Filtering", Rect(0, 0, (~nbOfBins), 180), w)
.value_(~magValues)
.editMode_(true)
.resolution_(0.1)
.plotMode_(\levels)
.specs_([0, 1, \lin, 0.001 ].asSpec)
// .domainSpecs_(\freq.asSpec);
.editFunc = { |plotter, plotIndex, i, val|
("Bin index: "++ i ++" --- from "++ (~binResolution * i).asInt ++ " to " ++ (~binResolution * i + i).asInt ++ " Hz ::: "++ val).postln;
~magValues[i] = val;
~eqBufValues = [~magValues, (0 ! (~nbOfBins))].flop.flat;
~eqbuf.setn(0, ~eqBufValues);
// ~eqbuf.set(i * 2, val); // why set is not sufficient and compulsory to use setn to act "correctly" ?
};
// Clear button
~eqClearView = Button(w, Rect(200, 220, 50, 20));
~eqClearView.states = [["clear", Color.black, Color.grey]];
~eqClearView.action = {
~magValues = 0 ! ~nbOfBins;
~plotterView.value_(~magValues);
~plotterView.specs_([0, 1, \lin, 0.001 ].asSpec);
~eqBufValues = 0 ! ~fftsize;
~eqbuf.loadCollection(~eqBufValues);
};
StaticText(w,***@20).string_("FFT bins--->");
// start synth
~syn = Synth(\fftEQ, [\out, 0, \fftsize, ~fftsize, \bufnum, ~eqbuf.bufnum ]);
~syn.run(true);
w.onClose = { ~syn.free; ~eqbuf.free };
};
// load the whole thing, when server booted
s.waitForBoot(loader);
)
~plotterView.domainSpecs = \freq.asSpec; ~plotterView.refresh;
~plotterView.domainSpecs = [0, 511, 'linear', 1, 0, ""].asSpec; ~plotterView.refresh;