Waveset sequencing, Frame / Wavelet conversion

Hello,

I am used to play with an “already implemented Synthdef” Waveset method, and using Task such as

w = Wavesets.from("/Users/....");

Wavesets.prepareSynthDefs;

w.numXings;
w.avgLength;

(
Task({
	inf.do { arg j;
		j.postln;
		w.numXings.do({ arg i;
			var ev = w.eventFor( i,numWs:10 + 3.rand, repeats:1 + 20.rand, playRate:0.1 + 2.15.rand);
			ev.putPairs([\pan, [-1, 1].choose, \amp,1]);
			ev.play;
			0.0003.wait;
		});
		10.wait;
	}
}).play;
)

It is really convenient using the Task and numXings.do method to me, and I would like to keep it, but using the normal SynthDef method. In some other words I would like to use exactly this Task using the source SynthDef as documented in SCbook


(
// the simplest synthdef as implented in *prepareSynthDefs:

		SynthDef(\wvst0, { arg out = 0, buf = 0, start = 0, length = 441, playRate = 1, sustain = 1, amp=0.2, pan;
			var phasor = Phasor.ar(0, BufRateScale.ir(w.buffer) * playRate, 0, length) + start;
			var env = EnvGen.ar(Env([amp, amp, 0], [sustain, 0]), doneAction: 2);
			var snd = BufRd.ar(1, w.buffer, phasor) * env;

			OffsetOut.ar(out, Pan2.ar(snd, pan));
		}, \ir.dup(8)).add;
)

In the book you have a sequencing exemple using Pbind,which is really clear

(
Pbindef(\ws1).clear;
Pbindef(\ws1,
	\instrument, \wvst0,
	\startWs, Pn(Pseries(0, 1, 3000), 1),
	\numWs, 1,
	\playRate, 1,
	\bufnum, b.bufnum,
	\repeats, 1,
	\amp, 0.4,
	[\start, \length, \sustain], Pfunc({ |ev|
		var start, length, wsDur;

		#start, length, wsDur = w.frameFor(ev[\startWs], ev[\numWs]);
		[start, length, wsDur * ev[\repeats] / ev[\playRate].abs]
	}),
	\dur, Pkey(\sustain)
).play;
)

But my problem replacing the Pbind using the Task example above is to know how to use (and where to put) the w.frameFor function, that allow me to do the frame/xings (wavesets unity) conversion.

Thank you

I think you’re unlikely able to run the frameFor function in a Synth (or even transparently convert it) - but that should be required. Why not try this:

  1. Read all the possible frameFor values out, e.g.:
~result = (0,1..3000).collect { |i| w.frameFor(i, 1) };
~result = ~result.flop;
~starts = ~result[0];
~lengths = ~result[1];
~wsDurs = ~result[2];
  1. Load these into Buffers
  2. In your Synth, look up the frameFor value by indexing into the buffer:
var start, length, wsDur;
#start, length, wsDur = BufRd.ar(1, [startsBuf, lengthsBuf, wsDursBuf], index, interpolation:1);

You’re probably better off using demand rate Ugens (e.g. Dbufrd) for this - you might be able to e.g. use wsDur to drive a Duty ugen, which would in turn pull the values out of the other buffers and trigger playback of the new waveset.