Update AudioSource with timer changes on set currentTime or length
This commit is contained in:
@@ -11,7 +11,6 @@ import flash.media.SoundChannel;
|
|||||||
import lime.audio.fmod.Channel;
|
import lime.audio.fmod.Channel;
|
||||||
#end
|
#end
|
||||||
|
|
||||||
|
|
||||||
#if lime_console
|
#if lime_console
|
||||||
// TODO(james4k): this is terribly hacky. looking for more sane solutions. the
|
// 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
|
// 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
|
#end
|
||||||
|
|
||||||
|
|
||||||
class AudioSource {
|
class AudioSource {
|
||||||
|
|
||||||
|
|
||||||
@@ -152,51 +152,45 @@ class AudioSource {
|
|||||||
#if html5
|
#if html5
|
||||||
#elseif flash
|
#elseif flash
|
||||||
|
|
||||||
if (channel != null) channel.stop ();
|
if (channel != null) channel.stop ();
|
||||||
var channel = buffer.src.play (pauseTime / 1000);
|
var channel = buffer.src.play (pauseTime / 1000);
|
||||||
|
|
||||||
#elseif lime_console
|
#elseif lime_console
|
||||||
|
|
||||||
if (channel.valid) {
|
if (channel.valid) {
|
||||||
|
|
||||||
channel.resume ();
|
channel.resume ();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
channel = buffer.src.play ();
|
channel = buffer.src.play ();
|
||||||
channel.setLoopCount (this.__loops);
|
channel.setLoopCount (this.__loops);
|
||||||
|
|
||||||
var old = setFmodActive (channel, this);
|
var old = setFmodActive (channel, this);
|
||||||
if (old != this) {
|
|
||||||
old.channel = Channel.INVALID;
|
if (old != this) {
|
||||||
}
|
|
||||||
|
old.channel = Channel.INVALID;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
if (playing || id == 0) {
|
if (playing || id == 0) {
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
playing = true;
|
playing = true;
|
||||||
|
|
||||||
var time = currentTime;
|
var time = currentTime;
|
||||||
|
|
||||||
AL.sourcePlay (id);
|
AL.sourcePlay (id);
|
||||||
|
|
||||||
currentTime = time;
|
currentTime = time;
|
||||||
|
|
||||||
if (timer != null) {
|
|
||||||
|
|
||||||
timer.stop ();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
timer = new Timer (length - currentTime);
|
|
||||||
timer.run = timer_onRun;
|
|
||||||
|
|
||||||
#end
|
#end
|
||||||
|
|
||||||
@@ -208,31 +202,31 @@ class AudioSource {
|
|||||||
#if html5
|
#if html5
|
||||||
#elseif flash
|
#elseif flash
|
||||||
|
|
||||||
if (channel != null) {
|
if (channel != null) {
|
||||||
|
|
||||||
pauseTime = Std.int (channel.position * 1000);
|
pauseTime = Std.int (channel.position * 1000);
|
||||||
channel.stop ();
|
channel.stop ();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#elseif lime_console
|
#elseif lime_console
|
||||||
|
|
||||||
if (channel.valid) {
|
if (channel.valid) {
|
||||||
|
|
||||||
channel.pause ();
|
channel.pause ();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
playing = false;
|
playing = false;
|
||||||
AL.sourcePause (id);
|
AL.sourcePause (id);
|
||||||
|
|
||||||
if (timer != null) {
|
if (timer != null) {
|
||||||
|
|
||||||
timer.stop ();
|
timer.stop ();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#end
|
#end
|
||||||
|
|
||||||
@@ -244,33 +238,120 @@ class AudioSource {
|
|||||||
#if html5
|
#if html5
|
||||||
#elseif flash
|
#elseif flash
|
||||||
|
|
||||||
pauseTime = 0;
|
pauseTime = 0;
|
||||||
if (channel != null) channel.stop ();
|
|
||||||
|
if (channel != null) {
|
||||||
|
|
||||||
|
channel.stop ();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#elseif lime_console
|
#elseif lime_console
|
||||||
|
|
||||||
if (channel.valid) {
|
if (channel.valid) {
|
||||||
|
|
||||||
channel.stop ();
|
channel.stop ();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
playing = false;
|
playing = false;
|
||||||
AL.sourceStop (id);
|
AL.sourceStop (id);
|
||||||
|
|
||||||
if (timer != null) {
|
if (timer != null) {
|
||||||
|
|
||||||
timer.stop ();
|
timer.stop ();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#end
|
#end
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#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
|
// 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
|
// Get & Set Methods
|
||||||
@@ -394,17 +397,17 @@ class AudioSource {
|
|||||||
|
|
||||||
#if html5
|
#if html5
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#elseif flash
|
#elseif flash
|
||||||
|
|
||||||
return Std.int (channel.position);
|
return Std.int (channel.position);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
var time = Std.int (AL.getSourcef (id, AL.SEC_OFFSET) * 1000) - offset;
|
var time = Std.int (AL.getSourcef (id, AL.SEC_OFFSET) * 1000) - offset;
|
||||||
if (time < 0) return 0;
|
if (time < 0) return 0;
|
||||||
return time;
|
return time;
|
||||||
|
|
||||||
#end
|
#end
|
||||||
|
|
||||||
@@ -415,25 +418,44 @@ class AudioSource {
|
|||||||
|
|
||||||
#if html5
|
#if html5
|
||||||
|
|
||||||
return pauseTime = value;
|
return pauseTime = value;
|
||||||
|
|
||||||
#elseif flash
|
#elseif flash
|
||||||
|
|
||||||
// TODO: create new sound channel
|
// TODO: create new sound channel
|
||||||
//channel.position = value;
|
//channel.position = value;
|
||||||
return pauseTime = value;
|
return pauseTime = value;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
if (buffer != null) {
|
if (buffer != null) {
|
||||||
|
|
||||||
AL.sourceRewind (id);
|
AL.sourceRewind (id);
|
||||||
if (playing) AL.sourcePlay (id);
|
if (playing) AL.sourcePlay (id);
|
||||||
AL.sourcef (id, AL.SEC_OFFSET, (value + offset) / 1000);
|
AL.sourcef (id, AL.SEC_OFFSET, (value + offset) / 1000);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (playing) {
|
||||||
|
|
||||||
|
if (timer != null) {
|
||||||
|
|
||||||
|
timer.stop ();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
var timeRemaining = length - (value + offset);
|
||||||
|
|
||||||
|
if (timeRemaining > 0) {
|
||||||
|
|
||||||
|
timer = new Timer (timeRemaining);
|
||||||
|
timer.run = timer_onRun;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
|
||||||
#end
|
#end
|
||||||
|
|
||||||
@@ -444,15 +466,15 @@ class AudioSource {
|
|||||||
|
|
||||||
#if html5
|
#if html5
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
#elseif flash
|
#elseif flash
|
||||||
|
|
||||||
return channel.soundTransform.volume;
|
return channel.soundTransform.volume;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
return AL.getSourcef (id, AL.GAIN);
|
return AL.getSourcef (id, AL.GAIN);
|
||||||
|
|
||||||
#end
|
#end
|
||||||
|
|
||||||
@@ -463,51 +485,25 @@ class AudioSource {
|
|||||||
|
|
||||||
#if html5
|
#if html5
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
#elseif flash
|
#elseif flash
|
||||||
|
|
||||||
var soundTransform = channel.soundTransform;
|
var soundTransform = channel.soundTransform;
|
||||||
soundTransform.volume = value;
|
soundTransform.volume = value;
|
||||||
channel.soundTransform = soundTransform;
|
channel.soundTransform = soundTransform;
|
||||||
return value;
|
return value;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
AL.sourcef (id, AL.GAIN, value);
|
AL.sourcef (id, AL.GAIN, value);
|
||||||
return value;
|
return value;
|
||||||
|
|
||||||
#end
|
#end
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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 {
|
private function get_length ():Int {
|
||||||
|
|
||||||
if (__length != null) {
|
if (__length != null) {
|
||||||
@@ -518,16 +514,16 @@ class AudioSource {
|
|||||||
|
|
||||||
#if html5
|
#if html5
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#elseif flash
|
#elseif flash
|
||||||
|
|
||||||
return Std.int (buffer.src.length);
|
return Std.int (buffer.src.length);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
var samples = (buffer.data.length * 8) / (buffer.channels * buffer.bitsPerSample);
|
var samples = (buffer.data.length * 8) / (buffer.channels * buffer.bitsPerSample);
|
||||||
return Std.int (samples / buffer.sampleRate * 1000) - offset;
|
return Std.int (samples / buffer.sampleRate * 1000) - offset;
|
||||||
|
|
||||||
#end
|
#end
|
||||||
|
|
||||||
@@ -536,9 +532,62 @@ class AudioSource {
|
|||||||
|
|
||||||
private function set_length (value:Int):Int {
|
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;
|
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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user