AudioBuffer feeds into AudioSource, make AudioSource handle context-specific functions to pause/play/etc

This commit is contained in:
Joshua Granick
2014-08-01 01:34:37 -07:00
parent 363a724a50
commit e50c2408a0
7 changed files with 233 additions and 161 deletions

View File

@@ -4,7 +4,7 @@ package lime;
import haxe.Unserializer; import haxe.Unserializer;
import lime.graphics.Font; import lime.graphics.Font;
import lime.media.AudioSource; import lime.media.AudioBuffer;
import lime.media.Image; import lime.media.Image;
import lime.utils.ByteArray; import lime.utils.ByteArray;
@@ -70,7 +70,7 @@ class Assets {
* @param id The ID or asset path for the sound * @param id The ID or asset path for the sound
* @return A new Sound object * @return A new Sound object
*/ */
public static function getAudio (id:String, useCache:Bool = true):AudioSource { public static function getAudioBuffer (id:String, useCache:Bool = true):AudioBuffer {
initialize (); initialize ();
@@ -98,7 +98,7 @@ class Assets {
if (library.isLocal (symbolName, cast AssetType.SOUND)) { if (library.isLocal (symbolName, cast AssetType.SOUND)) {
var audio = library.getAudio (symbolName); var audio = library.getAudioBuffer (symbolName);
if (useCache && cache.enabled) { if (useCache && cache.enabled) {
@@ -486,7 +486,7 @@ class Assets {
} }
private static function isValidAudio (audio:AudioSource):Bool { private static function isValidAudio (audio:AudioBuffer):Bool {
#if (tools && !display) #if (tools && !display)
#if (cpp || neko) #if (cpp || neko)
@@ -554,7 +554,7 @@ class Assets {
} }
public static function loadAudio (id:String, handler:AudioSource -> Void, useCache:Bool = true):Void { public static function loadAudioBuffer (id:String, handler:AudioBuffer -> Void, useCache:Bool = true):Void {
initialize (); initialize ();
@@ -583,7 +583,7 @@ class Assets {
if (useCache && cache.enabled) { if (useCache && cache.enabled) {
library.loadAudio (symbolName, function (audio:Dynamic):Void { library.loadAudioBuffer (symbolName, function (audio:Dynamic):Void {
cache.audio.set (id, audio); cache.audio.set (id, audio);
handler (audio); handler (audio);
@@ -592,7 +592,7 @@ class Assets {
} else { } else {
library.loadAudio (symbolName, handler); library.loadAudioBuffer (symbolName, handler);
} }
@@ -953,7 +953,7 @@ class AssetLibrary {
} }
public function getAudio (id:String):AudioSource { public function getAudioBuffer (id:String):AudioBuffer {
return null; return null;
@@ -1034,9 +1034,9 @@ class AssetLibrary {
} }
public function loadAudio (id:String, handler:AudioSource -> Void):Void { public function loadAudioBuffer (id:String, handler:AudioBuffer -> Void):Void {
handler (getAudio (id)); handler (getAudioBuffer (id));
} }
@@ -1097,7 +1097,7 @@ class AssetLibrary {
class AssetCache { class AssetCache {
public var audio:Map<String, AudioSource>; public var audio:Map<String, AudioBuffer>;
public var enabled:Bool = true; public var enabled:Bool = true;
public var image:Map<String, Image>; public var image:Map<String, Image>;
public var font:Map<String, Font>; public var font:Map<String, Font>;
@@ -1105,7 +1105,7 @@ class AssetCache {
public function new () { public function new () {
audio = new Map<String, AudioSource> (); audio = new Map<String, AudioBuffer> ();
font = new Map<String, Font> (); font = new Map<String, Font> ();
image = new Map<String, Image> (); image = new Map<String, Image> ();
@@ -1116,7 +1116,7 @@ class AssetCache {
if (prefix == null) { if (prefix == null) {
audio = new Map<String, AudioSource> (); audio = new Map<String, AudioBuffer> ();
font = new Map<String, Font> (); font = new Map<String, Font> ();
image = new Map<String, Image> (); image = new Map<String, Image> ();

View File

@@ -113,9 +113,10 @@ class Application extends Module {
#if (cpp || neko) #if (cpp || neko)
var result = lime_application_exec (__handle); var result = lime_application_exec (__handle);
AudioManager.destroy ();
return result;
AudioManager.shutdown ();
return result;
#elseif js #elseif js

View File

@@ -6,6 +6,12 @@ import lime.system.System;
import lime.utils.ByteArray; import lime.utils.ByteArray;
import lime.utils.Float32Array; import lime.utils.Float32Array;
#if js
import js.html.Audio;
#elseif flash
import flash.media.Sound;
#end
class AudioBuffer { class AudioBuffer {
@@ -16,6 +22,14 @@ class AudioBuffer {
public var id:UInt; public var id:UInt;
public var sampleRate:Int; public var sampleRate:Int;
#if js
public var src:Audio;
#elseif flash
public var src:Sound;
#else
public var src:Dynamic;
#end
public function new () { public function new () {
@@ -24,42 +38,6 @@ class AudioBuffer {
} }
public function createALBuffer ():Void {
var format = 0;
if (channels == 1) {
if (bitsPerSample == 8) {
format = AL.FORMAT_MONO8;
} else if (bitsPerSample == 16) {
format = AL.FORMAT_MONO16;
}
} else if (channels == 2) {
if (bitsPerSample == 8) {
format = AL.FORMAT_STEREO8;
} else if (bitsPerSample == 16) {
format = AL.FORMAT_STEREO16;
}
}
id = AL.genBuffer ();
AL.bufferData (id, format, data, data.length << 2, sampleRate);
}
public static function fromBytes (bytes:ByteArray):AudioBuffer { public static function fromBytes (bytes:ByteArray):AudioBuffer {
#if (cpp || neko) #if (cpp || neko)

View File

@@ -17,34 +17,6 @@ class AudioManager {
public static var context:AudioContext; public static var context:AudioContext;
public static function destroy ():Void {
if (context != null) {
switch (context) {
case OPENAL (alc, al):
var currentContext = alc.getCurrentContext ();
if (currentContext != null) {
var device = alc.getContextsDevice (currentContext);
alc.makeContextCurrent (null);
alc.destroyContext (currentContext);
alc.closeDevice (device);
}
default:
}
}
}
public static function init (context:AudioContext = null) { public static function init (context:AudioContext = null) {
if (context == null) { if (context == null) {
@@ -81,14 +53,68 @@ class AudioManager {
} }
public static function play (source:AudioSource):Void { public static function resume ():Void {
#if js if (context != null) {
#elseif flash
source.src.play (); switch (context) {
#else
AL.sourcePlay (source.id); case OPENAL (alc, al):
#end
alc.processContext (alc.getCurrentContext ());
default:
}
}
}
public static function shutdown ():Void {
if (context != null) {
switch (context) {
case OPENAL (alc, al):
var currentContext = alc.getCurrentContext ();
if (currentContext != null) {
var device = alc.getContextsDevice (currentContext);
alc.makeContextCurrent (null);
alc.destroyContext (currentContext);
alc.closeDevice (device);
}
default:
}
}
}
public static function suspend ():Void {
if (context != null) {
switch (context) {
case OPENAL (alc, al):
alc.suspendContext (alc.getCurrentContext ());
default:
}
}
} }

View File

@@ -3,41 +3,113 @@ package lime.media;
import lime.media.openal.AL; import lime.media.openal.AL;
#if js
import js.html.Audio;
#elseif flash
import flash.media.Sound;
#end
class AudioSource { class AudioSource {
public var buffer:AudioBuffer; public var buffer:AudioBuffer;
public var id:UInt;
#if js private var id:UInt;
public var src:Audio;
#elseif flash
public var src:Sound;
#else
public var src:Dynamic;
#end
public function new () { public function new (buffer:AudioBuffer = null) {
this.buffer = buffer;
id = 0; id = 0;
if (buffer != null) {
init ();
}
} }
public function createALSource (buffer:AudioBuffer):Void { private function init ():Void {
this.buffer = buffer; switch (AudioManager.context) {
case OPENAL (alc, al):
if (buffer.id == 0) {
buffer.id = al.genBuffer ();
var format = 0;
if (buffer.channels == 1) {
if (buffer.bitsPerSample == 8) {
format = al.FORMAT_MONO8;
} else if (buffer.bitsPerSample == 16) {
format = al.FORMAT_MONO16;
}
} else if (buffer.channels == 2) {
if (buffer.bitsPerSample == 8) {
format = al.FORMAT_STEREO8;
} else if (buffer.bitsPerSample == 16) {
format = al.FORMAT_STEREO16;
}
}
al.bufferData (buffer.id, format, buffer.data, buffer.data.length << 2, buffer.sampleRate);
}
id = al.genSource ();
al.sourcei (id, al.BUFFER, buffer.id);
default:
}
id = AL.genSource (); }
AL.sourcei (id, AL.BUFFER, buffer.id);
public function play ():Void {
#if js
#elseif flash
buffer.src.play ();
#else
AL.sourcePlay (id);
#end
}
public function pause ():Void {
#if js
#elseif flash
buffer.src.pause ();
#else
AL.sourcePause (id);
#end
}
public function stop ():Void {
#if js
#elseif flash
buffer.src.stop ();
#else
AL.sourceStop (id);
#end
} }

View File

@@ -16,12 +16,12 @@ class FlashAudioContext {
} }
public function createSource (stream:Dynamic /*URLRequest*/ = null, context:Dynamic /*SoundLoaderContext*/ = null):AudioSource { public function createBuffer (stream:Dynamic /*URLRequest*/ = null, context:Dynamic /*SoundLoaderContext*/ = null):AudioBuffer {
#if flash #if flash
var source = new AudioSource (); var buffer = new AudioBuffer ();
source.src = new Sound (stream, context); buffer.src = new Sound (stream, context);
return source; return buffer;
#else #else
return null; return null;
#end #end
@@ -29,12 +29,12 @@ class FlashAudioContext {
} }
public function getBytesLoaded (source:AudioSource):UInt { public function getBytesLoaded (buffer:AudioBuffer):UInt {
#if flash #if flash
if (source.src != null) { if (buffer.src != null) {
return source.src.bytesLoaded; return buffer.src.bytesLoaded;
} }
#end #end
@@ -44,12 +44,12 @@ class FlashAudioContext {
} }
public function getBytesTotal (source:AudioSource):Int { public function getBytesTotal (buffer:AudioBuffer):Int {
#if flash #if flash
if (source.src != null) { if (buffer.src != null) {
return source.src.bytesTotal; return buffer.src.bytesTotal;
} }
#end #end
@@ -59,12 +59,12 @@ class FlashAudioContext {
} }
public function getID3 (source:AudioSource):Dynamic /*ID3Info*/ { public function getID3 (buffer:AudioBuffer):Dynamic /*ID3Info*/ {
#if flash #if flash
if (source.src != null) { if (buffer.src != null) {
return source.src.id3; return buffer.src.id3;
} }
#end #end
@@ -74,12 +74,12 @@ class FlashAudioContext {
} }
public function getIsBuffering (source:AudioSource):Bool { public function getIsBuffering (buffer:AudioBuffer):Bool {
#if flash #if flash
if (source.src != null) { if (buffer.src != null) {
return source.src.isBuffering; return buffer.src.isBuffering;
} }
#end #end
@@ -89,12 +89,12 @@ class FlashAudioContext {
} }
public function getIsURLInaccessible (source:AudioSource):Bool { public function getIsURLInaccessible (buffer:AudioBuffer):Bool {
#if flash #if flash
if (source.src != null) { if (buffer.src != null) {
return source.src.isURLInaccessible; return buffer.src.isURLInaccessible;
} }
#end #end
@@ -104,12 +104,12 @@ class FlashAudioContext {
} }
public function getLength (source:AudioSource):Float { public function getLength (buffer:AudioBuffer):Float {
#if flash #if flash
if (source.src != null) { if (buffer.src != null) {
return source.src.length; return buffer.src.length;
} }
#end #end
@@ -119,12 +119,12 @@ class FlashAudioContext {
} }
public function getURL (source:AudioSource):String { public function getURL (buffer:AudioBuffer):String {
#if flash #if flash
if (source.src != null) { if (buffer.src != null) {
return source.src.url; return buffer.src.url;
} }
#end #end
@@ -134,12 +134,12 @@ class FlashAudioContext {
} }
public function close (source:AudioSource):Void { public function close (buffer:AudioBuffer):Void {
#if flash #if flash
if (source.src != null) { if (buffer.src != null) {
source.src.close (); buffer.src.close ();
} }
#end #end
@@ -147,12 +147,12 @@ class FlashAudioContext {
} }
public function extract (source:AudioSource, target:Dynamic /*flash.utils.ByteArray*/, length:Float, startPosition:Float = -1):Float { public function extract (buffer:AudioBuffer, target:Dynamic /*flash.utils.ByteArray*/, length:Float, startPosition:Float = -1):Float {
#if flash #if flash
if (source.src != null) { if (buffer.src != null) {
return source.src.extract (target, length, startPosition); return buffer.src.extract (target, length, startPosition);
} }
#end #end
@@ -162,12 +162,12 @@ class FlashAudioContext {
} }
public function load (source:AudioSource, stream:Dynamic /*flash.net.URLRequest*/, context:Dynamic /*SoundLoaderContext*/ = null):Void { public function load (buffer:AudioBuffer, stream:Dynamic /*flash.net.URLRequest*/, context:Dynamic /*SoundLoaderContext*/ = null):Void {
#if flash #if flash
if (source.src != null) { if (buffer.src != null) {
source.src.load (stream, context); buffer.src.load (stream, context);
} }
#end #end
@@ -175,12 +175,12 @@ class FlashAudioContext {
} }
public function loadCompressedDataFromByteArray (source:AudioSource, bytes:Dynamic /*flash.utils.ByteArray*/, bytesLength:UInt):Void { public function loadCompressedDataFromByteArray (buffer:AudioBuffer, bytes:Dynamic /*flash.utils.ByteArray*/, bytesLength:UInt):Void {
#if flash #if flash
if (source.src != null) { if (buffer.src != null) {
source.src.loadCompressedDataFromByteArray (bytes, bytesLength); buffer.src.loadCompressedDataFromByteArray (bytes, bytesLength);
} }
#end #end
@@ -188,12 +188,12 @@ class FlashAudioContext {
} }
public function loadPCMFromByteArray (source:AudioSource, bytes:Dynamic /*flash.utils.ByteArray*/, samples:UInt, format:String = null, stereo:Bool = true, sampleRate:Float = 44100):Void { public function loadPCMFromByteArray (buffer:AudioBuffer, bytes:Dynamic /*flash.utils.ByteArray*/, samples:UInt, format:String = null, stereo:Bool = true, sampleRate:Float = 44100):Void {
#if flash #if flash
if (source.src != null) { if (buffer.src != null) {
source.src.loadPCMFromByteArray (bytes, samples, format, stereo, sampleRate); buffer.src.loadPCMFromByteArray (bytes, samples, format, stereo, sampleRate);
} }
#end #end
@@ -201,12 +201,12 @@ class FlashAudioContext {
} }
public function play (source:AudioSource, startTime:Float = 0, loops:Int = 0, sndTransform:Dynamic /*SoundTransform*/ = null):Dynamic /*SoundChannel*/ { public function play (buffer:AudioBuffer, startTime:Float = 0, loops:Int = 0, sndTransform:Dynamic /*SoundTransform*/ = null):Dynamic /*SoundChannel*/ {
#if flash #if flash
if (source.src != null) { if (buffer.src != null) {
return source.src.play (startTime, loops, sndTransform); return buffer.src.play (startTime, loops, sndTransform);
} }
#end #end

View File

@@ -5,7 +5,6 @@ import haxe.Timer;
import haxe.Unserializer; import haxe.Unserializer;
import lime.app.Preloader; import lime.app.Preloader;
import lime.media.AudioBuffer; import lime.media.AudioBuffer;
import lime.media.AudioSource;
import lime.media.Image; import lime.media.Image;
import lime.media.openal.AL; import lime.media.openal.AL;
import lime.utils.ByteArray; import lime.utils.ByteArray;
@@ -153,13 +152,13 @@ class DefaultAssetLibrary extends AssetLibrary {
} }
public override function getAudio (id:String):AudioSource { public override function getAudioBuffer (id:String):AudioBuffer {
#if flash #if flash
var audio = new AudioSource (); var buffer = new AudioBuffer ();
audio.src = cast (Type.createInstance (className.get (id), []), Sound); buffer.src = cast (Type.createInstance (className.get (id), []), Sound);
return audio; return buffer;
#elseif js #elseif js
@@ -168,11 +167,7 @@ class DefaultAssetLibrary extends AssetLibrary {
#else #else
var buffer = AudioBuffer.fromFile (path.get (id)); return AudioBuffer.fromFile (path.get (id));
buffer.createALBuffer ();
var audio = new AudioSource ();
audio.createALSource (buffer);
return audio;
//if (className.exists(id)) return cast (Type.createInstance (className.get (id), []), Sound); //if (className.exists(id)) return cast (Type.createInstance (className.get (id), []), Sound);
//else return new Sound (new URLRequest (path.get (id)), null, type.get (id) == MUSIC); //else return new Sound (new URLRequest (path.get (id)), null, type.get (id) == MUSIC);
@@ -384,7 +379,7 @@ class DefaultAssetLibrary extends AssetLibrary {
} }
public override function loadAudio (id:String, handler:AudioSource -> Void):Void { public override function loadAudioBuffer (id:String, handler:AudioBuffer -> Void):Void {
#if (flash || js) #if (flash || js)
@@ -400,13 +395,13 @@ class DefaultAssetLibrary extends AssetLibrary {
//} else { //} else {
handler (getAudio (id)); handler (getAudioBuffer (id));
//} //}
#else #else
handler (getAudio (id)); handler (getAudioBuffer (id));
#end #end