forked from LeenkxTeam/LNXSDK
127 lines
3.9 KiB
Haxe
127 lines
3.9 KiB
Haxe
package auratests.channels;
|
|
|
|
import utest.Assert;
|
|
|
|
import kha.arrays.Float32Array;
|
|
|
|
import aura.Types.Balance;
|
|
import aura.channels.UncompBufferResamplingChannel;
|
|
import aura.dsp.sourcefx.SourceEffect;
|
|
import aura.types.AudioBuffer;
|
|
|
|
@:access(aura.channels.UncompBufferResamplingChannel)
|
|
class TestUncompBufferResamplingChannel extends utest.Test {
|
|
static inline var channelLength = 16;
|
|
|
|
var audioChannel: UncompBufferResamplingChannel;
|
|
|
|
final rampLeft = new Array<Float>();
|
|
final rampRight = new Array<Float>();
|
|
final data = new Float32Array(2 * channelLength); // interleaved stereo
|
|
|
|
function setupClass() {
|
|
rampLeft.resize(channelLength);
|
|
rampRight.resize(channelLength);
|
|
|
|
for (i in 0...channelLength) { // Fill data with a value ramp
|
|
final val = (i + 1) / channelLength;
|
|
|
|
data[i * 2 + 0] = rampLeft[i] = val;
|
|
data[i * 2 + 1] = rampRight[i] = -val;
|
|
}
|
|
}
|
|
|
|
function setup() {
|
|
audioChannel = new UncompBufferResamplingChannel(data, false, 1000);
|
|
}
|
|
|
|
function teardown() {}
|
|
|
|
function test_dataConversion() {
|
|
for (i in 0...channelLength) {
|
|
Assert.floatEquals(rampLeft[i], audioChannel.data.getChannelView(0)[i]);
|
|
Assert.floatEquals(rampRight[i], audioChannel.data.getChannelView(1)[i]);
|
|
}
|
|
}
|
|
|
|
function test_nextSamples() {
|
|
final outBuffer = new AudioBuffer(2, channelLength);
|
|
|
|
audioChannel.nextSamples(outBuffer, 1000);
|
|
|
|
for (i in 0...channelLength) {
|
|
Assert.floatEquals(rampLeft[i], outBuffer.getChannelView(0)[i]);
|
|
Assert.floatEquals(rampRight[i], outBuffer.getChannelView(1)[i]);
|
|
}
|
|
|
|
// Now the channel has processed all data and will reset position to 0
|
|
Assert.equals(0, audioChannel.playbackPosition);
|
|
Assert.floatEquals(0.0, audioChannel.floatPosition);
|
|
|
|
// No looping, but request more samples
|
|
final longOutBuffer = new AudioBuffer(2, channelLength + 4);
|
|
audioChannel.nextSamples(longOutBuffer, 1000);
|
|
for (i in 0...channelLength) {
|
|
Assert.floatEquals(rampLeft[i], longOutBuffer.getChannelView(0)[i]);
|
|
Assert.floatEquals(rampRight[i], longOutBuffer.getChannelView(1)[i]);
|
|
}
|
|
for (i in channelLength...channelLength + 4) {
|
|
Assert.floatEquals(0.0, longOutBuffer.getChannelView(0)[i]);
|
|
Assert.floatEquals(0.0, longOutBuffer.getChannelView(1)[i]);
|
|
}
|
|
|
|
// Now change the sample rate, second half should be zero
|
|
audioChannel.playbackPosition = 0;
|
|
audioChannel.floatPosition = 0.0;
|
|
audioChannel.nextSamples(outBuffer, 500);
|
|
for (i in Std.int(channelLength / 2)...channelLength) {
|
|
Assert.floatEquals(0.0, outBuffer.getChannelView(0)[i]);
|
|
Assert.floatEquals(0.0, outBuffer.getChannelView(1)[i]);
|
|
}
|
|
|
|
// Now with looping
|
|
audioChannel.playbackPosition = 0;
|
|
audioChannel.floatPosition = 0.0;
|
|
audioChannel.looping = true;
|
|
audioChannel.nextSamples(outBuffer, 500);
|
|
final halfChannelLength = Std.int(channelLength / 2);
|
|
for (i in 0...halfChannelLength) {
|
|
Assert.floatEquals(outBuffer.getChannelView(0)[i], outBuffer.getChannelView(0)[halfChannelLength + i], null, '$i');
|
|
Assert.floatEquals(outBuffer.getChannelView(1)[i], outBuffer.getChannelView(1)[halfChannelLength + i], null, '$i');
|
|
}
|
|
|
|
// TODO: check sample precise looping without gaps with unusual sample rates?
|
|
}
|
|
|
|
function test_nextSamples_onLoop_ApplySourceEffectsOnce() {
|
|
audioChannel.looping = true;
|
|
|
|
final sourceFX = new SourceFXDummy();
|
|
|
|
audioChannel.addSourceEffect(sourceFX);
|
|
|
|
Assert.equals(0, sourceFX.numProcessCalled);
|
|
|
|
final outBuffer = new AudioBuffer(2, channelLength + 1);
|
|
audioChannel.nextSamples(outBuffer, 1000);
|
|
|
|
// Make sure process is only called once for _all_ channels
|
|
Assert.equals(1, sourceFX.numProcessCalled);
|
|
}
|
|
}
|
|
|
|
private class SourceFXDummy extends SourceEffect {
|
|
public var numProcessCalled = 0;
|
|
|
|
public function new() {}
|
|
|
|
function calculateRequiredChannelLength(srcChannelLength: Int): Int {
|
|
return srcChannelLength;
|
|
}
|
|
|
|
function process(srcBuffer: AudioBuffer, srcChannelLength: Int, dstBuffer: AudioBuffer): Int {
|
|
numProcessCalled++;
|
|
return srcChannelLength;
|
|
}
|
|
}
|