127 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
		
		
			
		
	
	
			127 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
| 
								 | 
							
								package kha.audio2;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import kha.js.AEAudioChannel;
							 | 
						||
| 
								 | 
							
								import kha.audio1.AudioChannel;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								enum abstract PlayMode(Int) {
							 | 
						||
| 
								 | 
							
									var Stopped;
							 | 
						||
| 
								 | 
							
									var Paused;
							 | 
						||
| 
								 | 
							
									var Playing;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class VirtualStreamChannel implements kha.audio1.AudioChannel {
							 | 
						||
| 
								 | 
							
									var aeChannel: AEAudioChannel;
							 | 
						||
| 
								 | 
							
									var mode = PlayMode.Playing;
							 | 
						||
| 
								 | 
							
									var lastTickTime: Float;
							 | 
						||
| 
								 | 
							
									var lastPosition: Float;
							 | 
						||
| 
								 | 
							
									var looping: Bool;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function new(aeChannel: AEAudioChannel, looping: Bool) {
							 | 
						||
| 
								 | 
							
										this.aeChannel = aeChannel;
							 | 
						||
| 
								 | 
							
										this.looping = looping;
							 | 
						||
| 
								 | 
							
										lastTickTime = Scheduler.realTime();
							 | 
						||
| 
								 | 
							
										lastPosition = 0;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function wake(): Void {
							 | 
						||
| 
								 | 
							
										updatePosition();
							 | 
						||
| 
								 | 
							
										aeChannel.position = lastPosition;
							 | 
						||
| 
								 | 
							
										aeChannel.play();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function updatePosition(): Void {
							 | 
						||
| 
								 | 
							
										var now = Scheduler.realTime();
							 | 
						||
| 
								 | 
							
										switch (mode) {
							 | 
						||
| 
								 | 
							
											case Stopped:
							 | 
						||
| 
								 | 
							
												lastPosition = 0;
							 | 
						||
| 
								 | 
							
											case Paused:
							 | 
						||
| 
								 | 
							
											// nothing
							 | 
						||
| 
								 | 
							
											case Playing:
							 | 
						||
| 
								 | 
							
												lastPosition += now - lastTickTime;
							 | 
						||
| 
								 | 
							
												while (lastPosition > length) {
							 | 
						||
| 
								 | 
							
													lastPosition -= length;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										lastTickTime = now;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function play(): Void {
							 | 
						||
| 
								 | 
							
										if (SystemImpl.mobileAudioPlaying) {
							 | 
						||
| 
								 | 
							
											aeChannel.play();
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else {
							 | 
						||
| 
								 | 
							
											updatePosition();
							 | 
						||
| 
								 | 
							
											mode = Playing;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function pause(): Void {
							 | 
						||
| 
								 | 
							
										if (SystemImpl.mobileAudioPlaying) {
							 | 
						||
| 
								 | 
							
											aeChannel.pause();
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else {
							 | 
						||
| 
								 | 
							
											updatePosition();
							 | 
						||
| 
								 | 
							
											mode = Paused;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function stop(): Void {
							 | 
						||
| 
								 | 
							
										if (SystemImpl.mobileAudioPlaying) {
							 | 
						||
| 
								 | 
							
											aeChannel.stop();
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else {
							 | 
						||
| 
								 | 
							
											updatePosition();
							 | 
						||
| 
								 | 
							
											mode = Stopped;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public var length(get, never): Float; // Seconds
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function get_length(): Float {
							 | 
						||
| 
								 | 
							
										return aeChannel.length;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public var position(get, set): Float; // Seconds
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function get_position(): Float {
							 | 
						||
| 
								 | 
							
										if (SystemImpl.mobileAudioPlaying) {
							 | 
						||
| 
								 | 
							
											return aeChannel.position;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else {
							 | 
						||
| 
								 | 
							
											updatePosition();
							 | 
						||
| 
								 | 
							
											return lastPosition;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function set_position(value: Float): Float {
							 | 
						||
| 
								 | 
							
										if (SystemImpl.mobileAudioPlaying) {
							 | 
						||
| 
								 | 
							
											return aeChannel.position = value;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else {
							 | 
						||
| 
								 | 
							
											updatePosition();
							 | 
						||
| 
								 | 
							
											return lastPosition = value;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public var volume(get, set): Float;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function get_volume(): Float {
							 | 
						||
| 
								 | 
							
										return aeChannel.volume;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function set_volume(value: Float): Float {
							 | 
						||
| 
								 | 
							
										return aeChannel.volume = value;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public var finished(get, never): Bool;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function get_finished(): Bool {
							 | 
						||
| 
								 | 
							
										if (SystemImpl.mobileAudioPlaying) {
							 | 
						||
| 
								 | 
							
											return aeChannel.finished;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else {
							 | 
						||
| 
								 | 
							
											return mode == Stopped || (!looping && position >= length);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 |