In the Buffer.loadCollection example, it is demonstrated how to fill 5 seconds with noise:
(
a = FloatArray.fill(44100 * 5.0, {1.0.rand2}); // 5 seconds of noise
b = Buffer.loadCollection(s, a);
)
What I’d like to do, though, is pick several arbitrary points in a 5 second buffer, plot 5 random values, and have the waveform interpolate between them over the 5 second interval.
I can think of a way of doing it where I still write values for all 220, 500 samples - but juggling data arrays of that size seems to be pretty slow on my system. Is there an efficient way of doing this?
Thanks!
If you’re just interpolating between 5 points, you certainly don’t need to use that many samples; it probably mostly depends on how precise you want the timing to be.
Here’s an example using an Env to interpolate the values into a 1024-sample Buffer:
// 5 random values at 3 random time points + start/end
~values = { 1.0.rand2 }.dup(5);
~points = [0] ++ { 1.0.rand }.dup(3).sort ++ [1];
// make an Env from these points
~env = Env(~values, ~points.differentiate[1..]);
~env.plot;
// make a 1024 point array from the Env (well, actually a signal)
~arr = ~env.discretize(1024);
// load it into a buffer
~buf = Buffer.loadCollection(s, ~arr);
~buf.plot;
// play the buffer over 5 seconds
(
{
var index = Line.ar(0, BufFrames.kr(~buf), 5);
var freq = BufRd.ar(1, ~buf, index).exprange(100, 1000);
SinOsc.ar(freq).dup(2) * 0.1;
}.play;
)
But this makes me wonder if you need the buffer at all, isn’t it better just to play the Env?
// better yet, just play the Env over 5 seconds
(
{
var freq = ~env.ar(timeScale: 5).exprange(100, 1000);
SinOsc.ar(freq).dup(2) * 0.1;
}.play;
)
1 Like
Thanks, this is exactly what I was looking for.