|
@@ -13,6 +13,82 @@ private class ChannelMapper extends sdl.SoundChannel {
|
|
@:privateAccess native.onSample(haxe.io.Float32Array.fromBytes(haxe.io.Bytes.ofData(data)));
|
|
@:privateAccess native.onSample(haxe.io.Float32Array.fromBytes(haxe.io.Bytes.ofData(data)));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+#elseif lime_openal
|
|
|
|
+import lime.audio.openal.AL;
|
|
|
|
+
|
|
|
|
+private class ALChannel {
|
|
|
|
+ var native : NativeChannel;
|
|
|
|
+ var samples : Int;
|
|
|
|
+
|
|
|
|
+ var buffers : Array<Int>;
|
|
|
|
+ var src : Int;
|
|
|
|
+
|
|
|
|
+ var fbuf : haxe.io.Bytes;
|
|
|
|
+ var ibuf : haxe.io.Bytes;
|
|
|
|
+ var iview : lime.utils.ArrayBufferView;
|
|
|
|
+
|
|
|
|
+ public function new(samples, native){
|
|
|
|
+ this.native = native;
|
|
|
|
+ this.samples = samples;
|
|
|
|
+ buffers = AL.genBuffers(2);
|
|
|
|
+ src = AL.genSource();
|
|
|
|
+ AL.sourcef(src,AL.PITCH,1.0);
|
|
|
|
+ AL.sourcef(src,AL.GAIN,1.0);
|
|
|
|
+ fbuf = haxe.io.Bytes.alloc( samples<<3 );
|
|
|
|
+ ibuf = haxe.io.Bytes.alloc( samples<<2 );
|
|
|
|
+ iview = new lime.utils.Int16Array(ibuf);
|
|
|
|
+
|
|
|
|
+ for ( b in buffers )
|
|
|
|
+ onSample(b);
|
|
|
|
+ forcePlay();
|
|
|
|
+ lime.app.Application.current.onUpdate.add( onUpdate );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public function stop() {
|
|
|
|
+ if( src != 0 ){
|
|
|
|
+ lime.app.Application.current.onUpdate.remove( onUpdate );
|
|
|
|
+ AL.deleteSource(src);
|
|
|
|
+ AL.deleteBuffers(buffers);
|
|
|
|
+ src = 0;
|
|
|
|
+ buffers = null;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @:noDebug function onSample( buf : Int ) {
|
|
|
|
+ @:privateAccess native.onSample(haxe.io.Float32Array.fromBytes(fbuf));
|
|
|
|
+
|
|
|
|
+ // Convert Float32 to Int16
|
|
|
|
+ #if cpp
|
|
|
|
+ var fb = fbuf.getData();
|
|
|
|
+ var ib = ibuf.getData();
|
|
|
|
+ for( i in 0...samples<<1 )
|
|
|
|
+ untyped __global__.__hxcpp_memory_set_i16( ib, i<<1, __global__.__int__(__global__.__hxcpp_memory_get_float( fb, i<<2 ) * 0x7FFF) );
|
|
|
|
+ #else
|
|
|
|
+ for ( i in 0...samples << 1 ) {
|
|
|
|
+ var v = Std.int(fbuf.getFloat(i << 2) * 0x7FFF);
|
|
|
|
+ ibuf.set( i<<1, v );
|
|
|
|
+ ibuf.set( (i<<1) + 1, v>>>8 );
|
|
|
|
+ }
|
|
|
|
+ #end
|
|
|
|
+
|
|
|
|
+ AL.bufferData(buf, AL.FORMAT_STEREO16, iview, ibuf.length, 44100);
|
|
|
|
+ AL.sourceQueueBuffers(src, 1, [buf]);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ inline function forcePlay() {
|
|
|
|
+ if( AL.getSourcei(src,AL.SOURCE_STATE) != AL.PLAYING )
|
|
|
|
+ AL.sourcePlay(src);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ function onUpdate( i : Int ){
|
|
|
|
+ var r = AL.getSourcei(src,AL.BUFFERS_PROCESSED);
|
|
|
|
+ if( r > 0 ){
|
|
|
|
+ for( b in AL.sourceUnqueueBuffers(src,r) )
|
|
|
|
+ onSample(b);
|
|
|
|
+ forcePlay();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
#end
|
|
#end
|
|
|
|
|
|
class NativeChannel {
|
|
class NativeChannel {
|
|
@@ -36,6 +112,8 @@ class NativeChannel {
|
|
var tmpBuffer : haxe.io.Float32Array;
|
|
var tmpBuffer : haxe.io.Float32Array;
|
|
#elseif hxsdl
|
|
#elseif hxsdl
|
|
var channel : ChannelMapper;
|
|
var channel : ChannelMapper;
|
|
|
|
+ #elseif lime_openal
|
|
|
|
+ var channel : ALChannel;
|
|
#end
|
|
#end
|
|
public var bufferSamples(default, null) : Int;
|
|
public var bufferSamples(default, null) : Int;
|
|
|
|
|
|
@@ -53,6 +131,8 @@ class NativeChannel {
|
|
sproc.onaudioprocess = onJsSample;
|
|
sproc.onaudioprocess = onJsSample;
|
|
#elseif hxsdl
|
|
#elseif hxsdl
|
|
channel = new ChannelMapper(bufferSamples, this);
|
|
channel = new ChannelMapper(bufferSamples, this);
|
|
|
|
+ #elseif lime_openal
|
|
|
|
+ channel = new ALChannel(bufferSamples, this);
|
|
#end
|
|
#end
|
|
}
|
|
}
|
|
|
|
|
|
@@ -99,7 +179,12 @@ class NativeChannel {
|
|
channel.stop();
|
|
channel.stop();
|
|
channel = null;
|
|
channel = null;
|
|
}
|
|
}
|
|
|
|
+ #elseif lime_openal
|
|
|
|
+ if( channel != null ) {
|
|
|
|
+ channel.stop();
|
|
|
|
+ channel = null;
|
|
|
|
+ }
|
|
#end
|
|
#end
|
|
}
|
|
}
|
|
|
|
|
|
-}
|
|
|
|
|
|
+}
|