284 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
		
		
			
		
	
	
			284 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
| 
								 | 
							
								package auratests.dsp.panner;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import utest.Assert;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import aura.Aura;
							 | 
						||
| 
								 | 
							
								import aura.Time;
							 | 
						||
| 
								 | 
							
								import aura.dsp.panner.Panner;
							 | 
						||
| 
								 | 
							
								import aura.math.Vec3;
							 | 
						||
| 
								 | 
							
								import aura.types.AudioBuffer;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import Utils;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								private class NonAbstractPanner extends Panner {
							 | 
						||
| 
								 | 
							
									public function process(buffer: AudioBuffer) {}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@:access(aura.channels.BaseChannel)
							 | 
						||
| 
								 | 
							
								@:access(aura.channels.BaseChannelHandle)
							 | 
						||
| 
								 | 
							
								@:access(aura.dsp.panner.Panner)
							 | 
						||
| 
								 | 
							
								class TestPanner extends utest.Test {
							 | 
						||
| 
								 | 
							
									var handle: BaseChannelHandle;
							 | 
						||
| 
								 | 
							
									var panner: Panner;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function setup() {
							 | 
						||
| 
								 | 
							
										handle = Utils.createDummyHandle();
							 | 
						||
| 
								 | 
							
										panner = new NonAbstractPanner(handle);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function teardown() {
							 | 
						||
| 
								 | 
							
										Time.overrideTime = null;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function test_setLocation_multipleCallsOnFirstTimestep() {
							 | 
						||
| 
								 | 
							
										Time.overrideTime = 0.0;
							 | 
						||
| 
								 | 
							
										panner.setLocation(new Vec3(0.5, 0.6, 0.7));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(0.5, panner.location.x);
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(0.6, panner.location.y);
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(0.7, panner.location.z);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(0.0, panner.velocity.x);
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(0.0, panner.velocity.y);
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(0.0, panner.velocity.z);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Time.overrideTime = 0.0;
							 | 
						||
| 
								 | 
							
										panner.setLocation(new Vec3(1.0, 2.0, 3.0));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(1.0, panner.location.x);
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(2.0, panner.location.y);
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(3.0, panner.location.z);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(0.0, panner.velocity.x);
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(0.0, panner.velocity.y);
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(0.0, panner.velocity.z);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function test_setLocation_firstCall_timeDeltaZero() {
							 | 
						||
| 
								 | 
							
										Time.overrideTime = 0.0;
							 | 
						||
| 
								 | 
							
										panner.setLocation(new Vec3(0.5, 0.6, 0.7));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(0.5, panner.location.x);
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(0.6, panner.location.y);
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(0.7, panner.location.z);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(0.0, panner.velocity.x);
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(0.0, panner.velocity.y);
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(0.0, panner.velocity.z);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function test_setLocation_firstCall_timeDeltaPositive() {
							 | 
						||
| 
								 | 
							
										Time.overrideTime = 2.0;
							 | 
						||
| 
								 | 
							
										panner.setLocation(new Vec3(0.5, 0.6, 0.7));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(0.5, panner.location.x);
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(0.6, panner.location.y);
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(0.7, panner.location.z);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(0.0, panner.velocity.x);
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(0.0, panner.velocity.y);
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(0.0, panner.velocity.z);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function test_setLocation_subsequentCalls_timeDeltaZero() {
							 | 
						||
| 
								 | 
							
										// Regression test for https://github.com/MoritzBrueckner/aura/pull/8
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Time.overrideTime = 1.0;
							 | 
						||
| 
								 | 
							
										panner.setLocation(new Vec3(0.0, 0.0, 0.0));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Time.overrideTime = 3.0;
							 | 
						||
| 
								 | 
							
										panner.setLocation(new Vec3(1.0, 2.0, 3.0));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Time.overrideTime = 3.0;
							 | 
						||
| 
								 | 
							
										panner.setLocation(new Vec3(2.0, 4.0, 6.0));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(2.0, panner.location.x);
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(4.0, panner.location.y);
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(6.0, panner.location.z);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// Compute velocity based on timestep 1.0
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(1.0, panner.velocity.x);
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(2.0, panner.velocity.y);
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(3.0, panner.velocity.z);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function test_update3D_noDopplerJumpIfLocationWasUninitialized() {
							 | 
						||
| 
								 | 
							
										Time.overrideTime = 0.0;
							 | 
						||
| 
								 | 
							
										panner.setLocation(new Vec3(20.0, 0.0, 0.0));
							 | 
						||
| 
								 | 
							
										panner.update3D();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										handle.channel.synchronize();
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(1.0, handle.channel.pDopplerRatio.targetValue);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function test_noDopplerEffect_ifNoMovement() {
							 | 
						||
| 
								 | 
							
										Time.overrideTime = 0.0;
							 | 
						||
| 
								 | 
							
										aura.Aura.listener.setLocation(new Vec3(0.0, 0.0, 0.0));
							 | 
						||
| 
								 | 
							
										panner.setLocation(new Vec3(5.0, 4.0, 3.0));
							 | 
						||
| 
								 | 
							
										panner.update3D();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Time.overrideTime = 0.5;
							 | 
						||
| 
								 | 
							
										aura.Aura.listener.setLocation(new Vec3(0.0, 0.0, 0.0));
							 | 
						||
| 
								 | 
							
										panner.setLocation(new Vec3(5.0, 4.0, 3.0));
							 | 
						||
| 
								 | 
							
										panner.update3D();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										handle.channel.synchronize();
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(1.0, handle.channel.pDopplerRatio.targetValue);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function test_calculateDoppler_physicallyCorrectValues_pannerMovesAway() {
							 | 
						||
| 
								 | 
							
										Time.overrideTime = 0.0;
							 | 
						||
| 
								 | 
							
										aura.Aura.listener.setLocation(new Vec3(0.0, 0.0, 0.0));
							 | 
						||
| 
								 | 
							
										panner.setLocation(new Vec3(0.0, 0.0, 0.0));
							 | 
						||
| 
								 | 
							
										panner.update3D();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Time.overrideTime = 0.5;
							 | 
						||
| 
								 | 
							
										aura.Aura.listener.setLocation(new Vec3(0.0, 0.0, 0.0));
							 | 
						||
| 
								 | 
							
										panner.setLocation(new Vec3(2.0, 0.0, 0.0));
							 | 
						||
| 
								 | 
							
										panner.update3D();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(4.0, @:privateAccess panner.velocity.length);
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(0.0, @:privateAccess aura.Aura.listener.velocity.length);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										handle.channel.synchronize();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// Values calculated at
							 | 
						||
| 
								 | 
							
										// https://www.omnicalculator.com/physics/doppler-effect?c=EUR&v=f0:5000!Hz,v:343.4!ms,vs:2!ms,vr:0!ms
							 | 
						||
| 
								 | 
							
										// Assuming that their implementation is correct
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(4942.43 / 5000, handle.channel.pDopplerRatio.targetValue);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function test_calculateDoppler_physicallyCorrectValues_listenerMovesAway() {
							 | 
						||
| 
								 | 
							
										Time.overrideTime = 0.0;
							 | 
						||
| 
								 | 
							
										aura.Aura.listener.setLocation(new Vec3(0.0, 0.0, 0.0));
							 | 
						||
| 
								 | 
							
										panner.setLocation(new Vec3(0.0, 0.0, 0.0));
							 | 
						||
| 
								 | 
							
										panner.update3D();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Time.overrideTime = 0.5;
							 | 
						||
| 
								 | 
							
										aura.Aura.listener.setLocation(new Vec3(2.0, 0.0, 0.0));
							 | 
						||
| 
								 | 
							
										panner.setLocation(new Vec3(0.0, 0.0, 0.0));
							 | 
						||
| 
								 | 
							
										panner.update3D();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(4.0, @:privateAccess aura.Aura.listener.velocity.length);
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(0.0, @:privateAccess panner.velocity.length);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										handle.channel.synchronize();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(4941.76 / 5000, handle.channel.pDopplerRatio.targetValue);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function test_calculateDoppler_physicallyCorrectValues_pannerMovesCloser() {
							 | 
						||
| 
								 | 
							
										Time.overrideTime = 0.0;
							 | 
						||
| 
								 | 
							
										aura.Aura.listener.setLocation(new Vec3(0.0, 0.0, 0.0));
							 | 
						||
| 
								 | 
							
										panner.setLocation(new Vec3(4.0, 0.0, 0.0));
							 | 
						||
| 
								 | 
							
										panner.update3D();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Time.overrideTime = 0.5;
							 | 
						||
| 
								 | 
							
										aura.Aura.listener.setLocation(new Vec3(0.0, 0.0, 0.0));
							 | 
						||
| 
								 | 
							
										panner.setLocation(new Vec3(2.0, 0.0, 0.0));
							 | 
						||
| 
								 | 
							
										panner.update3D();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(4.0, @:privateAccess panner.velocity.length);
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(0.0, @:privateAccess aura.Aura.listener.velocity.length);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										handle.channel.synchronize();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(5058.93 / 5000, handle.channel.pDopplerRatio.targetValue);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function test_calculateDoppler_physicallyCorrectValues_listenerMovesCloser() {
							 | 
						||
| 
								 | 
							
										Time.overrideTime = 0.0;
							 | 
						||
| 
								 | 
							
										aura.Aura.listener.setLocation(new Vec3(4.0, 0.0, 0.0));
							 | 
						||
| 
								 | 
							
										panner.setLocation(new Vec3(0.0, 0.0, 0.0));
							 | 
						||
| 
								 | 
							
										panner.update3D();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Time.overrideTime = 0.5;
							 | 
						||
| 
								 | 
							
										aura.Aura.listener.setLocation(new Vec3(2.0, 0.0, 0.0));
							 | 
						||
| 
								 | 
							
										panner.setLocation(new Vec3(0.0, 0.0, 0.0));
							 | 
						||
| 
								 | 
							
										panner.update3D();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(4.0, @:privateAccess aura.Aura.listener.velocity.length);
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(0.0, @:privateAccess panner.velocity.length);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										handle.channel.synchronize();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(5058.24 / 5000, handle.channel.pDopplerRatio.targetValue);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function test_calculateDoppler_noDopplerEffectIfNoRadialVelocity() {
							 | 
						||
| 
								 | 
							
										Time.overrideTime = 0.0;
							 | 
						||
| 
								 | 
							
										aura.Aura.listener.setLocation(new Vec3(0.0, 0.0, 0.0));
							 | 
						||
| 
								 | 
							
										panner.setLocation(new Vec3(2.0, 0.0, 0.0));
							 | 
						||
| 
								 | 
							
										panner.update3D();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Time.overrideTime = 0.5;
							 | 
						||
| 
								 | 
							
										aura.Aura.listener.setLocation(new Vec3(0.0, 0.0, 0.0));
							 | 
						||
| 
								 | 
							
										panner.setLocation(new Vec3(0.0, 0.0, 0.0));
							 | 
						||
| 
								 | 
							
										panner.update3D();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										handle.channel.synchronize();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(1, handle.channel.pDopplerRatio.targetValue);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function test_calculateDoppler_noDopplerEffectIfNoRadialVelocity2() {
							 | 
						||
| 
								 | 
							
										Time.overrideTime = 0.0;
							 | 
						||
| 
								 | 
							
										aura.Aura.listener.setLocation(new Vec3(5.0, 0.0, 0.0));
							 | 
						||
| 
								 | 
							
										panner.setLocation(new Vec3(5.0, 0.0, 0.0));
							 | 
						||
| 
								 | 
							
										panner.update3D();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Time.overrideTime = 0.5;
							 | 
						||
| 
								 | 
							
										aura.Aura.listener.setLocation(new Vec3(5.0, 0.0, 0.0));
							 | 
						||
| 
								 | 
							
										panner.setLocation(new Vec3(5.0, 0.0, 0.0));
							 | 
						||
| 
								 | 
							
										panner.update3D();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										handle.channel.synchronize();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(1, handle.channel.pDopplerRatio.targetValue);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function test_calculateDoppler_noDopplerEffectIfNoRadialVelocity3() {
							 | 
						||
| 
								 | 
							
										Time.overrideTime = 0.0;
							 | 
						||
| 
								 | 
							
										aura.Aura.listener.setLocation(new Vec3(0.0, 0.0, 0.0));
							 | 
						||
| 
								 | 
							
										panner.setLocation(new Vec3(2.0, 2.0, 0.0));
							 | 
						||
| 
								 | 
							
										panner.update3D();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Time.overrideTime = 0.5;
							 | 
						||
| 
								 | 
							
										aura.Aura.listener.setLocation(new Vec3(0.0, 0.0, 0.0));
							 | 
						||
| 
								 | 
							
										panner.setLocation(new Vec3(0.0, 2.0, 0.0));
							 | 
						||
| 
								 | 
							
										panner.update3D();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										handle.channel.synchronize();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(1, handle.channel.pDopplerRatio.targetValue);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function test_dopplerEffect_isZeroIfPannerMovesCloserAtSpeedOfSound() {
							 | 
						||
| 
								 | 
							
										Time.overrideTime = 0.0;
							 | 
						||
| 
								 | 
							
										panner.setLocation(new Vec3(Panner.SPEED_OF_SOUND + 1, 0.0, 0.0));
							 | 
						||
| 
								 | 
							
										panner.update3D();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Time.overrideTime = 1.0;
							 | 
						||
| 
								 | 
							
										panner.setLocation(new Vec3(1, 0.0, 0.0));
							 | 
						||
| 
								 | 
							
										panner.update3D();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										handle.channel.synchronize();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(0, handle.channel.pDopplerRatio.targetValue);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function test_dopplerEffect_pannerMovesCloserAboveSpeedOfSound() {
							 | 
						||
| 
								 | 
							
										Time.overrideTime = 0.0;
							 | 
						||
| 
								 | 
							
										panner.setLocation(new Vec3(Panner.SPEED_OF_SOUND + 5, 0.0, 0.0));
							 | 
						||
| 
								 | 
							
										panner.update3D();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Time.overrideTime = 1.0;
							 | 
						||
| 
								 | 
							
										panner.setLocation(new Vec3(1, 0.0, 0.0));
							 | 
						||
| 
								 | 
							
										panner.update3D();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										handle.channel.synchronize();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Assert.floatEquals(-85.85, handle.channel.pDopplerRatio.targetValue);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 |