Переглянути джерело

fixed wav playing, added isPlaying()

ncannasse 11 роки тому
батько
коміт
3d62dba2e6
1 змінених файлів з 37 додано та 25 видалено
  1. 37 25
      hxd/res/Sound.hx

+ 37 - 25
hxd/res/Sound.hx

@@ -1,27 +1,28 @@
 package hxd.res;
 
 class Sound extends Resource {
-	
+
 	public static var BUFFER_SIZE = 4096;
-	
+
 	public static dynamic function getGlobalVolume( s : Sound ) {
 		return 1.0;
 	}
-	
+
 	public var volume(default, set) = 1.0;
 	public var loop : Bool;
-	
+
 	#if flash
 	var snd : flash.media.Sound;
 	var channel : flash.media.SoundChannel;
-	
+
 	var mp3Data : flash.media.Sound;
 	var wavHeader : format.wav.Data.WAVEHeader;
 	var playingBytes : haxe.io.Bytes;
 	var bytesPosition : Int;
 	var mp3SampleCount : Int;
+	var playDelay : Float = 0;
 	#end
-	
+
 	public function getPosition() : Float {
 		#if flash
 		return channel.position;
@@ -29,11 +30,19 @@ class Sound extends Resource {
 		return 0.;
 		#end
 	}
-	
+
 	public function play() {
 		playAt(0);
 	}
-	
+
+	public function isPlaying() {
+		#if flash
+		return channel != null || playDelay > haxe.Timer.stamp();
+		#else
+		return false;
+		#end
+	}
+
 	#if flash
 	function onWavSample( e : flash.events.SampleDataEvent ) {
 		var input = new haxe.io.BytesInput(playingBytes,bytesPosition);
@@ -41,27 +50,28 @@ class Sound extends Resource {
 		var size = BUFFER_SIZE;
 		out.position = 0;
 		do {
+			var write = size - Std.int(out.position/8);
 			try {
 				switch( [wavHeader.channels, wavHeader.bitsPerSample] ) {
 				case [2, 16]:
-					for( i in 0...size ) {
+					for( i in 0...write ) {
 						out.writeFloat(input.readInt16() / 32767);
 						out.writeFloat(input.readInt16() / 32767);
 					}
 				case [1, 16]:
-					for( i in 0...size ) {
+					for( i in 0...write ) {
 						var f = input.readInt16() / 32767;
 						out.writeFloat(f);
 						out.writeFloat(f);
 					}
 				case [1, 8]:
-					for( i in 0...size ) {
+					for( i in 0...write ) {
 						var f = input.readByte() / 255;
 						out.writeFloat(f);
 						out.writeFloat(f);
 					}
 				case [2, 8]:
-					for( i in 0...size ) {
+					for( i in 0...write ) {
 						out.writeFloat(input.readByte() / 255);
 						out.writeFloat(input.readByte() / 255);
 					}
@@ -72,8 +82,10 @@ class Sound extends Resource {
 				if( loop )
 					input.position = 0;
 				else if( channel != null && out.position == 0 ) {
-					haxe.Timer.delay(channel.stop, 1);
+					haxe.Timer.delay(channel.stop, 150); // wait until the buffer is played
 					channel = null;
+				} else if( out.position > 0 ) {
+					playDelay = haxe.Timer.stamp() + (out.position / 8) / 44000;
 				}
 			}
 		} while( Std.int(out.position) < size * 8 && loop );
@@ -84,7 +96,7 @@ class Sound extends Resource {
 		}
 		bytesPosition = input.position;
 	}
-	
+
 	function onMp3Sample(e:flash.events.SampleDataEvent) {
 		var out = e.data;
 		out.position = 0;
@@ -105,7 +117,7 @@ class Sound extends Resource {
 		}
 		bytesPosition = position;
 	}
-	
+
 	#end
 
 	public function playAt( startPosition : Float ) {
@@ -121,20 +133,20 @@ class Sound extends Resource {
 		switch( bytes.get(0) ) {
 		case 'R'.code: // RIFF (wav)
 			var s = new format.wav.Reader(new haxe.io.BytesInput(bytes)).read();
-			
+
 			if( s.header.channels > 2 || (s.header.bitsPerSample != 8 && s.header.bitsPerSample != 16) )
 				throw "Unsupported " + s.header.bitsPerSample + "x" + s.header.channels;
-			
+
 			wavHeader = s.header;
 			playingBytes = s.data;
 			bytesPosition = 0;
 			snd.addEventListener(flash.events.SampleDataEvent.SAMPLE_DATA, onWavSample);
-			
+
 		case 255, 'I'.code: // MP3 (or ID3)
-			
+
 			snd.loadCompressedDataFromByteArray(bytes.getData(), bytes.length);
 			if( loop ) {
-				
+
 				var mp = new format.mp3.Reader(new haxe.io.BytesInput(bytes)).read();
 				var samples = mp.sampleCount;
 				var frame = mp.frames[0].data.toString();
@@ -146,14 +158,14 @@ class Sound extends Resource {
 					var end = startEnd & ((1 << 12) - 1);
 					samples -= start + end + 1152; // first frame is empty
 				}
-				
-				
+
+
 				mp3Data = snd;
 				mp3SampleCount = samples;
 				snd = new flash.media.Sound();
 				snd.addEventListener(flash.events.SampleDataEvent.SAMPLE_DATA, onMp3Sample);
 			}
-			
+
 		default:
 			throw "Unsupported sound format " + entry.path;
 		}
@@ -163,7 +175,7 @@ class Sound extends Resource {
 		#else
 		#end
 	}
-	
+
 	public function stop() {
 		#if flash
 		if( channel != null ) {
@@ -172,7 +184,7 @@ class Sound extends Resource {
 		}
 		#end
 	}
-	
+
 	function set_volume( v : Float ) {
 		volume = v;
 		#if flash