瀏覽代碼

added Channel.fadeTo

Nicolas Cannasse 8 年之前
父節點
當前提交
34e290df32
共有 3 個文件被更改,包括 52 次插入10 次删除
  1. 15 3
      hxd/snd/Channel.hx
  2. 27 1
      hxd/snd/ChannelBase.hx
  3. 10 6
      hxd/snd/Driver.hx

+ 15 - 3
hxd/snd/Channel.hx

@@ -64,10 +64,22 @@ class Channel extends ChannelBase {
 		return streaming = v;
 	}
 
-	public function calcAudibleGain() {
-		audibleGain = volume * channelGroup.volume * soundGroup.volume;
+	override function updateCurrentVolume( now : Float ) {
+		if( pause && currentFade != null ) {
+			var f = currentFade;
+			currentFade = null;
+			updateCurrentVolume(now);
+			currentFade = f;
+		}
+		super.updateCurrentVolume(now);
+		channelGroup.updateCurrentVolume(now);
+		currentVolume *= channelGroup.currentVolume * soundGroup.volume;
+	}
+
+	public function calcAudibleGain( now : Float ) {
+		updateCurrentVolume(now);
+		audibleGain = currentVolume;
 		for (e in effects) audibleGain *= e.gain;
-		return audibleGain;
 	}
 
 	/**

+ 27 - 1
hxd/snd/ChannelBase.hx

@@ -3,10 +3,12 @@ package hxd.snd;
 class ChannelBase {
 
 	public var priority : Float = 0.;
-	public var volume   : Float = 1.;
 	public var pan      : Float = 0.;
 	public var mute     : Bool = false;
 	public var effects  : Array<Effect> = [];
+	public var volume(default, set) : Float = 1.;
+	var currentFade : { start : Float, duration : Float, startVolume : Float, targetVolume : Float, onEnd : Void -> Void };
+	var currentVolume : Float; // global volume
 
 	function new() {
 	}
@@ -19,6 +21,30 @@ class ChannelBase {
 		return null;
 	}
 
+	function set_volume(v) {
+		currentFade = null;
+		return volume = v;
+	}
+
+	public function fadeTo( volume : Float, ?time = 1., ?onEnd ) {
+		currentFade = { start : haxe.Timer.stamp(), duration : time, startVolume : this.volume, targetVolume : volume, onEnd : onEnd };
+	}
+
+	function updateCurrentVolume( now : Float ) {
+		if( currentFade != null ) {
+			var f = currentFade;
+			var dt = now - f.start;
+			if( dt >= f.duration ) {
+				volume = f.targetVolume;
+				if( f.onEnd != null ) f.onEnd();
+			} else {
+				volume = f.startVolume + (dt / f.duration) * (f.targetVolume - f.startVolume);
+				currentFade = f; // restore
+			}
+		}
+		currentVolume = volume;
+	}
+
 	public function addEffect<T:Effect>( e : T ) : T {
 		if( e == null ) throw "Can't add null effect";
 		effects.push(e);

+ 10 - 6
hxd/snd/Driver.hx

@@ -146,6 +146,12 @@ class Driver {
 			channels.stop();
 	}
 
+	public function cleanCache() {
+		for( b in buffers.copy() )
+			if( b.playCount == 0 )
+				releaseBuffer(b);
+	}
+
 	public function dispose() {
 		stopAll();
 
@@ -261,9 +267,8 @@ class Driver {
 		// calc audible gain & virtualize inaudible channels
 		var c = channels;
 		while (c != null) {
-			c.isVirtual = false;
-			c.calcAudibleGain();
-			if (c.pause || c.mute || c.channelGroup.mute || c.audibleGain < 1e-5 ) c.isVirtual = true;
+			c.calcAudibleGain(now);
+			c.isVirtual = c.pause || c.mute || c.channelGroup.mute || c.audibleGain < 1e-5;
 			c = c.next;
 		}
 
@@ -377,7 +382,7 @@ class Driver {
 			s.loop = loopFlag;
 			AL.sourcei(s.inst, AL.LOOPING, loopFlag ? AL.TRUE : AL.FALSE);
 		}
-		var v = c.volume * c.channelGroup.volume * c.soundGroup.volume;
+		var v = c.currentVolume;
 		if( s.volume != v ) {
 			s.volume = v;
 			AL.sourcef(s.inst, AL.GAIN, v);
@@ -411,7 +416,6 @@ class Driver {
 			s.channel.source = null;
 			s.channel = null;
 		}
-		
 		if( s.playing ) {
 			s.playing = false;
 			AL.sourceStop(s.inst);
@@ -608,7 +612,7 @@ class Driver {
 
 	function sortChannel(a : Channel, b : Channel) {
 		if (a.isVirtual != b.isVirtual)
-			return (a.isVirtual && !b.isVirtual) ? 1 : -1;
+			return a.isVirtual ? 1 : -1;
 
 		if (a.channelGroup.priority != b.channelGroup.priority)
 			return a.channelGroup.priority < b.channelGroup.priority ? 1 : -1;