Add Howler.js

This commit is contained in:
Joshua Granick
2016-10-03 16:53:39 -07:00
parent 53cab7043b
commit e5d83cdcff
7 changed files with 748 additions and 100 deletions

4
dependencies/howler.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -6,6 +6,9 @@
<haxedef name="native" if="cpp || neko || nodejs || cs" />
<set name="native" if="cpp || neko || nodejs || cs" />
<haxedef name="howlerjs" if="html5" />
<set name="howlerjs" if="html5" />
<haxedef name="lime-html5" if="html5" />
<haxedef name="lime-native" if="native" />
<haxedef name="lime-cffi" if="native" />
@@ -43,11 +46,11 @@
<ndll name="std" haxelib="hxcpp" if="cpp" unless="static_link" />
<ndll name="regexp" haxelib="hxcpp" if="cpp" unless="static_link" />
<ndll name="zlib" haxelib="hxcpp" if="cpp" unless="emscripten || ios || static_link || tvos" />
<ndll name="lime" if="cpp || neko || nodejs" />
</section>
<dependency name="extension-api" path="dependencies/extension-api" if="android" />
<dependency path="dependencies/howler.min.js" if="html5 howlerjs" />
<dependency path="dependencies/pako.min.js" if="html5" />
<dependency path="dependencies/webgl-debug.js" if="html5 webgl-debug" />
<dependency path="dependencies/stats.min.js" if="html5 stats" />

View File

@@ -3,10 +3,11 @@ package lime.audio;
import haxe.io.Bytes;
import lime.audio.openal.AL;
//import lime.net.URLLoader;
//import lime.net.URLRequest;
import lime.utils.UInt8Array;
#if howlerjs
import lime.audio.howlerjs.Howl;
#end
#if (js && html5)
import js.html.Audio;
#elseif flash
@@ -29,16 +30,13 @@ class AudioBuffer {
public var data:UInt8Array;
public var id:UInt;
public var sampleRate:Int;
public var src (get, set):Dynamic;
#if (js && html5)
public var src:Audio;
#elseif flash
public var src:Sound;
#elseif lime_console
public var src:FMODSound;
#else
public var src:Dynamic;
#end
@:noCompletion private var __srcAudio:#if (js && html5) Audio #else Dynamic #end;
@:noCompletion private var __srcCustom:Dynamic;
@:noCompletion private var __srcFMODSound:#if lime_console FMODSound #else Dynamic #end;
@:noCompletion private var __srcHowl:#if howlerjs Howl #else Dynamic #end;
@:noCompletion private var __srcSound:#if flash Sound #else Dynamic #end;
public function new () {
@@ -113,7 +111,13 @@ class AudioBuffer {
if (path == null) return null;
#if lime_console
#if (js && html5 && howlerjs)
var audioBuffer = new AudioBuffer ();
audioBuffer.__srcHowl = new Howl ({ src: [ path ] });
return audioBuffer;
#elseif lime_console
var mode = StringTools.endsWith(path, ".wav") ? FMODMode.LOOP_OFF : FMODMode.LOOP_NORMAL;
var sound:FMODSound = FMODSound.fromFile (path, mode);
@@ -132,7 +136,7 @@ class AudioBuffer {
audioBuffer.channels = 1;
audioBuffer.data = null;
audioBuffer.sampleRate = 0;
audioBuffer.src = sound;
audioBuffer.__srcFMODSound = sound;
cpp.vm.Gc.setFinalizer (audioBuffer, cpp.Function.fromStaticFunction (finalize));
return audioBuffer;
@@ -169,6 +173,32 @@ class AudioBuffer {
}
public static function fromFiles (paths:Array<String>):AudioBuffer {
#if (js && html5 && howlerjs)
var audioBuffer = new AudioBuffer ();
audioBuffer.__srcHowl = new Howl ({ src: paths });
return audioBuffer;
#else
var buffer = null;
for (path in paths) {
buffer = AudioBuffer.fromFile (path);
if (buffer != null) break;
}
return buffer;
#end
}
public static function fromURL (url:String, handler:AudioBuffer->Void):Void {
if (url != null && url.indexOf ("http://") == -1 && url.indexOf ("https://") == -1) {
@@ -209,6 +239,78 @@ class AudioBuffer {
}
// Get & Set Methods
private function get_src ():Dynamic {
#if (js && html5)
#if howlerjs
return __srcHowl;
#else
return __srcAudio;
#end
#elseif flash
return __srcSound;
#elseif lime_console
return __srcFMODSound;
#else
return __srcCustom;
#end
}
private function set_src (value:Dynamic):Dynamic {
#if (js && html5)
#if howlerjs
return __srcHowl = value;
#else
return __srcAudio = value;
#end
#elseif flash
return __srcSound = value;
#elseif lime_console
return __srcFMODSound = value;
#else
return __srcCustom = value;
#end
}
// Native Methods
#if (lime_cffi && !macro)
@:cffi private static function lime_audio_load (data:Dynamic, buffer:Dynamic):Dynamic;
#end

View File

@@ -24,6 +24,8 @@ void haxe_staticfunc_onFmodChannelEnd (ConsoleFmodChannel c) {
")
#end
@:access(lime.audio.AudioBuffer)
class AudioSource {
@@ -158,10 +160,29 @@ class AudioSource {
public function play ():Void {
#if html5
#if howlerjs
if (playing || buffer == null) {
return;
}
playing = true;
var time = currentTime;
__completed = false;
id = buffer.__srcHowl.play ();
buffer.__srcHowl.on ("end", howl_onEnd, id);
currentTime = time;
#end
#elseif flash
if (channel != null) channel.stop ();
channel = buffer.src.play (pauseTime / 1000 + offset, loops + 1);
channel = buffer.__srcSound.play (pauseTime / 1000 + offset, loops + 1);
#elseif lime_console
@@ -171,7 +192,7 @@ class AudioSource {
} else {
channel = buffer.src.play ();
channel = buffer.__srcSound.play ();
channel.setLoopCount (__loops);
if (__gain < 1.0) {
channel.setVolume (__gain);
@@ -211,6 +232,12 @@ class AudioSource {
public function pause ():Void {
#if html5
#if howlerjs
playing = false;
buffer.__srcHowl.pause (id);
#end
#elseif flash
if (channel != null) {
@@ -247,6 +274,12 @@ class AudioSource {
public function stop ():Void {
#if html5
#if howlerjs
playing = false;
buffer.__srcHowl.stop (id);
#end
#elseif flash
pauseTime = 0;
@@ -370,6 +403,34 @@ class AudioSource {
private function howl_onEnd () {
#if howlerjs
playing = false;
if (loops > 0) {
loops--;
stop ();
//currentTime = 0;
play ();
return;
} else {
buffer.__srcHowl.stop (id);
}
__completed = true;
onComplete.dispatch ();
#end
}
private function timer_onRun () {
#if (!flash && !html5)
@@ -408,9 +469,23 @@ class AudioSource {
private function get_currentTime ():Int {
#if html5
#if howlerjs
if (__completed) {
return length;
} else {
return Std.int (buffer.__srcHowl.seek (id) * 1000);
}
#else
return 0;
#end
#elseif flash
if (channel != null) {
@@ -450,9 +525,22 @@ class AudioSource {
private function set_currentTime (value:Int):Int {
#if html5
#if howlerjs
if (buffer != null) {
//if (playing) buffer.__srcHowl.play (id);
buffer.__srcHowl.seek ((value + offset) / 1000, id);
}
return value;
#else
return pauseTime = value;
#end
#elseif flash
// TODO: create new sound channel
@@ -508,9 +596,15 @@ class AudioSource {
private function get_gain ():Float {
#if html5
#if howlerjs
return buffer.__srcHowl.volume (id);
#else
return 1;
#end
#elseif flash
return channel.soundTransform.volume;
@@ -537,9 +631,16 @@ class AudioSource {
private function set_gain (value:Float):Float {
#if html5
#if howlerjs
buffer.__srcHowl.volume (value, id);
return value;
#else
return 1;
#end
#elseif flash
var soundTransform = channel.soundTransform;
@@ -576,12 +677,18 @@ class AudioSource {
}
#if html5
#if howlerjs
return Std.int (buffer.__srcHowl.duration () * 1000);
#else
return 0;
#end
#elseif flash
return Std.int (buffer.src.length) - offset;
return Std.int (buffer.__srcSound.length) - offset;
#elseif lime_console
@@ -670,6 +777,11 @@ class AudioSource {
private function get_position ():Vector4 {
#if html5
#if howlerjs
// TODO: Use 3D audio plugin
#end
#elseif flash
__position.x = channel.soundTransform.pan;

View File

@@ -5,6 +5,8 @@ package lime.audio;
import js.html.Audio;
#end
@:access(lime.audio.AudioBuffer)
class HTML5AudioContext {
@@ -30,9 +32,9 @@ class HTML5AudioContext {
public function canPlayType (buffer:AudioBuffer, type:String):String {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
return buffer.src.canPlayType (type);
return buffer.__srcAudio.canPlayType (type);
}
#end
@@ -46,8 +48,8 @@ class HTML5AudioContext {
#if (js && html5)
var buffer = new AudioBuffer ();
buffer.src = new Audio ();
buffer.src.src = urlString;
buffer.__srcAudio = new Audio ();
buffer.__srcAudio.src = urlString;
return buffer;
#else
return null;
@@ -60,9 +62,9 @@ class HTML5AudioContext {
public function getAudioDecodedByteCount (buffer:AudioBuffer):Int {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
return buffer.src.audioDecodedByteCount;
return buffer.__srcAudio.audioDecodedByteCount;
}
#end
@@ -76,9 +78,9 @@ class HTML5AudioContext {
public function getAutoplay (buffer:AudioBuffer):Bool {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
return buffer.src.autoplay;
return buffer.__srcAudio.autoplay;
}
#end
@@ -91,9 +93,9 @@ class HTML5AudioContext {
public function getBuffered (buffer:AudioBuffer):Dynamic /*TimeRanges*/ {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
return buffer.src.buffered;
return buffer.__srcAudio.buffered;
}
#end
@@ -107,9 +109,9 @@ class HTML5AudioContext {
public function getController (buffer:AudioBuffer):Dynamic /*MediaController*/ {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
return buffer.src.controller;
return buffer.__srcAudio.controller;
}
#end
@@ -123,9 +125,9 @@ class HTML5AudioContext {
public function getCurrentSrc (buffer:AudioBuffer):String {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
return buffer.src.currentSrc;
return buffer.__srcAudio.currentSrc;
}
#end
@@ -138,9 +140,9 @@ class HTML5AudioContext {
public function getCurrentTime (buffer:AudioBuffer):Float {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
return buffer.src.currentTime;
return buffer.__srcAudio.currentTime;
}
#end
@@ -153,9 +155,9 @@ class HTML5AudioContext {
public function getDefaultPlaybackRate (buffer:AudioBuffer):Float {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
return buffer.src.defaultPlaybackRate;
return buffer.__srcAudio.defaultPlaybackRate;
}
#end
@@ -168,9 +170,9 @@ class HTML5AudioContext {
public function getDuration (buffer:AudioBuffer):Float {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
return buffer.src.duration;
return buffer.__srcAudio.duration;
}
#end
@@ -183,9 +185,9 @@ class HTML5AudioContext {
public function getEnded (buffer:AudioBuffer):Bool {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
return buffer.src.ended;
return buffer.__srcAudio.ended;
}
#end
@@ -198,9 +200,9 @@ class HTML5AudioContext {
public function getError (buffer:AudioBuffer):Dynamic /*MediaError*/ {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
return buffer.src.error;
return buffer.__srcAudio.error;
}
#end
@@ -214,9 +216,9 @@ class HTML5AudioContext {
public function getInitialTime (buffer:AudioBuffer):Float {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
return buffer.src.initialTime;
return buffer.__srcAudio.initialTime;
}
#end
@@ -230,9 +232,9 @@ class HTML5AudioContext {
public function getLoop (buffer:AudioBuffer):Bool {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
return buffer.src.loop;
return buffer.__srcAudio.loop;
}
#end
@@ -246,9 +248,9 @@ class HTML5AudioContext {
public function getMediaGroup (buffer:AudioBuffer):String {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
return buffer.src.mediaGroup;
return buffer.__srcAudio.mediaGroup;
}
#end
@@ -262,9 +264,9 @@ class HTML5AudioContext {
public function getMuted (buffer:AudioBuffer):Bool {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
return buffer.src.muted;
return buffer.__srcAudio.muted;
}
#end
@@ -277,9 +279,9 @@ class HTML5AudioContext {
public function getNetworkState (buffer:AudioBuffer):Int {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
return buffer.src.networkState;
return buffer.__srcAudio.networkState;
}
#end
@@ -292,9 +294,9 @@ class HTML5AudioContext {
public function getPaused (buffer:AudioBuffer):Bool {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
return buffer.src.paused;
return buffer.__srcAudio.paused;
}
#end
@@ -307,9 +309,9 @@ class HTML5AudioContext {
public function getPlaybackRate (buffer:AudioBuffer):Float {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
return buffer.src.playbackRate;
return buffer.__srcAudio.playbackRate;
}
#end
@@ -322,9 +324,9 @@ class HTML5AudioContext {
public function getPlayed (buffer:AudioBuffer):Dynamic /*TimeRanges*/ {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
return buffer.src.played;
return buffer.__srcAudio.played;
}
#end
@@ -337,9 +339,9 @@ class HTML5AudioContext {
public function getPreload (buffer:AudioBuffer):String {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
return buffer.src.preload;
return buffer.__srcAudio.preload;
}
#end
@@ -352,9 +354,9 @@ class HTML5AudioContext {
public function getReadyState (buffer:AudioBuffer):Int {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
return buffer.src.readyState;
return buffer.__srcAudio.readyState;
}
#end
@@ -367,9 +369,9 @@ class HTML5AudioContext {
public function getSeekable (buffer:AudioBuffer):Dynamic /*TimeRanges*/ {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
return buffer.src.seekable;
return buffer.__srcAudio.seekable;
}
#end
@@ -382,9 +384,9 @@ class HTML5AudioContext {
public function getSeeking (buffer:AudioBuffer):Bool {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
return buffer.src.seeking;
return buffer.__srcAudio.seeking;
}
#end
@@ -397,9 +399,9 @@ class HTML5AudioContext {
public function getSrc (buffer:AudioBuffer):String {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
return buffer.src.src;
return buffer.__srcAudio.src;
}
#end
@@ -412,9 +414,9 @@ class HTML5AudioContext {
public function getStartTime (buffer:AudioBuffer):Float {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
return buffer.src.playbackRate;
return buffer.__srcAudio.playbackRate;
}
#end
@@ -427,9 +429,9 @@ class HTML5AudioContext {
public function getVolume (buffer:AudioBuffer):Float {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
return buffer.src.volume;
return buffer.__srcAudio.volume;
}
#end
@@ -442,9 +444,9 @@ class HTML5AudioContext {
public function load (buffer:AudioBuffer):Void {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
return buffer.src.load ();
return buffer.__srcAudio.load ();
}
#end
@@ -455,9 +457,9 @@ class HTML5AudioContext {
public function pause (buffer:AudioBuffer):Void {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
return buffer.src.pause ();
return buffer.__srcAudio.pause ();
}
#end
@@ -468,9 +470,9 @@ class HTML5AudioContext {
public function play (buffer:AudioBuffer):Void {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
return buffer.src.play ();
return buffer.__srcAudio.play ();
}
#end
@@ -481,9 +483,9 @@ class HTML5AudioContext {
public function setAutoplay (buffer:AudioBuffer, value:Bool):Void {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
buffer.src.autoplay = value;
buffer.__srcAudio.autoplay = value;
}
#end
@@ -495,9 +497,9 @@ class HTML5AudioContext {
public function setController (buffer:AudioBuffer, value:Dynamic /*MediaController*/):Void {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
buffer.src.controller = value;
buffer.__srcAudio.controller = value;
}
#end
@@ -509,9 +511,9 @@ class HTML5AudioContext {
public function setCurrentTime (buffer:AudioBuffer, value:Float):Void {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
buffer.src.currentTime = value;
buffer.__srcAudio.currentTime = value;
}
#end
@@ -522,9 +524,9 @@ class HTML5AudioContext {
public function setDefaultPlaybackRate (buffer:AudioBuffer, value:Float):Void {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
buffer.src.defaultPlaybackRate = value;
buffer.__srcAudio.defaultPlaybackRate = value;
}
#end
@@ -535,9 +537,9 @@ class HTML5AudioContext {
public function setLoop (buffer:AudioBuffer, value:Bool):Void {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
buffer.src.loop = value;
buffer.__srcAudio.loop = value;
}
#end
@@ -549,9 +551,9 @@ class HTML5AudioContext {
public function setMediaGroup (buffer:AudioBuffer, value:String):Void {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
buffer.src.mediaGroup = value;
buffer.__srcAudio.mediaGroup = value;
}
#end
@@ -563,9 +565,9 @@ class HTML5AudioContext {
public function setMuted (buffer:AudioBuffer, value:Bool):Void {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
buffer.src.muted = value;
buffer.__srcAudio.muted = value;
}
#end
@@ -576,9 +578,9 @@ class HTML5AudioContext {
public function setPlaybackRate (buffer:AudioBuffer, value:Float):Void {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
buffer.src.playbackRate = value;
buffer.__srcAudio.playbackRate = value;
}
#end
@@ -589,9 +591,9 @@ class HTML5AudioContext {
public function setPreload (buffer:AudioBuffer, value:String):Void {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
buffer.src.preload = value;
buffer.__srcAudio.preload = value;
}
#end
@@ -602,9 +604,9 @@ class HTML5AudioContext {
public function setSrc (buffer:AudioBuffer, value:String):Void {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
buffer.src.src = value;
buffer.__srcAudio.src = value;
}
#end
@@ -615,9 +617,9 @@ class HTML5AudioContext {
public function setVolume (buffer:AudioBuffer, value:Float):Void {
#if (js && html5)
if (buffer.src != null) {
if (buffer.__srcAudio != null) {
buffer.src.volume = value;
buffer.__srcAudio.volume = value;
}
#end

330
lime/audio/howlerjs/Howl.hx Normal file
View File

@@ -0,0 +1,330 @@
package lime.audio.howlerjs; #if (!js || !html5 || display)
import haxe.Constraints.Function;
class Howl {
public function new (options:HowlOptions) {
}
/**
* Get the duration of this sound. Passing a sound id will return the sprite duration.
* @param id The sound id to check. If none is passed, return full source duration.
* @return Audio duration in seconds.
*/
public function duration (?id:Int):Int {
return 0;
}
/**
* Fade a currently playing sound between two volumes (if no id is passsed, all sounds will fade).
* @param from The value to fade from (0.0 to 1.0).
* @param to The volume to fade to (0.0 to 1.0).
* @param len Time in milliseconds to fade.
* @param id The sound id (omit to fade all sounds).
* @return
*/
public function fade (from:Float, to:Float, len:Int, ?id:Int):Howl {
return this;
}
/**
* Load the audio file.
* @return
*/
public function load ():Howl {
return this;
}
/**
* Get/set the loop parameter on a sound. This method can optionally take 0, 1 or 2 arguments.
* loop() -> Returns the group's loop value.
* loop(id) -> Returns the sound id's loop value.
* loop(loop) -> Sets the loop value for all sounds in this Howl group.
* loop(loop, id) -> Sets the loop value of passed sound id.
* @return Returns self or current loop value.
*/
public function loop (?loop:Dynamic, ?id:Int):Dynamic {
return null;
}
/**
* Mute/unmute a single sound or all sounds in this Howl group.
* @param muted Set to true to mute and false to unmute.
* @param id The sound ID to update (omit to mute/unmute all).
* @return
*/
public function mute (muted:Bool, ?id:Int):Howl {
return this;
}
/**
* Remove a custom event. Call without parameters to remove all events.
* @param event Event name.
* @param fn Listener to remove. Leave empty to remove all.
* @param id (optional) Only remove events for this sound.
* @return
*/
public function off (event:String, fn:Function, ?id:Int):Howl {
return this;
}
/**
* Listen to a custom event.
* @param event Event name.
* @param fn Listener to call.
* @param id (optional) Only listen to events for this sound.
* @return
*/
public function on (event:String, fn:Function, ?id:Int):Howl {
return this;
}
/**
* Listen to a custom event and remove it once fired.
* @param event Event name.
* @param fn Listener to call.
* @param id (optional) Only listen to events for this sound.
* @return
*/
public function once (event:String, fn:Function, ?id:Int):Howl {
return this;
}
/**
* Pause playback and save current position.
* @param id The sound ID (empty to pause all in group).
* @return
*/
public function pause (?id:Int):Howl {
return this;
}
/**
* Play a sound or resume previous playback.
* @param sprite Sprite name for sprite playback or sound id to continue previous.
* @return Sound ID.
*/
public function play (?sprite:Dynamic):Int {
return 0;
}
/**
* Check if a specific sound is currently playing or not (if id is provided), or check if at least one of the sounds in the group is playing or not.
* @param id The sound id to check. If none is passed, the whole sound group is checked.
* @return True if playing and false if not.
*/
public function playing (?id:Int):Bool {
return false;
}
/**
* Get/set the playback rate of a sound. This method can optionally take 0, 1 or 2 arguments.
* rate() -> Returns the first sound node's current playback rate.
* rate(id) -> Returns the sound id's current playback rate.
* rate(rate) -> Sets the playback rate of all sounds in this Howl group.
* rate(rate, id) -> Sets the playback rate of passed sound id.
* @return Returns self or the current playback rate.
*/
public function rate (?rate:Float, ?id:Int):Dynamic {
return null;
}
/**
* Get/set the seek position of a sound (in seconds). This method can optionally take 0, 1 or 2 arguments.
* seek() -> Returns the first sound node's current seek position.
* seek(id) -> Returns the sound id's current seek position.
* seek(seek) -> Sets the seek position of the first sound node.
* seek(seek, id) -> Sets the seek position of passed sound id.
* @return Returns self or the current seek position.
*/
public function seek (?seek:Float, ?id:Int):Dynamic {
return null;
}
/**
* Returns the current loaded state of this Howl.
* @return 'unloaded', 'loading', 'loaded'
*/
public function state ():String {
return null;
}
/**
* Stop playback and reset to start.
* @param id The sound ID (empty to stop all in group).
* @return
*/
public function stop (?id:Int):Howl {
return this;
}
/**
* Unload and destroy the current Howl object.
* This will immediately stop all sound instances attached to this group.
*/
public function unload ():Void {
}
/**
* Get/set the volume of this sound or of the Howl group. This method can optionally take 0, 1 or 2 arguments.
* volume() -> Returns the group's volume value.
* volume(id) -> Returns the sound id's current volume.
* volume(vol) -> Sets the volume of all sounds in this Howl group.
* volume(vol, id) -> Sets the volume of passed sound id.
* @return Returns self or current volume.
*/
public function volume (?vol:Float, ?id:Int):Dynamic {
return null;
}
}
#else
import haxe.Constraints.Function;
import haxe.extern.EitherType;
@:native("Howl")
extern class Howl {
public function new (options:HowlOptions);
public function duration (?id:Int):Int;
public function fade (from:Float, to:Float, len:Int, ?id:Int):Howl;
public function load ():Howl;
@:overload(function(id:Int):Bool {})
@:overload(function(loop:Bool):Howl {})
@:overload(function(loop:Bool, id:Int):Howl {})
public function loop ():Bool;
public function mute (muted:Bool, ?id:Int):Howl;
public function off (event:String, fn:Function, ?id:Int):Howl;
public function on (event:String, fn:Function, ?id:Int):Howl;
public function once (event:String, fn:Function, ?id:Int):Howl;
public function pause (?id:Int):Howl;
@:overload(function(id:Int):Int {})
public function play (?sprite:String):Int;
public function playing (?id:Int):Bool;
@:overload(function(id:Int):Float {})
@:overload(function(rate:Float):Howl {})
@:overload(function(rate:Float, id:Int):Howl {})
public function rate ():Float;
public function state ():String;
@:overload(function(id:Int):Float {})
@:overload(function(seek:Float):Howl {})
@:overload(function(seek:Float, id:Int):Howl {})
public function seek ():Float;
public function stop (?id:Int):Howl;
public function unload ():Void;
@:overload(function(id:Int):Float {})
@:overload(function(vol:Float):Howl {})
@:overload(function(vol:Float, id:Int):Howl {})
public function volume ():Float;
}
#end
typedef HowlOptions = {
src:Array<String>,
?volume:Float,
?html5:Bool,
?loop:Bool,
?preload:Bool,
?autoplay:Bool,
?mute:Bool,
?sprite:Dynamic,
?rate:Float,
?pool:Float,
?format:Array<String>,
?onload:Function,
?onloaderror:Function,
?onplay:Function,
?onend:Function,
?onpause:Function,
?onstop:Function,
?onmute:Function,
?onvolume:Function,
?onrate:Function,
?onseek:Function,
?onfade:Function
}

View File

@@ -0,0 +1,95 @@
package lime.audio.howlerjs; #if (!js || !html5 || display)
class Howler {
public static var autoSuspend:Bool;
public static var ctx:WebAudioContext;
public static var masterGain:Dynamic;
public static var mobileAutoEnable:Bool;
public static var noAudio:Bool;
public static var usingWebAudio:Bool;
/**
* Check for codec support of specific extension.
* @param ext Audio file extention.
* @return
*/
public static function codecs (ext:String):Bool {
return false;
}
/**
* Handle muting and unmuting globally.
* @param muted Is muted or not.
*/
public static function mute (muted:Bool):Class<Howler> {
return Howler;
}
/**
* Unload and destroy all currently loaded Howl objects.
* @return
*/
public static function unload ():Class<Howler> {
return Howler;
}
/**
* Get/set the global volume for all sounds.
* @param vol Volume from 0.0 to 1.0.
* @return Returns self or current volume.
*/
public static function volume (?vol:Float):Dynamic {
if (vol != null) return Howler;
return vol;
}
}
#else
import haxe.extern.EitherType;
import js.html.audio.GainNode;
import lime.audio.WebAudioContext;
@:native("Howler")
extern class Howler {
public static var autoSuspend:Bool;
public static var ctx:WebAudioContext;
public static var masterGain:GainNode;
public static var mobileAutoEnable:Bool;
public static var noAudio:Bool;
public static var usingWebAudio:Bool;
public static function codecs (ext:String):Bool;
public static function mute (muted:Bool):Howler;
public static function unload ():Howler;
public static function volume (?vol:Float):EitherType<Int, Howler>;
}
#end