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