Skip to content

Commit

Permalink
tests: coreUGens: add init phase tests for LFPulse, LFSaw, LFPar, LFC…
Browse files Browse the repository at this point in the history
…ub, LFtri, SinOsc
  • Loading branch information
mtmccrea committed Jun 8, 2024
1 parent 6314510 commit bb13fd9
Showing 1 changed file with 149 additions and 0 deletions.
149 changes: 149 additions & 0 deletions testsuite/classlibrary/TestCoreUGens.sc
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,155 @@ TestCoreUGens : UnitTest {

}

test_line_startAndEndSampleAreOuputOverDur {
var durFrames = 5; // duration for the line to complete its trajectory, in frames
var renderFrames = durFrames + 1; // render one extra frame to check that the end value is reached
var startVal = 2;
var endVal = 20;
var tolerance = -100.dbamp;
var condvar = CondVar();

server.bootSync;

[\ar, \kr].do{ |rate|
[Line, XLine].do{ |ugen|
var rateScale = switch(rate, \ar, { 1.0 }, \kr, { server.options.blockSize });
var fs = server.sampleRate;
{
ugen.perform(rate, startVal, endVal, (durFrames * rateScale / fs))

}.loadToFloatArray(renderFrames * rateScale / fs, server,
action: { |data|

this.assertFloatEquals(data.first, startVal,
"%.%'s first output sample should be its given start value.".format(ugen, rate), within: tolerance);
this.assert(data.last == endVal and: { data[data.size-2] != endVal },
"%.% should not reach its end value before the given duration".format(ugen, rate));
// Note an exception to the previouse test would be if the duration of the Line is less than a frame duration.
// In that (odd) case the "correct" first value is the end value. See GH issue #4279.
condvar.signalOne;
}
);
condvar.wait;
}
}
}

test_oscillators_startAtCorrectPhase {

var tolerance = -100.dbamp;
var condvar = CondVar();

server.bootSync;

[\ar, \kr].do{ |rate|

var per = 10; // a 10-sample period (should be even)
var halfPer = per * 0.5; // should divide evenly into sampleT
var fs = switch(rate,
\ar, { server.sampleRate },
\kr, { server.sampleRate / server.options.blockSize }
);
var freq = fs / per;
var iPhase, target, phs_val, phaseScale;

// LFPulse: initial phase is one sample before the end of the pulse width
{
iPhase = (halfPer - 1) / per; // LFPulse phase is 0->1
LFPulse.perform(rate, freq, iPhase, 0.5)
}.loadToFloatArray(per + 1 / fs, action: { |data|
data[0..5].postln;
this.assert(
data[0] == 1.0 and: { data[1] == 0.0 },
"LFPulse.% should start at the correct initial phase".format(rate)
);
condvar.signalOne;
});
condvar.wait;

// LFSaw: initial phase is one sample before the signal flip toward -1
{
iPhase = (halfPer - 1) / per * 2; // LFPulse phase is 0->2
LFSaw.perform(rate, freq, iPhase)
}.loadToFloatArray(per + 1 / fs, action: { |data|
this.assert(data[0] > 0.0 and: { data[1] < 0.0 },
"LFSaw.% should start at the correct initial phase".format(rate)
);
condvar.signalOne;
});
condvar.wait;

// LFPar: test initial phase
// [initPhase, value] pairs, LFPar phase is 0->4
phs_val = [
0, 1.0,
1, 0.0,
2, -1.0,
3, 0.0,
4, 1.0
].clump(2).do{ |pvPair|
#iPhase, target = pvPair;
{
LFPar.perform(rate, freq, iPhase)
}.loadToFloatArray(per + 1 / fs, action: { |data|
this.assertFloatEquals(data[0], target,
"LFPar.% should be % at initial phase of %".format(rate, target, iPhase),
within: tolerance
);
condvar.signalOne;
});
condvar.wait;
};

// LFCub, LFTri, SinOsc: testing initial phase
// [initPhase, value] pairs, phase normalized 0->1 then scaled for each UGen
phs_val = [
0.00, 0.0,
0.25, 1.0,
0.50, 0.0,
0.75, -1.0,
1.00, 0.0
].clump(2).do{ |pvPair|
#iPhase, target = pvPair;

{ // LFCub
phaseScale = 2.0; // LFPar phase is 0->2
LFCub.perform(rate, freq, iPhase * phaseScale)
}.loadToFloatArray(per + 1 / fs, action: { |data|
this.assertFloatEquals(data[0], target,
"LFCub.% should be % at initial phase of %".format(rate, target, iPhase * phaseScale),
within: tolerance
);
condvar.signalOne;
});
condvar.wait;

{ // LFTri
phaseScale = 4.0; // LFTri phase is 0->4
LFTri.perform(rate, freq, iPhase * phaseScale)
}.loadToFloatArray(per + 1 / fs, action: { |data|
this.assertFloatEquals(data[0], target,
"LFTri.% should be % at initial phase of %".format(rate, target, iPhase * phaseScale),
within: tolerance
);
condvar.signalOne;
});
condvar.wait;

{ // SinOsc
phaseScale = 2pi; // SinOsc phase is 0->2pi
SinOsc.perform(rate, freq, iPhase * phaseScale)
}.loadToFloatArray(per + 1 / fs, action: { |data|
this.assertFloatEquals(data[0], target,
"SinOsc.% should be % at initial phase of %".format(rate, target, iPhase * phaseScale),
within: tolerance
);
condvar.signalOne;
});
condvar.wait;
};
}
}


} // end TestCoreUGens class

0 comments on commit bb13fd9

Please sign in to comment.