Browse Source

started new audio api : added NativeChannel (hxsl requires cpp patch)

Nicolas Cannasse 10 years ago
parent
commit
7425289102
5 changed files with 209 additions and 0 deletions
  1. 97 0
      hxd/snd/NativeChannel.hx
  2. 30 0
      samples/sound/Sound.hx
  3. 16 0
      samples/sound/index.html
  4. 13 0
      samples/sound/sound.hxml
  5. 53 0
      samples/sound/sound.hxproj

+ 97 - 0
hxd/snd/NativeChannel.hx

@@ -0,0 +1,97 @@
+package hxd.snd;
+
+#if hxsdl
+private class ChannelMapper extends sdl.SoundChannel {
+	var native : NativeChannel;
+	public function new(samples, native) {
+		super(samples);
+		this.native = native;
+	}
+	override function onSample( buf : cpp.Pointer<cpp.UInt8>, len : Int ) {
+		var data : haxe.io.BytesData = null;
+		untyped __cpp__('
+			Array_obj<unsigned char> *o = new Array_obj<unsigned char>((char * ) buf.ptr, len);
+			data = Array<unsigned char>(o);
+		');
+		@:privateAccess native.onSample(haxe.io.Float32Array.fromBytes(haxe.io.Bytes.ofData(data)));
+	}
+}
+#end
+
+class NativeChannel {
+
+	#if flash
+	var snd : flash.media.Sound;
+	var channel : flash.media.SoundChannel;
+	#elseif js
+	static var ctx : js.html.audio.AudioContext;
+	var sproc : js.html.audio.ScriptProcessorNode;
+	var tmpBuffer : haxe.io.Float32Array;
+	#elseif hxsdl
+	var channel : ChannelMapper;
+	#end
+	public var bufferSamples(default, null) : Int;
+
+	public function new( bufferSamples : Int ) {
+		this.bufferSamples = bufferSamples;
+		#if flash
+		snd = new flash.media.Sound();
+		snd.addEventListener(flash.events.SampleDataEvent.SAMPLE_DATA, onFlashSample);
+		channel = snd.play(0, 0x7FFFFFFF);
+		#elseif js
+		if( ctx == null )
+			ctx = new js.html.audio.AudioContext();
+		sproc = ctx.createScriptProcessor(bufferSamples, 2, 2);
+		tmpBuffer = new haxe.io.Float32Array(bufferSamples * 2);
+		sproc.connect(ctx.destination);
+		sproc.onaudioprocess = onJsSample;
+		#elseif hxsdl
+		channel = new ChannelMapper(bufferSamples, this);
+		#end
+	}
+
+	#if flash
+	function onFlashSample( event : flash.events.SampleDataEvent ) {
+		var buf = event.data;
+		buf.length = bufferSamples * 2 * 4;
+		onSample(haxe.io.Float32Array.fromBytes(haxe.io.Bytes.ofData(buf)));
+	}
+	#end
+
+	#if js
+	function onJsSample( event : js.html.audio.AudioProcessingEvent ) {
+		onSample(tmpBuffer);
+		// split the channels and copy to output
+		var r = 0;
+		var left = event.outputBuffer.getChannelData(0);
+		var right = event.outputBuffer.getChannelData(1);
+		for( i in 0...bufferSamples ) {
+			left[i] = tmpBuffer[r++];
+			right[i] = tmpBuffer[r++];
+		}
+	}
+	#end
+
+	function onSample( out : haxe.io.Float32Array ) {
+	}
+
+	public function stop() {
+		#if flash
+		if( channel != null ) {
+			channel.stop();
+			channel = null;
+		}
+		#elseif js
+		if( sproc != null ) {
+			sproc.disconnect();
+			sproc = null;
+		}
+		#elseif hxsdl
+		if( channel != null ) {
+			channel.stop();
+			channel = null;
+		}
+		#end
+	}
+
+}

+ 30 - 0
samples/sound/Sound.hx

@@ -0,0 +1,30 @@
+import hxd.snd.NativeChannel;
+
+class NoiseChannel extends hxd.snd.NativeChannel {
+
+	public function new() {
+		super(4096);
+	}
+
+	override function onSample( buf : haxe.io.Float32Array ) {
+		for( i in 0...buf.length )
+			buf[i] = Math.random() * 2 - 1;
+	}
+
+}
+
+
+class Sound extends hxd.App {
+
+	var chan : hxd.snd.SoundChannel;
+
+	override function init() {
+		var c = new NoiseChannel();
+		haxe.Timer.delay(c.stop, 1000);
+	}
+
+	static function main() {
+		new Sound();
+	}
+
+}

+ 16 - 0
samples/sound/index.html

@@ -0,0 +1,16 @@
+<html>
+<body style="margin:0;padding:0;background-color:red">
+	<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
+	
+	<br/>
+	
+	
+	<div id="log"></div>
+	
+	<center>
+		<canvas id="webgl" style="width:80%;height:60%"></canvas>
+	</center>
+	<script type="text/javascript" src="main.js"></script>
+	
+</body>
+</html>

+ 13 - 0
samples/sound/sound.hxml

@@ -0,0 +1,13 @@
+-js main.js
+-main Sound
+-lib heaps
+--next
+-swf main.swf
+-swf-version 11.8
+-main Sound
+-lib heaps
+--next
+-cpp bin
+-main Sound
+-lib heaps
+-lib hxsdl

+ 53 - 0
samples/sound/sound.hxproj

@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<project version="2">
+  <!-- Output SWF options -->
+  <output>
+    <movie outputType="Application" />
+    <movie input="" />
+    <movie path="main.js" />
+    <movie fps="60" />
+    <movie width="800" />
+    <movie height="600" />
+    <movie version="1" />
+    <movie minorVersion="0" />
+    <movie platform="JavaScript" />
+    <movie background="#FFFFFF" />
+  </output>
+  <!-- Other classes to be compiled into your SWF -->
+  <classpaths>
+    <!-- example: <class path="..." /> -->
+  </classpaths>
+  <!-- Build options -->
+  <build>
+    <option directives="" />
+    <option flashStrict="False" />
+    <option noInlineOnDebug="False" />
+    <option mainClass="Sound" />
+    <option enabledebug="False" />
+    <option additional="-lib heaps&#xA;&#xA;--next&#xA;-swf main.swf&#xA;-swf-version 11.8&#xA;-main Sound&#xA;-lib heaps&#xA;&#xA;--next&#xA;-cpp bin&#xA;-main Sound&#xA;-lib heaps&#xA;-lib hxsdl" />
+  </build>
+  <!-- haxelib libraries -->
+  <haxelib>
+    <!-- example: <library name="..." /> -->
+  </haxelib>
+  <!-- Class files to compile (other referenced classes will automatically be included) -->
+  <compileTargets>
+    <!-- example: <compile path="..." /> -->
+  </compileTargets>
+  <!-- Paths to exclude from the Project Explorer tree -->
+  <hiddenPaths>
+    <hidden path="obj" />
+  </hiddenPaths>
+  <!-- Executed before build -->
+  <preBuildCommand />
+  <!-- Executed after build -->
+  <postBuildCommand alwaysRun="False" />
+  <!-- Other project options -->
+  <options>
+    <option showHiddenPaths="False" />
+    <option testMovie="OpenDocument" />
+    <option testMovieCommand="main.swf" />
+  </options>
+  <!-- Plugin storage -->
+  <storage />
+</project>