109 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
		
		
			
		
	
	
			109 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
| 
								 | 
							
								package kha.audio2;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import haxe.io.Bytes;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@:headerCode("#define STB_VORBIS_HEADER_ONLY\n#include <kinc/libs/stb_vorbis.c>")
							 | 
						||
| 
								 | 
							
								@:headerClassCode("stb_vorbis* vorbis;")
							 | 
						||
| 
								 | 
							
								class StreamChannel implements kha.audio1.AudioChannel {
							 | 
						||
| 
								 | 
							
									var atend: Bool = false;
							 | 
						||
| 
								 | 
							
									@:keep var loop: Bool;
							 | 
						||
| 
								 | 
							
									var myVolume: Float;
							 | 
						||
| 
								 | 
							
									var paused: Bool = false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function new(data: Bytes, loop: Bool) {
							 | 
						||
| 
								 | 
							
										myVolume = 1;
							 | 
						||
| 
								 | 
							
										this.loop = loop;
							 | 
						||
| 
								 | 
							
										initVorbis(data);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									@:functionCode("vorbis = stb_vorbis_open_memory(data->b->Pointer(), data->length, NULL, NULL);")
							 | 
						||
| 
								 | 
							
									function initVorbis(data: Bytes): Void {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									@:functionCode("
							 | 
						||
| 
								 | 
							
										int read = stb_vorbis_get_samples_float_interleaved(vorbis, 2, (float*)samples->self.data, length);
							 | 
						||
| 
								 | 
							
										if (read < length / 2) {
							 | 
						||
| 
								 | 
							
											if (loop) {
							 | 
						||
| 
								 | 
							
												stb_vorbis_seek_start(vorbis);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											else {
							 | 
						||
| 
								 | 
							
												atend = true;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											for (int i = read * 2; i < length; ++i) {
							 | 
						||
| 
								 | 
							
												samples->self.data[i] = 0;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									")
							 | 
						||
| 
								 | 
							
									function nextVorbisSamples(samples: kha.arrays.Float32Array, length: Int): Void {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function nextSamples(samples: kha.arrays.Float32Array, length: Int, sampleRate: Int): Void {
							 | 
						||
| 
								 | 
							
										if (paused) {
							 | 
						||
| 
								 | 
							
											for (i in 0...length) {
							 | 
						||
| 
								 | 
							
												samples[i] = 0;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											return;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										nextVorbisSamples(samples, length);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function play(): Void {
							 | 
						||
| 
								 | 
							
										paused = false;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function pause(): Void {
							 | 
						||
| 
								 | 
							
										paused = true;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function stop(): Void {
							 | 
						||
| 
								 | 
							
										atend = true;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public var length(get, never): Float; // Seconds
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									@:functionCode("
							 | 
						||
| 
								 | 
							
										if (vorbis == NULL) return 0;
							 | 
						||
| 
								 | 
							
										return stb_vorbis_stream_length_in_seconds(vorbis);
							 | 
						||
| 
								 | 
							
									")
							 | 
						||
| 
								 | 
							
									function get_length(): Int {
							 | 
						||
| 
								 | 
							
										return 0;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public var position(get, set): Float; // Seconds
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									@:functionCode("
							 | 
						||
| 
								 | 
							
										if (vorbis == NULL) return 0;
							 | 
						||
| 
								 | 
							
										return stb_vorbis_get_sample_offset(vorbis) /
							 | 
						||
| 
								 | 
							
											(float)stb_vorbis_stream_length_in_samples(vorbis) *
							 | 
						||
| 
								 | 
							
											stb_vorbis_stream_length_in_seconds(vorbis);
							 | 
						||
| 
								 | 
							
									")
							 | 
						||
| 
								 | 
							
									function get_position(): Float {
							 | 
						||
| 
								 | 
							
										return 0;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									@:functionCode("
							 | 
						||
| 
								 | 
							
										if (vorbis == NULL) return value;
							 | 
						||
| 
								 | 
							
										unsigned int rate = stb_vorbis_get_info(vorbis).sample_rate;
							 | 
						||
| 
								 | 
							
										stb_vorbis_seek_frame(vorbis, rate * value);
							 | 
						||
| 
								 | 
							
										return value;
							 | 
						||
| 
								 | 
							
									")
							 | 
						||
| 
								 | 
							
									function set_position(value: Float): Float {
							 | 
						||
| 
								 | 
							
										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, never): Bool;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function get_finished(): Bool {
							 | 
						||
| 
								 | 
							
										return atend;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 |