Update AudioSource with timer changes on set currentTime or length

This commit is contained in:
Joshua Granick
2015-12-14 15:10:46 -08:00
parent 9acf835d55
commit 3feb02ae68

View File

@@ -11,7 +11,6 @@ import flash.media.SoundChannel;
import lime.audio.fmod.Channel;
#end
#if lime_console
// TODO(james4k): this is terribly hacky. looking for more sane solutions. the
// caller uses an extern declaration of this function so that it does not need
@@ -24,6 +23,7 @@ void haxe_staticfunc_onFmodChannelEnd (ConsoleFmodChannel c) {
")
#end
class AudioSource {
@@ -167,8 +167,11 @@ class AudioSource {
channel.setLoopCount (this.__loops);
var old = setFmodActive (channel, this);
if (old != this) {
old.channel = Channel.INVALID;
}
}
@@ -189,15 +192,6 @@ class AudioSource {
currentTime = time;
if (timer != null) {
timer.stop ();
}
timer = new Timer (length - currentTime);
timer.run = timer_onRun;
#end
}
@@ -245,7 +239,12 @@ class AudioSource {
#elseif flash
pauseTime = 0;
if (channel != null) channel.stop ();
if (channel != null) {
channel.stop ();
}
#elseif lime_console
@@ -271,6 +270,88 @@ class AudioSource {
}
#if lime_console
// TODO(james4k): these arrays become Array<Dynamic> so a lot of hidden
// boxing and allocations going on.
// can't use Maps because we need by-value key comparisons, so use two arrays.
private static var fmodActiveChannels = new Array<Channel> ();
private static var fmodActiveSources = new Array<AudioSource> ();
// onFmodChannelEnd is called from C++ when an fmod channel end callback is
// called.
private static function onFmodChannelEnd (channel:Channel) {
var source = removeFmodActive (channel);
if (source != null) {
source.channel = Channel.INVALID;
source.onComplete.dispatch ();
}
}
// removeFmodActive disassociates a Channel with its AudioSource, returning
// the AudioSource it was associated with.
private static function removeFmodActive(key:Channel):AudioSource {
for (i in 0...fmodActiveChannels.length) {
if (fmodActiveChannels[i] == key) {
var source = fmodActiveSources[i];
// swap in the last element and pop() to remove from array
var last = fmodActiveChannels.length - 1;
fmodActiveChannels[i] = fmodActiveChannels[last];
fmodActiveSources[i] = fmodActiveSources[last];
fmodActiveChannels.pop ();
fmodActiveSources.pop ();
return source;
}
}
return null;
}
// setFmodActive associates a Channel with an AudioSource to allow for fmod
// channel callbacks to propagate to the user's AudioSource onComplete
// callbacks. Returns the previous AudioSource associated with the channel
// if there was one, or the passed in AudioSource if not.
private static function setFmodActive (key:Channel, value:AudioSource):AudioSource {
for (i in 0...fmodActiveChannels.length) {
if (fmodActiveChannels[i] == key) {
var old = fmodActiveSources[i];
fmodActiveSources[i] = value;
return old;
}
}
fmodActiveChannels.push (key);
fmodActiveSources.push (value);
return value;
}
#end
// Event Handlers
@@ -305,84 +386,6 @@ class AudioSource {
}
#if lime_console
// TODO(james4k): these arrays become Array<Dynamic> so a lot of hidden
// boxing and allocations going on.
// can't use Maps because we need by-value key comparisons, so use two arrays.
private static var fmodActiveChannels = new Array<Channel> ();
private static var fmodActiveSources = new Array<AudioSource> ();
// setFmodActive associates a Channel with an AudioSource to allow for fmod
// channel callbacks to propagate to the user's AudioSource onComplete
// callbacks. Returns the previous AudioSource associated with the channel
// if there was one, or the passed in AudioSource if not.
private static function setFmodActive (key:Channel, value:AudioSource):AudioSource {
for (i in 0...fmodActiveChannels.length) {
if (fmodActiveChannels[i] == key) {
var old = fmodActiveSources[i];
fmodActiveSources[i] = value;
return old;
}
}
fmodActiveChannels.push (key);
fmodActiveSources.push (value);
return value;
}
// removeFmodActive disassociates a Channel with its AudioSource, returning
// the AudioSource it was associated with.
private static function removeFmodActive(key:Channel):AudioSource {
for (i in 0...fmodActiveChannels.length) {
if (fmodActiveChannels[i] == key) {
var source = fmodActiveSources[i];
// swap in the last element and pop() to remove from array
var last = fmodActiveChannels.length - 1;
fmodActiveChannels[i] = fmodActiveChannels[last];
fmodActiveSources[i] = fmodActiveSources[last];
fmodActiveChannels.pop ();
fmodActiveSources.pop ();
return source;
}
}
return null;
}
// onFmodChannelEnd is called from C++ when an fmod channel end callback is
// called.
private static function onFmodChannelEnd (channel:Channel) {
var source = removeFmodActive (channel);
if (source != null) {
source.channel = Channel.INVALID;
source.onComplete.dispatch ();
}
}
#end
// Get & Set Methods
@@ -433,6 +436,25 @@ class AudioSource {
}
if (playing) {
if (timer != null) {
timer.stop ();
}
var timeRemaining = length - (value + offset);
if (timeRemaining > 0) {
timer = new Timer (timeRemaining);
timer.run = timer_onRun;
}
}
return value;
#end
@@ -482,32 +504,6 @@ class AudioSource {
}
private inline function get_loops ():Int {
#if lime_console
if (channel.valid) {
__loops = channel.getLoopCount ();
}
#end
return __loops;
}
private inline function set_loops (loops:Int):Int {
#if lime_console
if (channel.valid) {
channel.setLoopCount (loops);
}
#end
return __loops = loops;
}
private function get_length ():Int {
if (__length != null) {
@@ -536,9 +532,62 @@ class AudioSource {
private function set_length (value:Int):Int {
if (playing && __length != value) {
if (timer != null) {
timer.stop ();
}
var timeRemaining = value - currentTime;
if (timeRemaining > 0) {
timer = new Timer (value - currentTime);
timer.run = timer_onRun;
}
}
return __length = value;
}
private function get_loops ():Int {
#if lime_console
if (channel.valid) {
__loops = channel.getLoopCount ();
}
#end
return __loops;
}
private function set_loops (loops:Int):Int {
#if lime_console
if (channel.valid) {
channel.setLoopCount (loops);
}
#end
return __loops = loops;
}
}