Map floats to array of values

I would like to somehow convert (maybe quantize is a better word) incoming floats between 0.0 and 1.0 to five fixed values.

Here is my array of values that I would like to map to:

[128, 512, 1024, 2048, 4096]

I am using this inside of a synthdef. It’s to do with a buffer so the whole things falls apart and takes SC with it when given a number which is not the ones in the array. Sure, I can remember to not give this synth bad values, but the thing is I’m sharing this synth with lots of other people whom I don’t want to create problems for.

I am aware of .linlin(0.0, 1.0, 128, 4096) and I think that I am looking for something similar that I don’t know the name of so I can’t search for it.

Any help greatly appreciated.

You could use Select:

(
{
	var inSig = LFTri.kr(20, -1).unipolar;
	var index = (inSig * 5).asInteger;
	var outSig = Select.kr(index, [128, 512, 1024, 2048, 4096]);
	outSig;
}.plot(0.2, minval: 0, maxval: 4096);
)

Best,
Paul

Hey Paul thanks for your help.

I tried to do what I think you mean, but I did not succeed.

At this time I think it would be a good idea to paste in the SynthDef and ask for help finessing it:

	SynthDef('spectral-enhance' ++ ~clean.numChannels, { |out, enh = 0.5, enb = 1024, enr = 0.5|
		var sig, chain, in, clean;
		var enrClipped = enr.clip(0.0, 1.0).linlin(0.0, 1.0, 1.0, 2.0);
		sig = In.ar(out, ~clean.numChannels);
		clean = sig;
		chain = sig.asArray.collect { |x| FFT(LocalBuf(enb), x) };
		sig = IFFT(
			PV_SpectralEnhance(chain,
				enh.linlin(0.0, 1.0, 1.0, enrClipped) * 16,
				enh.linlin(0.0, 1.0, 1.0, enrClipped) * 5.0,
				enh.linlin(0.0, 1.0, 0.0, enrClipped) * 0.99
			)
		).tanh; // .tanh is used as a crude limiter here because sometimes this ugen goes crazy
		ReplaceOut.ar(out, sig)
	}, [\ir, \ir]).add;

Right now enb only accepts these nice values: [128, 512, 1024, 2048, 4096]
I would like enb to take something like Pwhite(0.0, 1.0) and then for this synth to read that as the array above.

Sorry for not getting it. I am just working with what I got here.

I think Select is indeed what you’re looking for; do these lines work in your SynthDef?

var array = [128, 512, 1024, 2048, 4096];
var bufSize = Select.kr(enb.linlin(0,1,0,array.size).floor,array);

Oh wow thanks Mike!

Works like a charm. Very kind of you to take the time to help me.

Here is the working synth for anyone following along:

SynthDef('spectral-enhance' ++ ~clean.numChannels, { |out, enh = 0.5, enb = 0.5, enr = 0.5|
		var sig, chain, in, clean;
		var enrClipped = enr.clip(0.0, 1.0).linlin(0.0, 1.0, 1.0, 2.0);
		var array = [128, 512, 1024, 2048, 4096];
		var bufSize = Select.kr(enb.linlin(0,1,0,array.size).floor,array);
		sig = In.ar(out, ~clean.numChannels);
		clean = sig;
		chain = sig.asArray.collect { |x| FFT(LocalBuf(bufSize), x) };
		sig = IFFT(
			PV_SpectralEnhance(chain,
				enh.linlin(0.0, 1.0, 1.0, enrClipped) * 16,
				enh.linlin(0.0, 1.0, 1.0, enrClipped) * 5.0,
				enh.linlin(0.0, 1.0, 0.0, enrClipped) * 0.99
			)
		).tanh; // .tanh is used as a crude limiter here because sometimes this ugen goes crazy
		ReplaceOut.ar(out, sig)
	}, [\ir, \ir]).add;

Here’s a short demo of me using the above thing with these tiny buffersizes

[32, 64, 128, 256, 512].

I had to set s.options.blockSize = 16; in my startup file in order for that to work.

Are there any serious drawbacks to setting such a low blockSize which I am not understanding now that someone on here would like to warn me about?

1 Like

Unlikely. It will raise CPU consumption somewhat, because the UGen calculation functions will be called more often, and each function call takes a tiny slice of CPU time. But if you’re seeing no ill effects, then it’s nothing to worry about.

Block size is different from audio driver buffer size – too small a hardware buffer can make it much more likely for processing to be late. Block size is purely SC-internal and won’t have an effect on that.

hjh

1 Like