98 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
		
		
			
		
	
	
			98 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
| 
								 | 
							
								package kha;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import haxe.io.Bytes;
							 | 
						||
| 
								 | 
							
								import haxe.io.BytesOutput;
							 | 
						||
| 
								 | 
							
								import kha.audio2.ogg.vorbis.Reader;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Contains compressed or uncompressed audio data.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								@:cppFileCode("\n#define STB_VORBIS_HEADER_ONLY\n#include <kinc/libs/stb_vorbis.c>")
							 | 
						||
| 
								 | 
							
								class Sound implements Resource {
							 | 
						||
| 
								 | 
							
									public var compressedData: Bytes;
							 | 
						||
| 
								 | 
							
									public var uncompressedData: kha.arrays.Float32Array;
							 | 
						||
| 
								 | 
							
									public var length: Float = 0; // in seconds
							 | 
						||
| 
								 | 
							
									public var channels: Int = 0;
							 | 
						||
| 
								 | 
							
									public var sampleRate: Int = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function new() {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									#if kha_kore
							 | 
						||
| 
								 | 
							
									public function uncompress(done: Void->Void): Void {
							 | 
						||
| 
								 | 
							
										if (uncompressedData != null) {
							 | 
						||
| 
								 | 
							
											done();
							 | 
						||
| 
								 | 
							
											return;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										var samples: Int = 0;
							 | 
						||
| 
								 | 
							
										var channels: Int = 0;
							 | 
						||
| 
								 | 
							
										var samplesPerSecond: Int = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										untyped __cpp__("int16_t *data = nullptr");
							 | 
						||
| 
								 | 
							
										untyped __cpp__("samples = stb_vorbis_decode_memory((uint8_t*)compressedData->b->GetBase(), compressedData->length, &channels, &samplesPerSecond, &data)");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if (channels == 1) {
							 | 
						||
| 
								 | 
							
											length = samples / samplesPerSecond;
							 | 
						||
| 
								 | 
							
											uncompressedData = new kha.arrays.Float32Array(samples * 2);
							 | 
						||
| 
								 | 
							
											for (i in 0...samples) {
							 | 
						||
| 
								 | 
							
												untyped __cpp__("*((float*)&this->uncompressedData->self.data[({0} * 2) * 4]) = data[{0}] / 32767.0f", i);
							 | 
						||
| 
								 | 
							
												untyped __cpp__("*((float*)&this->uncompressedData->self.data[({0} * 2 + 1) * 4]) = data[{0}] / 32767.0f", i);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else {
							 | 
						||
| 
								 | 
							
											length = samples / samplesPerSecond;
							 | 
						||
| 
								 | 
							
											samples *= channels;
							 | 
						||
| 
								 | 
							
											uncompressedData = new kha.arrays.Float32Array(samples);
							 | 
						||
| 
								 | 
							
											for (i in 0...samples) {
							 | 
						||
| 
								 | 
							
												untyped __cpp__("*((float*)&this->uncompressedData->self.data[{0} * 4]) = data[{0}] / 32767.0f", i);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										this.channels = channels;
							 | 
						||
| 
								 | 
							
										this.sampleRate = samplesPerSecond;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										untyped __cpp__("delete[] data");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										compressedData = null;
							 | 
						||
| 
								 | 
							
										done();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									#else
							 | 
						||
| 
								 | 
							
									public function uncompress(done: Void->Void): Void {
							 | 
						||
| 
								 | 
							
										#if (!kha_no_ogg)
							 | 
						||
| 
								 | 
							
										if (uncompressedData != null) {
							 | 
						||
| 
								 | 
							
											done();
							 | 
						||
| 
								 | 
							
											return;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										var output = new BytesOutput();
							 | 
						||
| 
								 | 
							
										var header = Reader.readAll(compressedData, output, true);
							 | 
						||
| 
								 | 
							
										var soundBytes = output.getBytes();
							 | 
						||
| 
								 | 
							
										var count = Std.int(soundBytes.length / 4);
							 | 
						||
| 
								 | 
							
										if (header.channel == 1) {
							 | 
						||
| 
								 | 
							
											length = count / kha.audio2.Audio.samplesPerSecond; // header.sampleRate;
							 | 
						||
| 
								 | 
							
											uncompressedData = new kha.arrays.Float32Array(count * 2);
							 | 
						||
| 
								 | 
							
											for (i in 0...count) {
							 | 
						||
| 
								 | 
							
												uncompressedData[i * 2 + 0] = soundBytes.getFloat(i * 4);
							 | 
						||
| 
								 | 
							
												uncompressedData[i * 2 + 1] = soundBytes.getFloat(i * 4);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else {
							 | 
						||
| 
								 | 
							
											length = count / 2 / kha.audio2.Audio.samplesPerSecond; // header.sampleRate;
							 | 
						||
| 
								 | 
							
											uncompressedData = new kha.arrays.Float32Array(count);
							 | 
						||
| 
								 | 
							
											for (i in 0...count) {
							 | 
						||
| 
								 | 
							
												uncompressedData[i] = soundBytes.getFloat(i * 4);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										channels = header.channel;
							 | 
						||
| 
								 | 
							
										sampleRate = header.sampleRate;
							 | 
						||
| 
								 | 
							
										compressedData = null;
							 | 
						||
| 
								 | 
							
										done();
							 | 
						||
| 
								 | 
							
										#end
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									#end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function unload() {
							 | 
						||
| 
								 | 
							
										compressedData = null;
							 | 
						||
| 
								 | 
							
										uncompressedData = null;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 |