Function for analysing wavesets

hey,
i would like to rewrite the code for analysing the wavesets from the TZeroXBufRd helpfile Ex. 8: Pulsar synthesis with envelopes, variable number of source and envelope half wavesets from the miSCellaneous_lib extension to have one function ~chooseZeroBufX with the ability to load source and envelope data into the languange and get all the necessary analysis data to use with TZeroXBufRd for pulsar synthesis and need some help :slight_smile: any ideas, thanks a lot?

from the helpfile:

// prepare buffers

(
p = Platform.resourceDir +/+ "sounds/a11wlk01.wav";
~srcBuf = Buffer.read(s, p);
~srcBufZeros = Buffer.alloc(s, 100000);

~envBuf = Buffer.alloc(s, 1000, 1);
~envBufZeros = Buffer.alloc(s, 100, 1);
)

// analyse source buffer and sine envelope

(
{
    var src = PlayBuf.ar(1, ~srcBuf, BufRateScale.ir(~srcBuf), doneAction: 2);
    ZeroXBufWr.ar(
        src, ~srcBuf, ~srcBufZeros,
        startWithZeroX: 0, adjustZeroXs: 1, doneAction: 2
    );
}.play;

{
    var src = SinOsc.ar(50);
    ZeroXBufWr.ar(
        src, ~envBuf, ~envBufZeros,
        startWithZeroX: 1, adjustZeroXs: 0, doneAction: 2
    );
    Silent.ar
}.play
)


// load source and envelope data into language

(
~srcBufZeros.loadToFloatArray(action: { |x| ~srcBufZeroXArr = x.reject(_==0) });
~srcBuf.loadToFloatArray(action: { |x| ~srcBufArr = x });

~envBufZeros.loadToFloatArray(action: { |x| ~envBufZeroXArr = x.as(Array) });
~envBuf.loadToFloatArray(action: { |x| ~envBufArr = x });
)


// choose source and envelope waveset and
// maximum number of half wavesets

// finally we need the lengths of the wavesets (~srcZeroXDiffs, ~envZeroXDiffs) for
// adjusting the envelope playback rate in the SynthDef dynamically

(
~srcZeroXOffset = 1019;  // check with other offset
~srcMaxHalfWavesetNum = 2;

~srcZeroXIndices = ~srcBufZeroXArr[~srcZeroXOffset..~srcZeroXOffset + ~srcMaxHalfWavesetNum];
~srcZeroXDiffs = ~srcZeroXIndices.differentiate.drop(1);

~envZeroXOffset = 0;
~envMaxHalfWavesetNum = 2;

~envZeroXIndices = ~envBufZeroXArr[~envZeroXOffset..~envZeroXOffset + ~envMaxHalfWavesetNum];
~envZeroXDiffs = ~envZeroXIndices.differentiate.drop(1);

[
    ~srcBufArr[(~srcZeroXIndices[0]..~srcZeroXIndices[~srcMaxHalfWavesetNum])],
    ~envBufArr[(~envZeroXIndices[0]..~envZeroXIndices[~envMaxHalfWavesetNum])]
].plot;
)

i made a first attempt to merge the code to one function but im a bit confused how all the “global” variables should be handled:

// load source and envelope data into language
(
~loadZeroBufX = {|srcBufZeros, srcBuf, envBufZeros, envBuf|

	srcBufZeros.loadToFloatArray(action: { |x| ~srcBufZeroXArr = x.reject(_==0) });
	srcBuf.loadToFloatArray(action: { |x| ~srcBufArr = x });

	envBufZeros.loadToFloatArray(action: { |x| ~envBufZeroXArr = x.as(Array) });
	envBuf.loadToFloatArray(action: { |x| ~envBufArr = x });
};
)

~loadZeroBufX.(~srcBufZeros, ~srcBuf, ~envBufZeros, ~envBuf);

(
~chooseZeroBufX = {|srcZeroXOffset=1019, srcMaxHalfWavesetNum=2, envZeroXOffset=0, envMaxHalfWavesetNum=2|

	var srcZeroXIndices = ~srcBufZeroXArr[srcZeroXOffset..srcZeroXOffset + srcMaxHalfWavesetNum];
	var srcZeroXDiffs = srcZeroXIndices.differentiate.drop(1);

	var envZeroXIndices = ~envBufZeroXArr[envZeroXOffset..envZeroXOffset + envMaxHalfWavesetNum];
	var envZeroXDiffs = envZeroXIndices.differentiate.drop(1);

	[
		~srcBufArr[(srcZeroXIndices[0]..srcZeroXIndices[srcMaxHalfWavesetNum])],
		~envBufArr[(envZeroXIndices[0]..envZeroXIndices[envMaxHalfWavesetNum])]
	].plot;
};
)

~chooseZeroBufX.(1019, 2, 0, 2);


//pulsar SynthDef needs these values:

~srcMaxHalfWavesetNum
~envMaxHalfWavesetNum

~srcZeroXDiffs
~envZeroXDiffs

~srcBuf
~srcBufZeros

~envBuf
~envBufZeros

ive tried something like this but unfortunately i get nil for srcZeroXDiffs and envZeroXDiffs when i call ~getZeroXData because its not saving the result from chooseZeroXBufs to the variables srcZeroXDiffs and envZeroXDiffs. any ideas how to adjust ~getZeroXData so that i get the desired array of values and can save it in ~zeroXData? thanks a lot :slight_smile:

// prepare buffers
(
p = Platform.resourceDir +/+ "sounds/a11wlk01.wav";
~srcBuf = Buffer.read(s, p);
~srcBufZeros = Buffer.alloc(s, 100000);

~envBuf = Buffer.alloc(s, 1000, 1);
~envBufZeros = Buffer.alloc(s, 100, 1);
)

// analyse source buffer and envelope
(
{
	var src = PlayBuf.ar(1, ~srcBuf, BufRateScale.ir(~srcBuf), doneAction: 2);
	ZeroXBufWr.ar(
		src, ~srcBuf, ~srcBufZeros,
		startWithZeroX: 0, adjustZeroXs: 1, doneAction: 2
	);
}.play;

{
    var src = SinOsc.ar(50);
    ZeroXBufWr.ar(
        src, ~envBuf, ~envBufZeros,
        startWithZeroX: 1, adjustZeroXs: 0, doneAction: 2
    );
    Silent.ar
}.play
)

(
~getZeroXData = {|srcZeroXOffset, envZeroXOffset, srcMaxHalfWavesetNum, envMaxHalfWavesetNum|

	var srcBufZeroXArr, srcBufArr, envBufZeroXArr, envBufArr;
	var srcZeroXDiffs, envZeroXDiffs, srcZeroXIndices, envZeroXIndices;

	// load source and envelope data into language
	var loadZeroXBufs = {

	~srcBufZeros.loadToFloatArray(action: { |x| srcBufZeroXArr = x.reject(_==0) });
	~srcBuf.loadToFloatArray(action: { |x| srcBufArr = x });

	~envBufZeros.loadToFloatArray(action: { |x| envBufZeroXArr = x.as(Array) });
	~envBuf.loadToFloatArray(action: { |x| envBufArr = x });
	};

	// choose source and envelope waveset and maximum number of half wavesets
	var chooseZeroXBufs = {

		srcZeroXIndices = srcBufZeroXArr[srcZeroXOffset..srcZeroXOffset + srcMaxHalfWavesetNum];
		envZeroXIndices = envBufZeroXArr[envZeroXOffset..envZeroXOffset + envMaxHalfWavesetNum];

		// finally we need the lengths of the wavesets (srcZeroXDiffs, envZeroXDiffs) for
		// adjusting the envelope playback rate in the SynthDef dynamically

		srcZeroXDiffs = srcZeroXIndices.differentiate.drop(1);
		envZeroXDiffs = envZeroXIndices.differentiate.drop(1);

		// Pulsar SynthDef needs these values
		// [srcZeroXDiffs, envZeroXDiffs, srcMaxHalfWavesetNum, envMaxHalfWavesetNum];
	};

	var plotZeroXBufs = {
		[
			srcBufArr[(srcZeroXIndices[0]..srcZeroXIndices[srcMaxHalfWavesetNum])],
			envBufArr[(envZeroXIndices[0]..envZeroXIndices[envMaxHalfWavesetNum])]
		].plot;
	};

	// Pulsar SynthDef needs these values
	[srcZeroXDiffs, envZeroXDiffs, srcMaxHalfWavesetNum, envMaxHalfWavesetNum];

};
)

// get values for Pulsar SynthDef and plot source and envelope
~zeroXData = ~getZeroXData.(10, 0, 2, 2);

EDIT:

i thought i could replace some of the global variables in here especially ~srcBufZeroXArr, ~srcBufArr, ~envBufZeroXArr and ~envBufArr, which are not needed after the analysis has been done. but its kind of working now. It also needs a kind of waiting condition to wait for the buffers being loaded into FloatArrays i guess.

(
~getZeroXData = {|srcZeroXOffset, envZeroXOffset, srcMaxHalfWavesetNum, envMaxHalfWavesetNum|

	var srcZeroXIndices, envZeroXIndices;

	Routine.new({

		// load source and envelope data into language

		~srcBufZeros.loadToFloatArray(action: { |x| ~srcBufZeroXArr = x.reject(_==0) });
		~srcBuf.loadToFloatArray(action: { |x| ~srcBufArr = x });

		~envBufZeros.loadToFloatArray(action: { |x| ~envBufZeroXArr = x.as(Array) });
		~envBuf.loadToFloatArray(action: { |x| ~envBufArr = x });

		s.sync;

		// choose source and envelope waveset and maximum number of half wavesets

		srcZeroXIndices = ~srcBufZeroXArr[srcZeroXOffset..srcZeroXOffset + srcMaxHalfWavesetNum];
		envZeroXIndices = ~envBufZeroXArr[envZeroXOffset..envZeroXOffset + envMaxHalfWavesetNum];

		// finally we need the lengths of the wavesets (srcZeroXDiffs, envZeroXDiffs) for
		// adjusting the envelope playback rate in the SynthDef dynamically

		~srcZeroXDiffs = srcZeroXIndices.differentiate.drop(1);
		~envZeroXDiffs = envZeroXIndices.differentiate.drop(1);

		~srcMaxHalfWavesetNum = srcMaxHalfWavesetNum;
		~envMaxHalfWavesetNum = envMaxHalfWavesetNum;

		s.sync;

		// plot source and envelope
		[
			~srcBufArr[(srcZeroXIndices[0]..srcZeroXIndices[srcMaxHalfWavesetNum])],
			~envBufArr[(envZeroXIndices[0]..envZeroXIndices[envMaxHalfWavesetNum])]
		].plot;

	}).play(AppClock);

};
)

// get values for Pulsar SynthDef and plot source and envelope

~getZeroXData.(0, 0, 2, 2); // choose different Offsets

Where does ZeroXBufWr come from? What’s it supposed to do?

its from the https://github.com/dkmayer/miSCellaneous_lib and should write zero crossing analysis from signals to buffers.