Load an Array to a Buffer (and an array of arrays into an array of buffers)?

Hi!

I’m banging my head against a silly task that should be quite easy, but I’m only getting lost in the documentation. :sweat_smile:

I’m simply trying to create a wavetable from a chunk of an audio file.
But the more I’m trying, the more I realize that there’s a looooot of basics that I’m still missing.

Specifically, here’s my crappy example code:

~wavebuf = Buffer.alloc(s, 1024)

// example chunk
~original = Buffer.readChannel(s, Platform.resourceDir +/+ "sounds/a11wlk01.wav", channels:0)

~original.loadToFloatArray(1000, 1024, action: { arg array; ~array = array })

// create the nearest thing to a Gaussian envelope I could find
~gaussian_env = Env.new(curve: 'welch').discretize(n: 1024) // <-- Really isn't there any built-in Gaussian?!

// envelope the chunk
~final_array = ~temp_array.normalize(-1.0, 1.0) * ~gaussian_env

// here it comes!
~wavebuf.loadCollection(s, ~final_array)

However, the last line throws me this error:

ERROR: Message 'collectAs' not understood.

What am I getting wrong?

…Also, for the sake of context, I would also like to have a single functions which stores two chunks from two signals in consecutive buffers ~wavebuf[0] and ~wavebuf[1], to be used in this SynthDef:

SynthDef.new(\wavet, {|out, freq, sustain = 1, gate = 1, pan = 0.5 |

	var line, func, env, detune, bufpos, osc;

	line = Line.kr(0, 1, sustain, doneAction: Done.freeSelf);
	func = Env.new([0, 1, 0.8, 0], [0.1, 0.3, 0.6], curve: \lin);
    env = IEnvGen.kr(func, line);

	detune = LFNoise1.kr(0.2!2).bipolar(0.2).midiratio;
	bufpos = ~wavebuf[0].bufnum + LFNoise1.kr(1).range(0.001, 1); // <--pseudo-code, just to get an idea of how it should work...

	osc = Mix.ar(VOsc.ar(bufpos, freq * detune, mul: 0.2) * env);

	OffsetOut.ar(out, Pan2.ar(osc, pan));
}).add;

…I tried to hard-code some functions with loops to iterate over two arrays, but it did not ended well…
If anybody has the patience to help me with this, thank you in advance!

Oh, and happy new year btw, hope you’re having a better night than mine, being sick at home getting errors from SuperCollider :partying_face: :partying_face: :partying_face:

the last line is:

~newbuf = Buffer.loadCollection(s, ~final_array)

You aren’t far off on the second one. You can’t do this in a SynthDef:

bufpos = ~wavebuf[0].bufnum + LFNoise1.kr(1).range(0.001, 1);

You can’t use a “global” ~variable in a SynthDef. You need this to look like this:

bufpos = bufoffset + LFNoise1.kr(1).range(0.001, 1);

where bufoffset is an argument in the top of the synthdef. The two buffers also need to be consecutive, so make sure of that.

Sam

1 Like

Gotcha!

I see that I cannot use .alloc then…
However, the only way I know to make sure that the buffers are consecutive is to use .allocConsecutive, but indeed this:

~waveBufs = Buffer.allocConsecutive(2, s, 1024)
~waveBufs[0].loadCollection(s, ~final_array)

…does not work, I assume for the same reason as before. So, what’s the safest way to ensure consecutiveness in this case?

Sorry!

~newbuf = Buffer.alloc(s, ~final_array.size);
~newbuf.loadCollection(~final_array);

It is already allocated so it doesn’t need the s

Sam

Oooh that’s the thing!

Nice to know. The error message was kinda hazy…

Thanks so much!