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;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 |