forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			166 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
		
		
			
		
	
	
			166 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
| 
								 | 
							
								package kha.audio2;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import kha.arrays.Float32Array;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@:headerCode("#include <kinc/threads/atomic.h>")
							 | 
						||
| 
								 | 
							
								@:headerClassCode("volatile float kinc_volume; volatile int kinc_position; volatile int kinc_paused; volatile int kinc_stopped; volatile int kinc_looping;")
							 | 
						||
| 
								 | 
							
								class AudioChannel implements kha.audio1.AudioChannel {
							 | 
						||
| 
								 | 
							
									public var data: Float32Array = null;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									#if cpp
							 | 
						||
| 
								 | 
							
									var myVolume(get, set): Float;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									inline function get_myVolume(): Float {
							 | 
						||
| 
								 | 
							
										return untyped __cpp__("kinc_volume");
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									inline function set_myVolume(value: Float): Float {
							 | 
						||
| 
								 | 
							
										untyped __cpp__("KINC_ATOMIC_EXCHANGE_FLOAT(&kinc_volume, (float){0})", value);
							 | 
						||
| 
								 | 
							
										return value;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									var myPosition(get, set): Int;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									inline function get_myPosition(): Int {
							 | 
						||
| 
								 | 
							
										return untyped __cpp__("kinc_position");
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									inline function set_myPosition(value: Int): Int {
							 | 
						||
| 
								 | 
							
										untyped __cpp__("KINC_ATOMIC_EXCHANGE_32(&kinc_position, {0})", value);
							 | 
						||
| 
								 | 
							
										return value;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									var paused(get, set): Bool;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									inline function get_paused(): Bool {
							 | 
						||
| 
								 | 
							
										return untyped __cpp__("kinc_paused != 0");
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									inline function set_paused(value: Bool): Bool {
							 | 
						||
| 
								 | 
							
										untyped __cpp__("KINC_ATOMIC_EXCHANGE_32(&kinc_paused, {0} ? 1 : 0)", value);
							 | 
						||
| 
								 | 
							
										return value;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									var stopped(get, set): Bool;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									inline function get_stopped(): Bool {
							 | 
						||
| 
								 | 
							
										return untyped __cpp__("kinc_stopped != 0");
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									inline function set_stopped(value: Bool): Bool {
							 | 
						||
| 
								 | 
							
										untyped __cpp__("KINC_ATOMIC_EXCHANGE_32(&kinc_stopped, {0} ? 1 : 0)", value);
							 | 
						||
| 
								 | 
							
										return value;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									var looping(get, set): Bool;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									inline function get_looping(): Bool {
							 | 
						||
| 
								 | 
							
										return untyped __cpp__("kinc_looping != 0");
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									inline function set_looping(value: Bool): Bool {
							 | 
						||
| 
								 | 
							
										untyped __cpp__("KINC_ATOMIC_EXCHANGE_32(&kinc_looping, {0} ? 1 : 0)", value);
							 | 
						||
| 
								 | 
							
										return value;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									#else
							 | 
						||
| 
								 | 
							
									var myVolume: Float;
							 | 
						||
| 
								 | 
							
									var myPosition: Int;
							 | 
						||
| 
								 | 
							
									var paused: Bool;
							 | 
						||
| 
								 | 
							
									var stopped: Bool;
							 | 
						||
| 
								 | 
							
									var looping: Bool;
							 | 
						||
| 
								 | 
							
									#end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function new(looping: Bool) {
							 | 
						||
| 
								 | 
							
										this.looping = looping;
							 | 
						||
| 
								 | 
							
										stopped = false;
							 | 
						||
| 
								 | 
							
										paused = false;
							 | 
						||
| 
								 | 
							
										myPosition = 0;
							 | 
						||
| 
								 | 
							
										myVolume = 1;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function nextSamples(requestedSamples: Float32Array, requestedLength: Int, sampleRate: Int): Void {
							 | 
						||
| 
								 | 
							
										if (paused || stopped) {
							 | 
						||
| 
								 | 
							
											for (i in 0...requestedLength) {
							 | 
						||
| 
								 | 
							
												requestedSamples[i] = 0;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											return;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										var requestedSamplesIndex = 0;
							 | 
						||
| 
								 | 
							
										while (requestedSamplesIndex < requestedLength) {
							 | 
						||
| 
								 | 
							
											for (i in 0...min(data.length - myPosition, requestedLength - requestedSamplesIndex)) {
							 | 
						||
| 
								 | 
							
												requestedSamples[requestedSamplesIndex++] = data[myPosition++];
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if (myPosition >= data.length) {
							 | 
						||
| 
								 | 
							
												myPosition = 0;
							 | 
						||
| 
								 | 
							
												if (!looping) {
							 | 
						||
| 
								 | 
							
													stopped = true;
							 | 
						||
| 
								 | 
							
													break;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										while (requestedSamplesIndex < requestedLength) {
							 | 
						||
| 
								 | 
							
											requestedSamples[requestedSamplesIndex++] = 0;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function play(): Void {
							 | 
						||
| 
								 | 
							
										paused = false;
							 | 
						||
| 
								 | 
							
										stopped = false;
							 | 
						||
| 
								 | 
							
										kha.audio1.Audio._playAgain(this);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function pause(): Void {
							 | 
						||
| 
								 | 
							
										paused = true;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function stop(): Void {
							 | 
						||
| 
								 | 
							
										myPosition = 0;
							 | 
						||
| 
								 | 
							
										stopped = true;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public var length(get, null): Float; // Seconds
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function get_length(): Float {
							 | 
						||
| 
								 | 
							
										return data.length / kha.audio2.Audio.samplesPerSecond / 2; // 44.1 khz in stereo
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public var position(get, set): Float; // Seconds
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function get_position(): Float {
							 | 
						||
| 
								 | 
							
										return myPosition / kha.audio2.Audio.samplesPerSecond / 2;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function set_position(value: Float): Float {
							 | 
						||
| 
								 | 
							
										myPosition = Math.round(value * kha.audio2.Audio.samplesPerSecond * 2);
							 | 
						||
| 
								 | 
							
										myPosition = max(min(myPosition, data.length), 0);
							 | 
						||
| 
								 | 
							
										return value;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public var volume(get, set): Float;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function get_volume(): Float {
							 | 
						||
| 
								 | 
							
										return myVolume;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function set_volume(value: Float): Float {
							 | 
						||
| 
								 | 
							
										return myVolume = value;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public var finished(get, null): Bool;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function get_finished(): Bool {
							 | 
						||
| 
								 | 
							
										return stopped;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									static inline function max(a: Int, b: Int) {
							 | 
						||
| 
								 | 
							
										return a > b ? a : b;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									static inline function min(a: Int, b: Int) {
							 | 
						||
| 
								 | 
							
										return a < b ? a : b;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 |