2
0
Эх сурвалжийг харах

OpenAL EFX support (reverb & filters) (#271)

Mathieu Capdegelle 8 жил өмнө
parent
commit
cac1c7d7ce

+ 31 - 27
hxd/snd/ALEmulator.hx

@@ -232,6 +232,8 @@ class ALEmulator {
 	}
 
 	// Extension support
+	public static function loadExtensions() {}
+
 	public static function isExtensionPresent(extname : Bytes) : Bool {
 		return false;
 	}
@@ -740,6 +742,8 @@ class ALCEmulator {
 	}
 
 	// Extension support
+	public static function loadExtensions(alDevice : Device) { }
+
 	public static function isExtensionPresent(device : Device, extname : Bytes) : Bool {
 		return false;
 	}
@@ -767,46 +771,46 @@ class ALCEmulator {
 	// Constants
 	// ------------------------------------------------------------------------
 
-	public static inline var ALC_FALSE                            = 0;
-	public static inline var ALC_TRUE                             = 1;
+	public static inline var FALSE                            = 0;
+	public static inline var TRUE                             = 1;
 
 	// Context attributes
-	public static inline var ALC_FREQUENCY                        = 0x1007;
-	public static inline var ALC_REFRESH                          = 0x1008;
-	public static inline var ALC_SYNC                             = 0x1009;
-	public static inline var ALC_MONO_SOURCES                     = 0x1010;
-	public static inline var ALC_STEREO_SOURCES                   = 0x1011;
+	public static inline var FREQUENCY                        = 0x1007;
+	public static inline var REFRESH                          = 0x1008;
+	public static inline var SYNC                             = 0x1009;
+	public static inline var MONO_SOURCES                     = 0x1010;
+	public static inline var STEREO_SOURCES                   = 0x1011;
 
 	// Errors
-	public static inline var ALC_NO_ERROR                         = 0;
-	public static inline var ALC_INVALID_DEVICE                   = 0xA001;
-	public static inline var ALC_INVALID_CONTEXT                  = 0xA002;
-	public static inline var ALC_INVALID_ENUM                     = 0xA003;
-	public static inline var ALC_INVALID_VALUE                    = 0xA004;
-	public static inline var ALC_OUT_OF_MEMORY                    = 0xA005;
+	public static inline var NO_ERROR                         = 0;
+	public static inline var INVALID_DEVICE                   = 0xA001;
+	public static inline var INVALID_CONTEXT                  = 0xA002;
+	public static inline var INVALID_ENUM                     = 0xA003;
+	public static inline var INVALID_VALUE                    = 0xA004;
+	public static inline var OUT_OF_MEMORY                    = 0xA005;
 
 	// Runtime ALC version
-	public static inline var ALC_MAJOR_VERSION                    = 0x1000;
-	public static inline var ALC_MINOR_VERSION                    = 0x1001;
+	public static inline var MAJOR_VERSION                    = 0x1000;
+	public static inline var MINOR_VERSION                    = 0x1001;
 
 	// Context attribute list properties
-	public static inline var ALC_ATTRIBUTES_SIZE                  = 0x1002;
-	public static inline var ALC_ALL_ATTRIBUTES                   = 0x1003;
+	public static inline var ATTRIBUTES_SIZE                  = 0x1002;
+	public static inline var ALL_ATTRIBUTES                   = 0x1003;
 
 	// Device strings
-	public static inline var ALC_DEFAULT_DEVICE_SPECIFIER         = 0x1004;
-	public static inline var ALC_DEVICE_SPECIFIER                 = 0x1005;
-	public static inline var ALC_EXTENSIONS                       = 0x1006;
+	public static inline var DEFAULT_DEVICE_SPECIFIER         = 0x1004;
+	public static inline var DEVICE_SPECIFIER                 = 0x1005;
+	public static inline var EXTENSIONS                       = 0x1006;
 
 	// Capture extension
-	public static inline var ALC_EXT_CAPTURE                      = 1;
-	public static inline var ALC_CAPTURE_DEVICE_SPECIFIER         = 0x310;
-	public static inline var ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER = 0x311;
-	public static inline var ALC_CAPTURE_SAMPLES                  = 0x312;
+	public static inline var EXT_CAPTURE                      = 1;
+	public static inline var CAPTURE_DEVICE_SPECIFIER         = 0x310;
+	public static inline var CAPTURE_DEFAULT_DEVICE_SPECIFIER = 0x311;
+	public static inline var CAPTURE_SAMPLES                  = 0x312;
 
 	// Enumerate All extension
-	public static inline var ALC_ENUMERATE_ALL_EXT                = 1;
-	public static inline var ALC_DEFAULT_ALL_DEVICES_SPECIFIER    = 0x1012;
-	public static inline var ALC_ALL_DEVICES_SPECIFIER            = 0x1013;
+	public static inline var ENUMERATE_ALL_EXT                = 1;
+	public static inline var DEFAULT_ALL_DEVICES_SPECIFIER    = 0x1012;
+	public static inline var ALL_DEVICES_SPECIFIER            = 0x1013;
 
 }

+ 5 - 2
hxd/snd/Channel.hx

@@ -1,5 +1,6 @@
 package hxd.snd;
 
+@:allow(hxd.snd.Driver)
 class Channel extends ChannelBase {
 	static var ID = 0;
 
@@ -74,13 +75,15 @@ class Channel extends ChannelBase {
 		super.updateCurrentVolume(now);
 		channelGroup.updateCurrentVolume(now);
 		currentVolume *= channelGroup.currentVolume * soundGroup.volume;
-		for( e in effects ) currentVolume *= e.getVolumeModifier();
+		for (e in channelGroup.effects) currentVolume *= e.getVolumeModifier();
+		for (e in effects) currentVolume *= e.getVolumeModifier();
 	}
 
 	public function calcAudibleGain( now : Float ) {
 		updateCurrentVolume(now);
 		audibleGain = currentVolume;
-		for (e in effects) audibleGain *= e.gain;
+		for (e in channelGroup.effects) audibleGain = e.applyAudibleGainModifier(audibleGain);
+		for (e in effects) audibleGain = e.applyAudibleGainModifier(audibleGain);
 	}
 
 	/**

+ 12 - 2
hxd/snd/ChannelBase.hx

@@ -1,10 +1,13 @@
 package hxd.snd;
 
+@:allow(hxd.snd.Driver)
 class ChannelBase {
 
 	public var priority : Float = 0.;
 	public var mute     : Bool = false;
 	public var effects  : Array<Effect> = [];
+	public var removedEffects : Array<Effect> = [];
+
 	public var volume(default, set) : Float = 1.;
 	var currentFade : { start : Float, duration : Float, startVolume : Float, targetVolume : Float, onEnd : Void -> Void };
 	var currentVolume : Float; // global volume
@@ -45,13 +48,20 @@ class ChannelBase {
 	}
 
 	public function addEffect<T:Effect>( e : T ) : T {
-		if( e == null ) throw "Can't add null effect";
+		if (e == null) throw "Can't add null effect";
+		if (effects.indexOf(e) >= 0) throw "effect already added on this channel";
+
 		effects.push(e);
+		e.incRefs();
 		return e;
 	}
 
 	public function removeEffect( e : Effect ) {
-		effects.remove(e);
+		var found = effects.remove(e);
+		if (!found) return;
+
+		removedEffects.push(e);
+		e.decRefs();
 	}
 
 }

+ 73 - 36
hxd/snd/Driver.hx

@@ -2,17 +2,17 @@ package hxd.snd;
 
 #if hlopenal
 typedef AL = openal.AL;
-private typedef ALC = openal.ALC;
-private typedef ALSource = openal.AL.Source;
-private typedef ALBuffer = openal.AL.Buffer;
-private typedef ALDevice = openal.ALC.Device;
-private typedef ALContext = openal.ALC.Context;
+private typedef ALC          = openal.ALC;
+private typedef ALSource     = openal.AL.Source;
+private typedef ALBuffer     = openal.AL.Buffer;
+private typedef ALDevice     = openal.ALC.Device;
+private typedef ALContext    = openal.ALC.Context;
 #else
 typedef AL = hxd.snd.ALEmulator;
-private typedef ALC = hxd.snd.ALEmulator.ALCEmulator;
-private typedef ALSource = hxd.snd.ALEmulator.ALSource;
-private typedef ALBuffer = hxd.snd.ALEmulator.ALBuffer;
-private typedef ALDevice = hxd.snd.ALEmulator.ALDevice;
+private typedef ALC       = hxd.snd.ALEmulator.ALCEmulator;
+private typedef ALSource  = hxd.snd.ALEmulator.ALSource;
+private typedef ALBuffer  = hxd.snd.ALEmulator.ALBuffer;
+private typedef ALDevice  = hxd.snd.ALEmulator.ALDevice;
 private typedef ALContext = hxd.snd.ALEmulator.ALContext;
 #end
 
@@ -59,8 +59,6 @@ class Buffer {
 	}
 }
 
-@:access(hxd.snd.Channel)
-@:access(hxd.snd.Effect)
 class Driver {
 
 	/**
@@ -89,16 +87,18 @@ class Driver {
 
 	static inline var AL_NUM_SOURCES = 16;
 
-	var cachedBytes : haxe.io.Bytes;
+	var cachedBytes   : haxe.io.Bytes;
 	var resampleBytes : haxe.io.Bytes;
 
 	var alDevice      : ALDevice;
 	var alContext     : ALContext;
-
 	var buffers       : Array<Buffer>;
 	var sources       : Array<Source>;
 	var bufferMap     : Map<hxd.res.Sound, Buffer>;
 
+	var preUpdateCallbacks  : Array<Void->Void>;
+	var postUpdateCallbacks : Array<Void->Void>;
+
 	// ------------------------------------------------------------------------
 
 	private function new() {
@@ -110,20 +110,39 @@ class Driver {
 		buffers = [];
 		bufferMap = new Map();
 
+		preUpdateCallbacks  = [];
+		postUpdateCallbacks = [];
+
 		// al init
 		alDevice  = ALC.openDevice(null);
 		alContext = ALC.createContext(alDevice, null);
 		ALC.makeContextCurrent(alContext);
-
-		// alloc sources
-		var bytes = haxe.io.Bytes.alloc(4 * AL_NUM_SOURCES);
-		AL.genSources(AL_NUM_SOURCES, bytes);
-		sources = [for (i in 0...AL_NUM_SOURCES) new Source(ALSource.ofInt(bytes.getInt32(i * 4)))];
-		for (s in sources) AL.sourcei(s.inst, AL.SOURCE_RELATIVE, AL.TRUE);
+		ALC.loadExtensions(alDevice);
+		AL.loadExtensions();
+
+		{	// alloc sources
+			sources = [];
+			var bytes = haxe.io.Bytes.alloc(4);
+			for (i in 0...AL_NUM_SOURCES) {
+				AL.genSources(1, bytes);
+				if (AL.getError() != AL.NO_ERROR) break;
+				var s = new Source(ALSource.ofInt(bytes.getInt32(0)));
+				AL.sourcei(s.inst, AL.SOURCE_RELATIVE, AL.TRUE);
+				sources.push(s);
+			}
+		}
 
 		cachedBytes = haxe.io.Bytes.alloc(4 * 3 * 2);
 	}
 
+	public function addPreUpdateCallback(f : Void->Void) {
+		preUpdateCallbacks.push(f);
+	}
+
+	public function addPostUpdateCallback(f : Void->Void) {
+		postUpdateCallbacks.push(f);
+	}
+
 	function getTmp(size) {
 		if( cachedBytes.length < size )
 			cachedBytes = haxe.io.Bytes.alloc(size);
@@ -131,7 +150,11 @@ class Driver {
 	}
 
 	static function soundUpdate() {
-		if( instance != null ) instance.update();
+		if( instance != null ) {
+			for (f in instance.preUpdateCallbacks) f();
+			instance.update();
+			for (f in instance.postUpdateCallbacks) f();
+		}
 	}
 
 	public static function get() {
@@ -169,9 +192,9 @@ class Driver {
 
 		AL.deleteSources(sources.length, arrayBytes([for( s in sources ) s.inst.toInt()]));
 		AL.deleteBuffers(buffers.length, arrayBytes([for( b in buffers ) b.inst.toInt()]));
-		sources = [];
-		buffers = [];
-
+		sources     = [];
+		buffers     = [];
+		
 		ALC.makeContextCurrent(null);
 		ALC.destroyContext(alContext);
 		ALC.closeDevice(alDevice);
@@ -195,13 +218,17 @@ class Driver {
 	public function update() {
 		// update playing channels from sources & release stopped channels
 		var now = haxe.Timer.stamp();
-
 		for( s in sources ) {
 			var c = s.channel;
 			if( c == null ) continue;
 			var state = AL.getSourcei(s.inst, AL.SOURCE_STATE);
 			switch (state) {
 			case AL.STOPPED:
+				if (c.streaming && s.streamPosition != s.streamPositionNext) {
+					// force full resync
+					releaseSource(s);
+					continue;
+				}
 				releaseChannel(c);
 				c.onEnd();
 			case AL.PLAYING:
@@ -296,7 +323,6 @@ class Driver {
 			}
 		}
 
-
 		// free sources that points to virtualized channels
 		for ( s in sources ) {
 			if ( s.channel == null || !s.channel.isVirtual) continue;
@@ -351,11 +377,11 @@ class Driver {
 			if( c == null) continue;
 			syncSource(s);
 		}
-
-		// update virtual channels
+		
 		var c = channels;
 		while (c != null) {
 			var next = c.next;
+			// update virtual channels
 			if (!c.pause && c.isVirtual) {
 				c.position += now - c.lastStamp;
 				c.lastStamp = now;
@@ -364,6 +390,10 @@ class Driver {
 					c.onEnd();
 				}
 			}
+
+			// clean removed effects
+			if (c.channelGroup.removedEffects.length > 0) c.channelGroup.removedEffects = [];
+			if (c.removedEffects != null && c.removedEffects.length > 0) c.removedEffects = [];
 			c = next;
 		}
 	}
@@ -388,8 +418,12 @@ class Driver {
 			s.volume = v;
 			AL.sourcef(s.inst, AL.GAIN, v);
 		}
-		for(e in c.effects)
-			e.apply(c, s);
+
+		for (e in c.channelGroup.removedEffects) e.unapply(s);
+		for (e in c.removedEffects) e.unapply(s);
+
+		for (e in c.channelGroup.effects) e.apply(s);
+		for (e in c.effects) e.apply(s);
 
 		if( !s.playing ) {
 			s.playing = true;
@@ -414,6 +448,11 @@ class Driver {
 
 	function releaseSource( s : Source ) {
 		if (s.channel != null) {
+			for (e in s.channel.channelGroup.removedEffects) e.unapply(s);
+			for (e in s.channel.removedEffects) e.unapply(s);
+			for (e in s.channel.channelGroup.effects) e.unapply(s);
+			for (e in s.channel.effects) e.unapply(s);
+
 			s.channel.source = null;
 			s.channel = null;
 		}
@@ -421,10 +460,6 @@ class Driver {
 			s.playing = false;
 			AL.sourceStop(s.inst);
 		}
-		AL.sourcei(s.inst,  AL.SOURCE_RELATIVE, AL.TRUE);
-		AL.source3f(s.inst, AL.POSITION,  0, 0, 0);
-		AL.source3f(s.inst, AL.VELOCITY,  0, 0, 0);
-		AL.source3f(s.inst, AL.DIRECTION, 0, 0, 0);
 		syncBuffers(s, null);
 	}
 
@@ -640,10 +675,13 @@ class Driver {
 				prev = prev.next;
 			prev.next = c.next;
 		}
+		
+		for (e in c.effects) c.removeEffect(e);
+		if  (c.source != null) releaseSource(c.source);
+
 		c.next = null;
 		c.driver = null;
-		if( c.source != null )
-			releaseSource(c.source);
+		c.removedEffects = null;
 	}
 
 	function fillBuffer(buf : Buffer, dat : hxd.snd.Data, forceMono = false) {
@@ -655,5 +693,4 @@ class Driver {
 //		if( AL.getError() != 0 )
 //			throw "Failed to upload buffer data";
 	}
-
 }

+ 24 - 15
hxd/snd/Effect.hx

@@ -1,30 +1,39 @@
 package hxd.snd;
 
+@:allow(hxd.snd.Driver)
+@:allow(hxd.snd.ChannelBase)
 class Effect {
+	var refs : Int;
+	
+	var allocated (get, never) : Bool;
+	inline function get_allocated() return refs > 0;
 
-	/**
-		Audible gain used to estimate wether the channel should be cutoff or not
-	**/
-	public var gain (get, set) : Float;
+	function new() { 
+		refs = 0;
+	}
 
-	function get_gain() return 1.0;
-	function set_gain(v) {
-		throw "cannot set the gain on this effect";
+	// used to evaluate gain midification for virtualization sorting
+	public function applyAudibleGainModifier(v : Float) : Float {
 		return v;
 	}
 
-	function new() { }
-
-
-	/**
-		Actual volume change to be performed on channel.
-	**/
+	// used to tweak channel volume after virtualization sorting
 	public function getVolumeModifier() : Float {
 		return 1;
 	}
 
-	function apply( channel : Channel, source : Driver.Source ) {
-		throw this+" is not supported on this platform";
+	inline function incRefs() {
+		if (refs++ == 0) onAlloc();
 	}
 
+	inline function decRefs() {
+		if (refs == 0) return;
+		if (--refs == 0) onDelete();
+	}
+
+	function onAlloc () { }
+	function onDelete() { }
+
+	function apply   (source : Driver.Source) { }
+	function unapply (source : Driver.Source) { }
 }

+ 26 - 0
hxd/snd/effect/Pitch.hx

@@ -0,0 +1,26 @@
+package hxd.snd.effect;
+
+#if hlopenal
+private typedef AL = openal.AL;
+#else
+private typedef AL = hxd.snd.ALEmulator;
+#end
+
+class Pitch extends hxd.snd.Effect {
+	
+	public var value : Float;
+
+	public function new( value = 1.0 ) {
+		super();
+		this.value =  value;
+	}
+
+	override function apply(s : Driver.Source) {
+		AL.sourcef(s.inst, AL.PITCH, value);
+	}
+
+	override function unapply(s : Driver.Source) {
+		AL.sourcef(s.inst, AL.PITCH,  1.);
+	}
+
+}

+ 14 - 10
hxd/snd/effect/Spatialization.hx

@@ -1,11 +1,12 @@
 package hxd.snd.effect;
 
 #if hlopenal
-import openal.AL;
+private typedef AL = openal.AL;
+#else
+private typedef AL = hxd.snd.ALEmulator;
 #end
 
-class Spatialization extends Effect {
-
+class Spatialization extends hxd.snd.Effect {
 	public var position  : h3d.Vector;
 	public var velocity  : h3d.Vector;
 	public var direction : h3d.Vector;
@@ -36,8 +37,7 @@ class Spatialization extends Effect {
 		return gain;
 	}
 
-	#if hlopenal
-	override function apply(channel : Channel, s : Driver.Source) {
+	override function apply(s : Driver.Source) {
 		AL.sourcei(s.inst,  AL.SOURCE_RELATIVE, AL.FALSE);
 
 		AL.source3f(s.inst, AL.POSITION,  -position.x,  position.y,  position.z);
@@ -46,18 +46,22 @@ class Spatialization extends Effect {
 
 		AL.sourcef(s.inst, AL.REFERENCE_DISTANCE, referenceDistance);
 		AL.sourcef(s.inst, AL.ROLLOFF_FACTOR, rollOffFactor);
-		AL.sourcef(s.inst, AL.MIN_GAIN, 0);
 
 		AL.sourcef(s.inst, AL.MAX_DISTANCE, maxDistance == null ? 3.40282347e38 /* FLT_MAX */ : (maxDistance:Float) );
 	}
-	#end
 
-	override function get_gain() {
+	override function unapply(s : Driver.Source) {
+		AL.sourcei (s.inst, AL.SOURCE_RELATIVE, AL.TRUE);
+		AL.source3f(s.inst, AL.POSITION,  0, 0, 0);
+		AL.source3f(s.inst, AL.VELOCITY,  0, 0, 0);
+		AL.source3f(s.inst, AL.DIRECTION, 0, 0, 0);
+	}
+
+	override function applyAudibleGainModifier(v : Float) {
 		var dist = Driver.get().listener.position.distance(position);
 		dist = Math.max(dist, referenceDistance);
 		if (maxDistance != null) dist = Math.min(dist, maxDistance);
 		var gain = referenceDistance/(referenceDistance + rollOffFactor * (dist - referenceDistance));
-		return gain;
+		return v * gain;
 	}
-
 }

+ 242 - 0
hxd/snd/efx/Effect.hx

@@ -0,0 +1,242 @@
+package hxd.snd.efx;
+
+import hxd.snd.Driver;
+
+private typedef AL           = openal.AL;
+private typedef ALC          = openal.ALC;
+private typedef EFX          = openal.EFX;
+private typedef ALEffect     = openal.EFX.Effect;
+private typedef ALEffectSlot = openal.EFX.EffectSlot;
+
+@:allow(hxd.snd.efx.Manager)
+private class EffectSlot {
+	public var instance (default, null) : ALEffectSlot;
+	public var changed  (default, null) : Bool;
+
+	var effect     : Effect;
+	var used       : Bool;
+	var retainTime : Float;
+	var lastStamp  : Float;
+
+	function new(instance : ALEffectSlot) {
+		this.instance   = instance;
+		this.used       = false;
+		this.effect     = null;
+		this.changed    = true;
+		this.retainTime = 0.0;
+		this.lastStamp  = 0.0;
+	}
+}
+
+@:allow(hxd.snd.efx.Manager)
+private class AuxiliarySend {
+	public var instance (default, null) : Int;
+	public var changed  (default, null) : Bool;
+
+	public function new(instance : Int) {
+		this.instance = instance;
+		this.changed  = true;
+	}
+}
+
+private class SourceSends {
+	public var used  : Map<Effect, AuxiliarySend>;
+	public var free  : Array<AuxiliarySend>;
+	public var count : Int;
+
+	public function new() {
+		used  = new Map();
+		free  = [];
+		count = 0;
+	}
+}
+
+private class Manager {
+	static inline var AL_NUM_EFFECT_SLOTS = 4;
+	static var instance : Manager;
+
+	public var maxAuxiliarySends(default, null) : Int;
+	var effectSlots : Array<EffectSlot>;
+	var sourceSends : Map<Driver.Source, SourceSends>;
+
+	private function new() {
+		var bytes = haxe.io.Bytes.alloc(4);
+
+		// query maximum number of auxiliary sends
+		var device = @:privateAccess hxd.snd.Driver.get().alDevice;
+		ALC.getIntegerv(device, EFX.MAX_AUXILIARY_SENDS, 1, bytes);
+		maxAuxiliarySends = bytes.getInt32(0);
+		
+		// alloc effect slots
+		effectSlots = [];
+		for (i in 0...AL_NUM_EFFECT_SLOTS) {
+			EFX.genAuxiliaryEffectSlots(1, bytes);
+			if (AL.getError() != AL.NO_ERROR) break;
+			effectSlots.push(new EffectSlot(ALEffectSlot.ofInt(bytes.getInt32(0))));
+		}
+
+		sourceSends = new Map();
+
+		/* dispose
+		EFX.deleteAuxiliaryEffectSlots(effectSlots.length, arrayBytes([for( es in effectSlots ) es.instance.toInt()]));
+		effectSlots = [];
+		*/
+	}
+
+	public static function get() : Manager {
+		if (instance == null) {
+			instance = new Manager();
+			var driver = hxd.snd.Driver.get();
+			driver.addPreUpdateCallback(instance.preUpdate);
+			driver.addPostUpdateCallback(instance.postUpdate);
+		}
+		return instance;
+	}
+
+	function preUpdate() {
+		for (e in effectSlots) e.used = false;
+	}
+
+	function postUpdate() {
+		var now = haxe.Timer.stamp();
+		for (e in effectSlots) {
+			if (e.used || e.effect == null) continue;
+			if (now - e.lastStamp > e.retainTime) releaseEffectSlot(e);
+		}
+	}
+
+	public function getEffectSlot(effect : Effect, retainTime : Float = 0.0) : EffectSlot { 
+		var slot : EffectSlot = null;
+		for (e in effectSlots) {
+			if (e.effect == effect) {
+				slot = e;
+				break;
+			} else if (e.effect == null) 
+				slot = e;
+		}
+
+		if (slot == null) throw "too many request slot requests";
+		if (slot.effect == effect) {
+			slot.changed = false;
+		} else {
+			slot.changed  = true;
+			slot.effect = effect;
+		}
+		
+		slot.used       = true;
+		slot.retainTime = retainTime;
+		slot.lastStamp  = haxe.Timer.stamp();
+		return slot;
+	}
+
+	function releaseEffectSlot(slot : EffectSlot) {
+		EFX.auxiliaryEffectSloti(slot.instance, EFX.EFFECTSLOT_EFFECT, EFX.EFFECTSLOT_NULL);
+		slot.effect = null;
+	}
+
+	public function getAuxiliarySend(effect : Effect, source : Driver.Source) : AuxiliarySend {
+		var sends = sourceSends.get(source);
+		if (sends == null) {
+			sends = new SourceSends();
+			sourceSends.set(source, sends);
+		}
+
+		var as = sends.used.get(effect);
+		if (as != null) {
+			as.changed = false;
+			return as;
+		}
+
+		if (sends.free.length > 0) {
+			as = sends.free.pop();
+		} else {
+			if (sends.count >= maxAuxiliarySends) throw "too many auxilary send requests (max = " + maxAuxiliarySends + " )";
+			as = new AuxiliarySend(sends.count++);
+		}
+
+		as.changed = true;
+		sends.used.set(effect, as);
+		return as;
+	}
+
+	public function releaseAuxiliarySend(effect : Effect, source : Driver.Source) {
+		var sends = sourceSends.get(source);
+		if (sends == null) return;
+
+		var as = sends.used.get(effect);
+		if (as == null) return;
+
+		sends.free.push(as);
+		sends.used.remove(effect);
+	}
+}
+
+class Effect extends hxd.snd.Effect {
+	public var filter (default, set) : Filter;
+
+	var manager        : Manager;
+	var changed        : Bool;
+	var filterChanged  : Bool;
+	var slotRetainTime : Float;
+	var instance       : ALEffect;
+	var alBytes        : haxe.io.Bytes;
+
+	public function new(?filter : Filter) {
+		super();
+		this.manager        = Manager.get();
+		this.changed        = true;
+		this.filter         = filter;
+		this.slotRetainTime = 0.0;
+		this.alBytes        = haxe.io.Bytes.alloc(4);
+	}
+
+	inline function set_filter(v : Filter) { 
+		if (v == filter) return filter;
+		if (allocated) {
+			if (filter != null) filter.decRefs();
+			if (v != null) v.incRefs();
+		}
+		filterChanged = true; 
+		return filter = v; 
+	}
+
+	override function onAlloc() {
+		EFX.genEffects(1, alBytes);
+		instance = ALEffect.ofInt(alBytes.getInt32(0));
+		changed  = true;
+		if (filter != null) filter.incRefs();
+	}
+
+	override function onDelete() {
+		EFX.deleteEffects(1, alBytes);
+		if (filter != null) filter.decRefs();
+	}
+
+	override function apply(source : Driver.Source) {
+		var slot = manager.getEffectSlot(this, slotRetainTime);
+		if (changed || slot.changed) {
+			EFX.auxiliaryEffectSloti(slot.instance, EFX.EFFECTSLOT_EFFECT, instance.toInt());
+			changed = false;
+		}
+
+		var filterInst = EFX.FILTER_NULL;
+		if (filter != null) {
+			filter.effect = this;
+			filter.apply(source);
+			filter.effect = null;
+			filterInst = filter.instance.toInt();
+		}
+
+		var send = manager.getAuxiliarySend(this, source);
+		if (filterChanged || send.changed || slot.changed) {
+			AL.source3i(source.inst, EFX.AUXILIARY_SEND_FILTER, slot.instance.toInt(), send.instance, filterInst);
+			filterChanged = false;
+		}	
+	}
+
+	override function unapply(source : Driver.Source) {
+		var send = manager.getAuxiliarySend(this, source);
+		AL.source3i(source.inst, EFX.AUXILIARY_SEND_FILTER, EFX.EFFECTSLOT_NULL, send.instance, EFX.FILTER_NULL);
+		manager.releaseAuxiliarySend(this, source);
+	}
+}

+ 37 - 0
hxd/snd/efx/Filter.hx

@@ -0,0 +1,37 @@
+package hxd.snd.efx;
+
+private typedef AL       = openal.AL;
+private typedef EFX      = openal.EFX;
+private typedef ALFilter = openal.EFX.Filter;
+
+@:allow(hxd.snd.efx.Effect)
+class Filter extends hxd.snd.Effect {
+	var changed  : Bool;
+	var instance : ALFilter;
+	var alBytes  : haxe.io.Bytes;
+	var effect   : Effect;
+
+	function new() {
+		super();
+		changed = true;
+		alBytes = haxe.io.Bytes.alloc(4);
+	}
+
+	override function onAlloc() {
+		EFX.genFilters(1, alBytes);
+		instance = ALFilter.ofInt(alBytes.getInt32(0));
+		changed = true;
+	}
+
+	override function onDelete() {
+		EFX.deleteFilters(1, alBytes);
+	}
+
+	override function apply(source : Driver.Source) {
+		if (effect == null) AL.sourcei(source.inst, EFX.DIRECT_FILTER, instance.toInt()); 
+	}
+
+	override function unapply(source : Driver.Source) {
+		if (effect == null) AL.sourcei(source.inst, EFX.DIRECT_FILTER, EFX.FILTER_NULL); 
+	}
+}

+ 36 - 0
hxd/snd/efx/LowPassFilter.hx

@@ -0,0 +1,36 @@
+package hxd.snd.efx;
+
+import openal.AL;
+import openal.EFX;
+
+class LowPassFilter extends hxd.snd.efx.Filter {
+	public var gain   (default, set) : Float;
+	public var gainHF (default, set) : Float;
+
+	inline function set_gain(v)   { changed = true; return gain = v; }
+	inline function set_gainHF(v) { changed = true; return gainHF = v; }
+
+	public function new() {
+		super();
+		gain   = 1.0;
+		gainHF = 1.0;
+	}
+
+	override function onAlloc() {
+		super.onAlloc();
+		EFX.filteri(instance, EFX.FILTER_TYPE, EFX.FILTER_LOWPASS);
+	}
+
+	override function apply(source : Driver.Source) {
+		if (changed) {
+			EFX.filterf(instance, EFX.LOWPASS_GAIN,   gain);
+			EFX.filterf(instance, EFX.LOWPASS_GAINHF, gainHF);
+			changed = false;
+		}
+		super.apply(source);
+	}
+
+	override function applyAudibleGainModifier(v : Float) {
+		return v * gain;
+	}
+}

+ 115 - 0
hxd/snd/efx/Reverb.hx

@@ -0,0 +1,115 @@
+package hxd.snd.efx;
+
+import openal.AL;
+import openal.EFX;
+
+class Reverb extends hxd.snd.efx.Effect {
+	public var density             (default, set) : Float;
+    public var diffusion           (default, set) : Float;
+	public var gain                (default, set) : Float;
+    public var gainHF              (default, set) : Float;
+    public var gainLF              (default, set) : Float;
+    public var decayTime           (default, set) : Float;
+    public var decayHFRatio        (default, set) : Float;
+    public var decayLFRatio        (default, set) : Float;
+    public var reflectionsGain     (default, set) : Float;
+    public var reflectionsDelay    (default, set) : Float;
+    public var reflectionsPan      (default, set) : h3d.Vector;
+    public var lateReverbGain      (default, set) : Float;
+    public var lateReverbDelay     (default, set) : Float;
+    public var lateReverbPan       (default, set) : h3d.Vector;
+    public var echoTime            (default, set) : Float;
+    public var echoDepth           (default, set) : Float;
+    public var modulationTime      (default, set) : Float;
+    public var modulationDepth     (default, set) : Float;
+    public var airAbsorptionGainHF (default, set) : Float;
+    public var hfReference         (default, set) : Float;
+    public var lfReference         (default, set) : Float;
+    public var roomRolloffFactor   (default, set) : Float;
+    public var decayHFLimit        (default, set) : Int;
+
+	inline function set_density(v)             { changed = true; return density = v; }            
+	inline function set_diffusion(v)           { changed = true; return diffusion = v; }  
+	inline function set_gain(v)                { changed = true; return gain = v; }          
+	inline function set_gainHF(v)              { changed = true; return gainHF = v; }             
+	inline function set_gainLF(v)              { changed = true; return gainLF = v; }             
+	inline function set_decayTime(v)           { changed = true; return decayTime = v; }          
+	inline function set_decayHFRatio(v)        { changed = true; return decayHFRatio = v; }       
+	inline function set_decayLFRatio(v)        { changed = true; return decayLFRatio = v; }       
+	inline function set_reflectionsGain(v)     { changed = true; return reflectionsGain = v; }    
+	inline function set_reflectionsDelay(v)    { changed = true; return reflectionsDelay = v; }   
+	inline function set_reflectionsPan(v)      { changed = true; return reflectionsPan = v; }     
+	inline function set_lateReverbGain(v)      { changed = true; return lateReverbGain = v; }     
+	inline function set_lateReverbDelay(v)     { changed = true; return lateReverbDelay = v; }    
+	inline function set_lateReverbPan(v)       { changed = true; return lateReverbPan = v; }      
+	inline function set_echoTime(v)            { changed = true; return echoTime = v; }           
+	inline function set_echoDepth(v)           { changed = true; return echoDepth = v; }          
+	inline function set_modulationTime(v)      { changed = true; return modulationTime = v; }     
+	inline function set_modulationDepth(v)     { changed = true; return modulationDepth = v; }    
+	inline function set_airAbsorptionGainHF(v) { changed = true; return airAbsorptionGainHF = v; }
+	inline function set_hfReference(v)         { changed = true; return hfReference = v; }        
+	inline function set_lfReference(v)         { changed = true; return lfReference = v; }        
+	inline function set_roomRolloffFactor(v)   { changed = true; return roomRolloffFactor = v; }  
+	inline function set_decayHFLimit(v)        { changed = true; return decayHFLimit = v; }       
+
+	public function new(?preset : ReverbPreset) {
+		super();
+		loadPreset(preset != null ? preset : ReverbPreset.GENERIC);
+	}
+
+	public function loadPreset(preset : ReverbPreset) {
+		density             = preset.density;
+		diffusion           = preset.diffusion;
+		gain                = preset.gain;
+		gainHF              = preset.gainHF;
+		gainLF              = preset.gainLF;
+		decayTime           = preset.decayTime;
+		decayHFRatio        = preset.decayHFRatio;
+		decayLFRatio        = preset.decayLFRatio;
+		reflectionsGain     = preset.reflectionsGain;
+		reflectionsDelay    = preset.reflectionsDelay;
+		reflectionsPan      = preset.reflectionsPan;
+		lateReverbGain      = preset.lateReverbGain;
+		lateReverbDelay     = preset.lateReverbDelay;
+		lateReverbPan       = preset.lateReverbPan;
+		echoTime            = preset.echoTime;
+		echoDepth           = preset.echoDepth;
+		modulationTime      = preset.modulationTime;
+		modulationDepth     = preset.modulationDepth;
+		airAbsorptionGainHF = preset.airAbsorptionGainHF;
+		hfReference         = preset.hfReference;
+		lfReference         = preset.lfReference;
+		roomRolloffFactor   = preset.roomRolloffFactor;
+		decayHFLimit        = preset.decayHFLimit;
+	}
+
+	override function onAlloc() {
+		super.onAlloc();
+		EFX.effecti(instance, EFX.EFFECT_TYPE, EFX.EFFECT_REVERB);
+	}
+
+	override function apply(source : Driver.Source) {
+		if (changed) {
+			EFX.effectf(instance, EFX.REVERB_DENSITY,               density);
+			EFX.effectf(instance, EFX.REVERB_DIFFUSION,             diffusion);
+			EFX.effectf(instance, EFX.REVERB_GAIN,                  gain);
+			EFX.effectf(instance, EFX.REVERB_GAINHF,                gainHF);
+			EFX.effectf(instance, EFX.REVERB_DECAY_TIME,            decayTime);
+			EFX.effectf(instance, EFX.REVERB_DECAY_HFRATIO,         decayHFRatio);
+			EFX.effectf(instance, EFX.REVERB_REFLECTIONS_GAIN,      reflectionsGain);
+			EFX.effectf(instance, EFX.REVERB_REFLECTIONS_DELAY,     reflectionsDelay);
+			EFX.effectf(instance, EFX.REVERB_LATE_REVERB_GAIN,      lateReverbGain);
+			EFX.effectf(instance, EFX.REVERB_LATE_REVERB_DELAY,     lateReverbDelay);
+			EFX.effectf(instance, EFX.REVERB_AIR_ABSORPTION_GAINHF, airAbsorptionGainHF);
+			EFX.effectf(instance, EFX.REVERB_ROOM_ROLLOFF_FACTOR,   roomRolloffFactor);
+			EFX.effecti(instance, EFX.REVERB_DECAY_HFLIMIT,         decayHFLimit);
+
+			slotRetainTime = decayTime + reflectionsDelay + lateReverbDelay;
+		}
+		super.apply(source);
+	}
+
+	override function applyAudibleGainModifier(v : Float) {
+		return v + gain * Math.max(reflectionsGain, lateReverbGain);
+	}
+}

+ 217 - 0
hxd/snd/efx/ReverbPreset.hx

@@ -0,0 +1,217 @@
+package hxd.snd.efx;
+
+class ReverbPreset {
+	public var density             (default, null) : Float;
+    public var diffusion           (default, null) : Float;
+    public var gain                (default, null) : Float;
+    public var gainHF              (default, null) : Float;
+    public var gainLF              (default, null) : Float;
+    public var decayTime           (default, null) : Float;
+    public var decayHFRatio        (default, null) : Float;
+    public var decayLFRatio        (default, null) : Float;
+    public var reflectionsGain     (default, null) : Float;
+    public var reflectionsDelay    (default, null) : Float;
+    public var reflectionsPan      (default, null) : h3d.Vector;
+    public var lateReverbGain      (default, null) : Float;
+    public var lateReverbDelay     (default, null) : Float;
+    public var lateReverbPan       (default, null) : h3d.Vector;
+    public var echoTime            (default, null) : Float;
+    public var echoDepth           (default, null) : Float;
+    public var modulationTime      (default, null) : Float;
+    public var modulationDepth     (default, null) : Float;
+    public var airAbsorptionGainHF (default, null) : Float;
+    public var hfReference         (default, null) : Float;
+    public var lfReference         (default, null) : Float;
+    public var roomRolloffFactor   (default, null) : Float;
+    public var decayHFLimit        (default, null) : Int;
+
+	public function new( 
+		density:             Float,
+		diffusion:           Float,
+		gain:                Float,
+		gainHF:              Float,
+		gainLF:              Float,
+		decayTime:           Float,
+		decayHFRatio:        Float,
+		decayLFRatio:        Float,
+		reflectionsGain:     Float,
+		reflectionsDelay:    Float,
+		reflectionsPan:      h3d.Vector,
+		lateReverbGain:      Float,
+		lateReverbDelay:     Float,
+		lateReverbPan:       h3d.Vector,
+		echoTime:            Float,
+		echoDepth:           Float,
+		modulationTime:      Float,
+		modulationDepth:     Float,
+		airAbsorptionGainHF: Float,
+		hfReference:         Float,
+		lfReference:         Float,
+		roomRolloffFactor:   Float,
+		decayHFLimit:        Int
+	) {
+		this.density             = density;
+		this.diffusion           = diffusion;
+		this.gain                = gain;
+		this.gainHF              = gainHF;
+		this.gainLF              = gainLF;
+		this.decayTime           = decayTime;
+		this.decayHFRatio        = decayHFRatio;
+		this.decayLFRatio        = decayLFRatio;
+		this.reflectionsGain     = reflectionsGain;
+		this.reflectionsDelay    = reflectionsDelay;
+		this.reflectionsPan      = reflectionsPan;
+		this.lateReverbGain      = lateReverbGain;
+		this.lateReverbDelay     = lateReverbDelay;
+		this.lateReverbPan       = lateReverbPan;
+		this.echoTime            = echoTime;
+		this.echoDepth           = echoDepth;
+		this.modulationTime      = modulationTime;
+		this.modulationDepth     = modulationDepth;
+		this.airAbsorptionGainHF = airAbsorptionGainHF;
+		this.hfReference         = hfReference;
+		this.lfReference         = lfReference;
+		this.roomRolloffFactor   = roomRolloffFactor;
+		this.decayHFLimit        = decayHFLimit;
+	}
+
+	public static var GENERIC                   = new ReverbPreset( 1.0000, 1.0000, 0.3162, 0.8913, 1.0000, 1.4900, 0.8300, 1.0000, 0.0500, 0.0070,  new h3d.Vector(0.0000, 0.0000, 0.0000), 1.2589, 0.0110, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 5000.0000, 250.0000, 0.0000, 0x1 );
+	public static var PADDEDCELL                = new ReverbPreset( 0.1715, 1.0000, 0.3162, 0.0010, 1.0000, 0.1700, 0.1000, 1.0000, 0.2500, 0.0010,  new h3d.Vector(0.0000, 0.0000, 0.0000), 1.2691, 0.0020, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 5000.0000, 250.0000, 0.0000, 0x1 );
+	public static var ROOM                      = new ReverbPreset( 0.4287, 1.0000, 0.3162, 0.5929, 1.0000, 0.4000, 0.8300, 1.0000, 0.1503, 0.0020,  new h3d.Vector(0.0000, 0.0000, 0.0000), 1.0629, 0.0030, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 5000.0000, 250.0000, 0.0000, 0x1 );
+	public static var BATHROOM                  = new ReverbPreset( 0.1715, 1.0000, 0.3162, 0.2512, 1.0000, 1.4900, 0.5400, 1.0000, 0.6531, 0.0070,  new h3d.Vector(0.0000, 0.0000, 0.0000), 3.2734, 0.0110, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 5000.0000, 250.0000, 0.0000, 0x1 );
+	public static var LIVINGROOM                = new ReverbPreset( 0.9766, 1.0000, 0.3162, 0.0010, 1.0000, 0.5000, 0.1000, 1.0000, 0.2051, 0.0030,  new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2805, 0.0040, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 5000.0000, 250.0000, 0.0000, 0x1 );
+	public static var STONEROOM                 = new ReverbPreset( 1.0000, 1.0000, 0.3162, 0.7079, 1.0000, 2.3100, 0.6400, 1.0000, 0.4411, 0.0120,  new h3d.Vector(0.0000, 0.0000, 0.0000), 1.1003, 0.0170, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 5000.0000, 250.0000, 0.0000, 0x1 );
+	public static var AUDITORIUM                = new ReverbPreset( 1.0000, 1.0000, 0.3162, 0.5781, 1.0000, 4.3200, 0.5900, 1.0000, 0.4032, 0.0200,  new h3d.Vector(0.0000, 0.0000, 0.0000), 0.7170, 0.0300, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 5000.0000, 250.0000, 0.0000, 0x1 );
+	public static var CONCERTHALL               = new ReverbPreset( 1.0000, 1.0000, 0.3162, 0.5623, 1.0000, 3.9200, 0.7000, 1.0000, 0.2427, 0.0200,  new h3d.Vector(0.0000, 0.0000, 0.0000), 0.9977, 0.0290, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 5000.0000, 250.0000, 0.0000, 0x1 );
+	public static var CAVE                      = new ReverbPreset( 1.0000, 1.0000, 0.3162, 1.0000, 1.0000, 2.9100, 1.3000, 1.0000, 0.5000, 0.0150,  new h3d.Vector(0.0000, 0.0000, 0.0000), 0.7063, 0.0220, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 5000.0000, 250.0000, 0.0000, 0x0 );
+	public static var ARENA                     = new ReverbPreset( 1.0000, 1.0000, 0.3162, 0.4477, 1.0000, 7.2400, 0.3300, 1.0000, 0.2612, 0.0200,  new h3d.Vector(0.0000, 0.0000, 0.0000), 1.0186, 0.0300, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 5000.0000, 250.0000, 0.0000, 0x1 );
+	public static var HANGAR                    = new ReverbPreset( 1.0000, 1.0000, 0.3162, 0.3162, 1.0000, 10.0500, 0.2300, 1.0000, 0.5000, 0.0200, new h3d.Vector(0.0000, 0.0000, 0.0000), 1.2560, 0.0300, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 5000.0000, 250.0000, 0.0000, 0x1 );
+	public static var CARPETEDHALLWAY           = new ReverbPreset( 0.4287, 1.0000, 0.3162, 0.0100, 1.0000, 0.3000, 0.1000, 1.0000, 0.1215, 0.0020,  new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1531, 0.0300, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 5000.0000, 250.0000, 0.0000, 0x1 );
+	public static var HALLWAY                   = new ReverbPreset( 0.3645, 1.0000, 0.3162, 0.7079, 1.0000, 1.4900, 0.5900, 1.0000, 0.2458, 0.0070,  new h3d.Vector(0.0000, 0.0000, 0.0000), 1.6615, 0.0110, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 5000.0000, 250.0000, 0.0000, 0x1 );
+	public static var STONECORRIDOR             = new ReverbPreset( 1.0000, 1.0000, 0.3162, 0.7612, 1.0000, 2.7000, 0.7900, 1.0000, 0.2472, 0.0130,  new h3d.Vector(0.0000, 0.0000, 0.0000), 1.5758, 0.0200, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 5000.0000, 250.0000, 0.0000, 0x1 );
+	public static var ALLEY                     = new ReverbPreset( 1.0000, 0.3000, 0.3162, 0.7328, 1.0000, 1.4900, 0.8600, 1.0000, 0.2500, 0.0070,  new h3d.Vector(0.0000, 0.0000, 0.0000), 0.9954, 0.0110, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1250, 0.9500, 0.2500, 0.0000, 0.9943, 5000.0000, 250.0000, 0.0000, 0x1 );
+	public static var FOREST                    = new ReverbPreset( 1.0000, 0.3000, 0.3162, 0.0224, 1.0000, 1.4900, 0.5400, 1.0000, 0.0525, 0.1620,  new h3d.Vector(0.0000, 0.0000, 0.0000), 0.7682, 0.0880, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1250, 1.0000, 0.2500, 0.0000, 0.9943, 5000.0000, 250.0000, 0.0000, 0x1 );
+	public static var CITY                      = new ReverbPreset( 1.0000, 0.5000, 0.3162, 0.3981, 1.0000, 1.4900, 0.6700, 1.0000, 0.0730, 0.0070,  new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1427, 0.0110, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 5000.0000, 250.0000, 0.0000, 0x1 );
+	public static var MOUNTAINS                 = new ReverbPreset( 1.0000, 0.2700, 0.3162, 0.0562, 1.0000, 1.4900, 0.2100, 1.0000, 0.0407, 0.3000,  new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1919, 0.1000, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 1.0000, 0.2500, 0.0000, 0.9943, 5000.0000, 250.0000, 0.0000, 0x0 );
+	public static var QUARRY                    = new ReverbPreset( 1.0000, 1.0000, 0.3162, 0.3162, 1.0000, 1.4900, 0.8300, 1.0000, 0.0000, 0.0610,  new h3d.Vector(0.0000, 0.0000, 0.0000), 1.7783, 0.0250, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1250, 0.7000, 0.2500, 0.0000, 0.9943, 5000.0000, 250.0000, 0.0000, 0x1 );
+	public static var PLAIN                     = new ReverbPreset( 1.0000, 0.2100, 0.3162, 0.1000, 1.0000, 1.4900, 0.5000, 1.0000, 0.0585, 0.1790,  new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1089, 0.1000, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 1.0000, 0.2500, 0.0000, 0.9943, 5000.0000, 250.0000, 0.0000, 0x1 );
+	public static var PARKINGLOT                = new ReverbPreset( 1.0000, 1.0000, 0.3162, 1.0000, 1.0000, 1.6500, 1.5000, 1.0000, 0.2082, 0.0080,  new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2652, 0.0120, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 5000.0000, 250.0000, 0.0000, 0x0 );
+	public static var SEWERPIPE                 = new ReverbPreset( 0.3071, 0.8000, 0.3162, 0.3162, 1.0000, 2.8100, 0.1400, 1.0000, 1.6387, 0.0140,  new h3d.Vector(0.0000, 0.0000, 0.0000), 3.2471, 0.0210, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 5000.0000, 250.0000, 0.0000, 0x1 );
+	public static var UNDERWATER                = new ReverbPreset( 0.3645, 1.0000, 0.3162, 0.0100, 1.0000, 1.4900, 0.1000, 1.0000, 0.5963, 0.0070,  new h3d.Vector(0.0000, 0.0000, 0.0000), 7.0795, 0.0110, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 1.1800, 0.3480, 0.9943, 5000.0000, 250.0000, 0.0000, 0x1 );
+	public static var DRUGGED                   = new ReverbPreset( 0.4287, 0.5000, 0.3162, 1.0000, 1.0000, 8.3900, 1.3900, 1.0000, 0.8760, 0.0020,  new h3d.Vector(0.0000, 0.0000, 0.0000), 3.1081, 0.0300, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 1.0000, 0.9943, 5000.0000, 250.0000, 0.0000, 0x0 );
+	public static var DIZZY                     = new ReverbPreset( 0.3645, 0.6000, 0.3162, 0.6310, 1.0000, 17.2300, 0.5600, 1.0000, 0.1392, 0.0200, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.4937, 0.0300, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 1.0000, 0.8100, 0.3100, 0.9943, 5000.0000, 250.0000, 0.0000, 0x0 );
+	public static var PSYCHOTIC                 = new ReverbPreset( 0.0625, 0.5000, 0.3162, 0.8404, 1.0000, 7.5600, 0.9100, 1.0000, 0.4864, 0.0200,  new h3d.Vector(0.0000, 0.0000, 0.0000), 2.4378, 0.0300, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 4.0000, 1.0000, 0.9943, 5000.0000, 250.0000, 0.0000, 0x0 );
+
+	// Castle Presets
+	public static var CASTLE_SMALLROOM          = new ReverbPreset( 1.0000, 0.8900, 0.3162, 0.3981, 0.1000, 1.2200, 0.8300, 0.3100, 0.8913, 0.0220, new h3d.Vector(0.0000, 0.0000, 0.0000), 1.9953, 0.0110, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1380, 0.0800, 0.2500, 0.0000, 0.9943, 5168.6001, 139.5000, 0.0000, 0x1 );
+	public static var CASTLE_SHORTPASSAGE       = new ReverbPreset( 1.0000, 0.8900, 0.3162, 0.3162, 0.1000, 2.3200, 0.8300, 0.3100, 0.8913, 0.0070, new h3d.Vector(0.0000, 0.0000, 0.0000), 1.2589, 0.0230, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1380, 0.0800, 0.2500, 0.0000, 0.9943, 5168.6001, 139.5000, 0.0000, 0x1 );
+	public static var CASTLE_MEDIUMROOM         = new ReverbPreset( 1.0000, 0.9300, 0.3162, 0.2818, 0.1000, 2.0400, 0.8300, 0.4600, 0.6310, 0.0220, new h3d.Vector(0.0000, 0.0000, 0.0000), 1.5849, 0.0110, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1550, 0.0300, 0.2500, 0.0000, 0.9943, 5168.6001, 139.5000, 0.0000, 0x1 );
+	public static var CASTLE_LARGEROOM          = new ReverbPreset( 1.0000, 0.8200, 0.3162, 0.2818, 0.1259, 2.5300, 0.8300, 0.5000, 0.4467, 0.0340, new h3d.Vector(0.0000, 0.0000, 0.0000), 1.2589, 0.0160, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1850, 0.0700, 0.2500, 0.0000, 0.9943, 5168.6001, 139.5000, 0.0000, 0x1 );
+	public static var CASTLE_LONGPASSAGE        = new ReverbPreset( 1.0000, 0.8900, 0.3162, 0.3981, 0.1000, 3.4200, 0.8300, 0.3100, 0.8913, 0.0070, new h3d.Vector(0.0000, 0.0000, 0.0000), 1.4125, 0.0230, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1380, 0.0800, 0.2500, 0.0000, 0.9943, 5168.6001, 139.5000, 0.0000, 0x1 );
+	public static var CASTLE_HALL               = new ReverbPreset( 1.0000, 0.8100, 0.3162, 0.2818, 0.1778, 3.1400, 0.7900, 0.6200, 0.1778, 0.0560, new h3d.Vector(0.0000, 0.0000, 0.0000), 1.1220, 0.0240, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 5168.6001, 139.5000, 0.0000, 0x1 );
+	public static var CASTLE_CUPBOARD           = new ReverbPreset( 1.0000, 0.8900, 0.3162, 0.2818, 0.1000, 0.6700, 0.8700, 0.3100, 1.4125, 0.0100, new h3d.Vector(0.0000, 0.0000, 0.0000), 3.5481, 0.0070, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1380, 0.0800, 0.2500, 0.0000, 0.9943, 5168.6001, 139.5000, 0.0000, 0x1 );
+	public static var CASTLE_COURTYARD          = new ReverbPreset( 1.0000, 0.4200, 0.3162, 0.4467, 0.1995, 2.1300, 0.6100, 0.2300, 0.2239, 0.1600, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.7079, 0.0360, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.3700, 0.2500, 0.0000, 0.9943, 5000.0000, 250.0000, 0.0000, 0x0 );
+	public static var CASTLE_ALCOVE             = new ReverbPreset( 1.0000, 0.8900, 0.3162, 0.5012, 0.1000, 1.6400, 0.8700, 0.3100, 1.0000, 0.0070, new h3d.Vector(0.0000, 0.0000, 0.0000), 1.4125, 0.0340, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1380, 0.0800, 0.2500, 0.0000, 0.9943, 5168.6001, 139.5000, 0.0000, 0x1 );
+
+	// Factory Presets
+	public static var FACTORY_SMALLROOM         = new ReverbPreset( 0.3645, 0.8200, 0.3162, 0.7943, 0.5012, 1.7200, 0.6500, 1.3100, 0.7079, 0.0100, new h3d.Vector(0.0000, 0.0000, 0.0000), 1.7783, 0.0240, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1190, 0.0700, 0.2500, 0.0000, 0.9943, 3762.6001, 362.5000, 0.0000, 0x1 );
+	public static var FACTORY_SHORTPASSAGE      = new ReverbPreset( 0.3645, 0.6400, 0.2512, 0.7943, 0.5012, 2.5300, 0.6500, 1.3100, 1.0000, 0.0100, new h3d.Vector(0.0000, 0.0000, 0.0000), 1.2589, 0.0380, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1350, 0.2300, 0.2500, 0.0000, 0.9943, 3762.6001, 362.5000, 0.0000, 0x1 );
+	public static var FACTORY_MEDIUMROOM        = new ReverbPreset( 0.4287, 0.8200, 0.2512, 0.7943, 0.5012, 2.7600, 0.6500, 1.3100, 0.2818, 0.0220, new h3d.Vector(0.0000, 0.0000, 0.0000), 1.4125, 0.0230, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1740, 0.0700, 0.2500, 0.0000, 0.9943, 3762.6001, 362.5000, 0.0000, 0x1 );
+	public static var FACTORY_LARGEROOM         = new ReverbPreset( 0.4287, 0.7500, 0.2512, 0.7079, 0.6310, 4.2400, 0.5100, 1.3100, 0.1778, 0.0390, new h3d.Vector(0.0000, 0.0000, 0.0000), 1.1220, 0.0230, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2310, 0.0700, 0.2500, 0.0000, 0.9943, 3762.6001, 362.5000, 0.0000, 0x1 );
+	public static var FACTORY_LONGPASSAGE       = new ReverbPreset( 0.3645, 0.6400, 0.2512, 0.7943, 0.5012, 4.0600, 0.6500, 1.3100, 1.0000, 0.0200, new h3d.Vector(0.0000, 0.0000, 0.0000), 1.2589, 0.0370, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1350, 0.2300, 0.2500, 0.0000, 0.9943, 3762.6001, 362.5000, 0.0000, 0x1 );
+	public static var FACTORY_HALL              = new ReverbPreset( 0.4287, 0.7500, 0.3162, 0.7079, 0.6310, 7.4300, 0.5100, 1.3100, 0.0631, 0.0730, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.8913, 0.0270, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0700, 0.2500, 0.0000, 0.9943, 3762.6001, 362.5000, 0.0000, 0x1 );
+	public static var FACTORY_CUPBOARD          = new ReverbPreset( 0.3071, 0.6300, 0.2512, 0.7943, 0.5012, 0.4900, 0.6500, 1.3100, 1.2589, 0.0100, new h3d.Vector(0.0000, 0.0000, 0.0000), 1.9953, 0.0320, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1070, 0.0700, 0.2500, 0.0000, 0.9943, 3762.6001, 362.5000, 0.0000, 0x1 );
+	public static var FACTORY_COURTYARD         = new ReverbPreset( 0.3071, 0.5700, 0.3162, 0.3162, 0.6310, 2.3200, 0.2900, 0.5600, 0.2239, 0.1400, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.3981, 0.0390, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.2900, 0.2500, 0.0000, 0.9943, 3762.6001, 362.5000, 0.0000, 0x1 );
+	public static var FACTORY_ALCOVE            = new ReverbPreset( 0.3645, 0.5900, 0.2512, 0.7943, 0.5012, 3.1400, 0.6500, 1.3100, 1.4125, 0.0100, new h3d.Vector(0.0000, 0.0000, 0.0000), 1.0000, 0.0380, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1140, 0.1000, 0.2500, 0.0000, 0.9943, 3762.6001, 362.5000, 0.0000, 0x1 );
+	
+	// Ice Palace Presets
+	public static var ICEPALACE_SMALLROOM       = new ReverbPreset( 1.0000, 0.8400, 0.3162, 0.5623, 0.2818, 1.5100, 1.5300, 0.2700, 0.8913, 0.0100, new h3d.Vector(0.0000, 0.0000, 0.0000), 1.4125, 0.0110, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1640, 0.1400, 0.2500, 0.0000, 0.9943, 12428.5000, 99.6000, 0.0000, 0x1 );
+	public static var ICEPALACE_SHORTPASSAGE    = new ReverbPreset( 1.0000, 0.7500, 0.3162, 0.5623, 0.2818, 1.7900, 1.4600, 0.2800, 0.5012, 0.0100, new h3d.Vector(0.0000, 0.0000, 0.0000), 1.1220, 0.0190, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1770, 0.0900, 0.2500, 0.0000, 0.9943, 12428.5000, 99.6000, 0.0000, 0x1 );
+	public static var ICEPALACE_MEDIUMROOM      = new ReverbPreset( 1.0000, 0.8700, 0.3162, 0.5623, 0.4467, 2.2200, 1.5300, 0.3200, 0.3981, 0.0390, new h3d.Vector(0.0000, 0.0000, 0.0000), 1.1220, 0.0270, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1860, 0.1200, 0.2500, 0.0000, 0.9943, 12428.5000, 99.6000, 0.0000, 0x1 );
+	public static var ICEPALACE_LARGEROOM       = new ReverbPreset( 1.0000, 0.8100, 0.3162, 0.5623, 0.4467, 3.1400, 1.5300, 0.3200, 0.2512, 0.0390, new h3d.Vector(0.0000, 0.0000, 0.0000), 1.0000, 0.0270, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2140, 0.1100, 0.2500, 0.0000, 0.9943, 12428.5000, 99.6000, 0.0000, 0x1 );
+	public static var ICEPALACE_LONGPASSAGE     = new ReverbPreset( 1.0000, 0.7700, 0.3162, 0.5623, 0.3981, 3.0100, 1.4600, 0.2800, 0.7943, 0.0120, new h3d.Vector(0.0000, 0.0000, 0.0000), 1.2589, 0.0250, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1860, 0.0400, 0.2500, 0.0000, 0.9943, 12428.5000, 99.6000, 0.0000, 0x1 );
+	public static var ICEPALACE_HALL            = new ReverbPreset( 1.0000, 0.7600, 0.3162, 0.4467, 0.5623, 5.4900, 1.5300, 0.3800, 0.1122, 0.0540, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.6310, 0.0520, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2260, 0.1100, 0.2500, 0.0000, 0.9943, 12428.5000, 99.6000, 0.0000, 0x1 );
+	public static var ICEPALACE_CUPBOARD        = new ReverbPreset( 1.0000, 0.8300, 0.3162, 0.5012, 0.2239, 0.7600, 1.5300, 0.2600, 1.1220, 0.0120, new h3d.Vector(0.0000, 0.0000, 0.0000), 1.9953, 0.0160, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1430, 0.0800, 0.2500, 0.0000, 0.9943, 12428.5000, 99.6000, 0.0000, 0x1 );
+	public static var ICEPALACE_COURTYARD       = new ReverbPreset( 1.0000, 0.5900, 0.3162, 0.2818, 0.3162, 2.0400, 1.2000, 0.3800, 0.3162, 0.1730, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.3162, 0.0430, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2350, 0.4800, 0.2500, 0.0000, 0.9943, 12428.5000, 99.6000, 0.0000, 0x1 );
+	public static var ICEPALACE_ALCOVE          = new ReverbPreset( 1.0000, 0.8400, 0.3162, 0.5623, 0.2818, 2.7600, 1.4600, 0.2800, 1.1220, 0.0100, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.8913, 0.0300, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1610, 0.0900, 0.2500, 0.0000, 0.9943, 12428.5000, 99.6000, 0.0000, 0x1 );
+
+	// Space Station Presets
+	public static var SPACESTATION_SMALLROOM    = new ReverbPreset( 0.2109, 0.7000, 0.3162, 0.7079, 0.8913, 1.7200, 0.8200, 0.5500, 0.7943, 0.0070, new h3d.Vector(0.0000, 0.0000, 0.0000), 1.4125, 0.0130, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1880, 0.2600, 0.2500, 0.0000, 0.9943, 3316.1001, 458.2000, 0.0000, 0x1 );
+	public static var SPACESTATION_SHORTPASSAGE = new ReverbPreset( 0.2109, 0.8700, 0.3162, 0.6310, 0.8913, 3.5700, 0.5000, 0.5500, 1.0000, 0.0120, new h3d.Vector(0.0000, 0.0000, 0.0000), 1.1220, 0.0160, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1720, 0.2000, 0.2500, 0.0000, 0.9943, 3316.1001, 458.2000, 0.0000, 0x1 );
+	public static var SPACESTATION_MEDIUMROOM   = new ReverbPreset( 0.2109, 0.7500, 0.3162, 0.6310, 0.8913, 3.0100, 0.5000, 0.5500, 0.3981, 0.0340, new h3d.Vector(0.0000, 0.0000, 0.0000), 1.1220, 0.0350, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2090, 0.3100, 0.2500, 0.0000, 0.9943, 3316.1001, 458.2000, 0.0000, 0x1 );
+	public static var SPACESTATION_LARGEROOM    = new ReverbPreset( 0.3645, 0.8100, 0.3162, 0.6310, 0.8913, 3.8900, 0.3800, 0.6100, 0.3162, 0.0560, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.8913, 0.0350, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2330, 0.2800, 0.2500, 0.0000, 0.9943, 3316.1001, 458.2000, 0.0000, 0x1 );
+	public static var SPACESTATION_LONGPASSAGE  = new ReverbPreset( 0.4287, 0.8200, 0.3162, 0.6310, 0.8913, 4.6200, 0.6200, 0.5500, 1.0000, 0.0120, new h3d.Vector(0.0000, 0.0000, 0.0000), 1.2589, 0.0310, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.2300, 0.2500, 0.0000, 0.9943, 3316.1001, 458.2000, 0.0000, 0x1 );
+	public static var SPACESTATION_HALL         = new ReverbPreset( 0.4287, 0.8700, 0.3162, 0.6310, 0.8913, 7.1100, 0.3800, 0.6100, 0.1778, 0.1000, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.6310, 0.0470, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.2500, 0.2500, 0.0000, 0.9943, 3316.1001, 458.2000, 0.0000, 0x1 );
+	public static var SPACESTATION_CUPBOARD     = new ReverbPreset( 0.1715, 0.5600, 0.3162, 0.7079, 0.8913, 0.7900, 0.8100, 0.5500, 1.4125, 0.0070, new h3d.Vector(0.0000, 0.0000, 0.0000), 1.7783, 0.0180, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1810, 0.3100, 0.2500, 0.0000, 0.9943, 3316.1001, 458.2000, 0.0000, 0x1 );
+	public static var SPACESTATION_ALCOVE       = new ReverbPreset( 0.2109, 0.7800, 0.3162, 0.7079, 0.8913, 1.1600, 0.8100, 0.5500, 1.4125, 0.0070, new h3d.Vector(0.0000, 0.0000, 0.0000), 1.0000, 0.0180, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1920, 0.2100, 0.2500, 0.0000, 0.9943, 3316.1001, 458.2000, 0.0000, 0x1 );
+
+	// Wooden Galleon Presets
+	public static var WOODEN_SMALLROOM          = new ReverbPreset( 1.0000, 1.0000, 0.3162, 0.1122, 0.3162, 0.7900, 0.3200, 0.8700, 1.0000, 0.0320, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.8913, 0.0290, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 4705.0000, 99.6000, 0.0000, 0x1 );
+	public static var WOODEN_SHORTPASSAGE       = new ReverbPreset( 1.0000, 1.0000, 0.3162, 0.1259, 0.3162, 1.7500, 0.5000, 0.8700, 0.8913, 0.0120, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.6310, 0.0240, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 4705.0000, 99.6000, 0.0000, 0x1 );
+	public static var WOODEN_MEDIUMROOM         = new ReverbPreset( 1.0000, 1.0000, 0.3162, 0.1000, 0.2818, 1.4700, 0.4200, 0.8200, 0.8913, 0.0490, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.8913, 0.0290, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 4705.0000, 99.6000, 0.0000, 0x1 );
+	public static var WOODEN_LARGEROOM          = new ReverbPreset( 1.0000, 1.0000, 0.3162, 0.0891, 0.2818, 2.6500, 0.3300, 0.8200, 0.8913, 0.0660, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.7943, 0.0490, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 4705.0000, 99.6000, 0.0000, 0x1 );
+	public static var WOODEN_LONGPASSAGE        = new ReverbPreset( 1.0000, 1.0000, 0.3162, 0.1000, 0.3162, 1.9900, 0.4000, 0.7900, 1.0000, 0.0200, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.4467, 0.0360, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 4705.0000, 99.6000, 0.0000, 0x1 );
+	public static var WOODEN_HALL               = new ReverbPreset( 1.0000, 1.0000, 0.3162, 0.0794, 0.2818, 3.4500, 0.3000, 0.8200, 0.8913, 0.0880, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.7943, 0.0630, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 4705.0000, 99.6000, 0.0000, 0x1 );
+	public static var WOODEN_CUPBOARD           = new ReverbPreset( 1.0000, 1.0000, 0.3162, 0.1413, 0.3162, 0.5600, 0.4600, 0.9100, 1.1220, 0.0120, new h3d.Vector(0.0000, 0.0000, 0.0000), 1.1220, 0.0280, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 4705.0000, 99.6000, 0.0000, 0x1 );
+	public static var WOODEN_COURTYARD          = new ReverbPreset( 1.0000, 0.6500, 0.3162, 0.0794, 0.3162, 1.7900, 0.3500, 0.7900, 0.5623, 0.1230, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1000, 0.0320, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 4705.0000, 99.6000, 0.0000, 0x1 );
+	public static var WOODEN_ALCOVE             = new ReverbPreset( 1.0000, 1.0000, 0.3162, 0.1259, 0.3162, 1.2200, 0.6200, 0.9100, 1.1220, 0.0120, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.7079, 0.0240, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 4705.0000, 99.6000, 0.0000, 0x1 );
+	
+	// Sports Presets
+	public static var SPORT_EMPTYSTADIUM        = new ReverbPreset( 1.0000, 1.0000, 0.3162, 0.4467, 0.7943, 6.2600, 0.5100, 1.1000, 0.0631, 0.1830, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.3981, 0.0380, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 5000.0000, 250.0000, 0.0000, 0x1 );
+	public static var SPORT_SQUASHCOURT         = new ReverbPreset( 1.0000, 0.7500, 0.3162, 0.3162, 0.7943, 2.2200, 0.9100, 1.1600, 0.4467, 0.0070, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.7943, 0.0110, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1260, 0.1900, 0.2500, 0.0000, 0.9943, 7176.8999, 211.2000, 0.0000, 0x1 );
+	public static var SPORT_SMALLSWIMMINGPOOL   = new ReverbPreset( 1.0000, 0.7000, 0.3162, 0.7943, 0.8913, 2.7600, 1.2500, 1.1400, 0.6310, 0.0200, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.7943, 0.0300, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1790, 0.1500, 0.8950, 0.1900, 0.9943, 5000.0000, 250.0000, 0.0000, 0x0 );
+	public static var SPORT_LARGESWIMMINGPOOL   = new ReverbPreset( 1.0000, 0.8200, 0.3162, 0.7943, 1.0000, 5.4900, 1.3100, 1.1400, 0.4467, 0.0390, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.5012, 0.0490, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2220, 0.5500, 1.1590, 0.2100, 0.9943, 5000.0000, 250.0000, 0.0000, 0x0 );
+	public static var SPORT_GYMNASIUM           = new ReverbPreset( 1.0000, 0.8100, 0.3162, 0.4467, 0.8913, 3.1400, 1.0600, 1.3500, 0.3981, 0.0290, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.5623, 0.0450, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1460, 0.1400, 0.2500, 0.0000, 0.9943, 7176.8999, 211.2000, 0.0000, 0x1 );
+	public static var SPORT_FULLSTADIUM         = new ReverbPreset( 1.0000, 1.0000, 0.3162, 0.0708, 0.7943, 5.2500, 0.1700, 0.8000, 0.1000, 0.1880, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2818, 0.0380, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 5000.0000, 250.0000, 0.0000, 0x1 );
+	public static var SPORT_STADIUMTANNOY       = new ReverbPreset( 1.0000, 0.7800, 0.3162, 0.5623, 0.5012, 2.5300, 0.8800, 0.6800, 0.2818, 0.2300, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.5012, 0.0630, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.2000, 0.2500, 0.0000, 0.9943, 5000.0000, 250.0000, 0.0000, 0x1 );
+
+	// Prefab Presets
+	public static var PREFAB_WORKSHOP           = new ReverbPreset( 0.4287, 1.0000, 0.3162, 0.1413, 0.3981, 0.7600, 1.0000, 1.0000, 1.0000, 0.0120, new h3d.Vector(0.0000, 0.0000, 0.0000 ), 1.1220, 0.0120, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 5000.0000, 250.0000, 0.0000, 0x0 );
+	public static var PREFAB_SCHOOLROOM         = new ReverbPreset( 0.4022, 0.6900, 0.3162, 0.6310, 0.5012, 0.9800, 0.4500, 0.1800, 1.4125, 0.0170, new h3d.Vector(0.0000, 0.0000, 0.0000 ), 1.4125, 0.0150, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.0950, 0.1400, 0.2500, 0.0000, 0.9943, 7176.8999, 211.2000, 0.0000, 0x1 );
+	public static var PREFAB_PRACTISEROOM       = new ReverbPreset( 0.4022, 0.8700, 0.3162, 0.3981, 0.5012, 1.1200, 0.5600, 0.1800, 1.2589, 0.0100, new h3d.Vector(0.0000, 0.0000, 0.0000 ), 1.4125, 0.0110, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.0950, 0.1400, 0.2500, 0.0000, 0.9943, 7176.8999, 211.2000, 0.0000, 0x1 );
+	public static var PREFAB_OUTHOUSE           = new ReverbPreset( 1.0000, 0.8200, 0.3162, 0.1122, 0.1585, 1.3800, 0.3800, 0.3500, 0.8913, 0.0240, new h3d.Vector(0.0000, 0.0000, -0.0000), 0.6310, 0.0440, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1210, 0.1700, 0.2500, 0.0000, 0.9943, 2854.3999, 107.5000, 0.0000, 0x0 );
+	public static var PREFAB_CARAVAN            = new ReverbPreset( 1.0000, 1.0000, 0.3162, 0.0891, 0.1259, 0.4300, 1.5000, 1.0000, 1.0000, 0.0120, new h3d.Vector(0.0000, 0.0000, 0.0000 ), 1.9953, 0.0120, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 5000.0000, 250.0000, 0.0000, 0x0 );
+
+	// Dome and Pipe Presets
+	public static var DOME_TOMB                 = new ReverbPreset( 1.0000, 0.7900, 0.3162, 0.3548, 0.2239, 4.1800, 0.2100, 0.1000, 0.3868, 0.0300,  new h3d.Vector(0.0000, 0.0000, 0.0000), 1.6788, 0.0220, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1770, 0.1900, 0.2500, 0.0000, 0.9943, 2854.3999, 20.0000, 0.0000, 0x0 );
+	public static var PIPE_SMALL                = new ReverbPreset( 1.0000, 1.0000, 0.3162, 0.3548, 0.2239, 5.0400, 0.1000, 0.1000, 0.5012, 0.0320,  new h3d.Vector(0.0000, 0.0000, 0.0000), 2.5119, 0.0150, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 2854.3999, 20.0000, 0.0000, 0x1 );
+	public static var DOME_SAINTPAULS           = new ReverbPreset( 1.0000, 0.8700, 0.3162, 0.3548, 0.2239, 10.4800, 0.1900, 0.1000, 0.1778, 0.0900, new h3d.Vector(0.0000, 0.0000, 0.0000), 1.2589, 0.0420, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.1200, 0.2500, 0.0000, 0.9943, 2854.3999, 20.0000, 0.0000, 0x1 );
+	public static var PIPE_LONGTHIN             = new ReverbPreset( 0.2560, 0.9100, 0.3162, 0.4467, 0.2818, 9.2100, 0.1800, 0.1000, 0.7079, 0.0100,  new h3d.Vector(0.0000, 0.0000, 0.0000), 0.7079, 0.0220, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 2854.3999, 20.0000, 0.0000, 0x0 );
+	public static var PIPE_LARGE                = new ReverbPreset( 1.0000, 1.0000, 0.3162, 0.3548, 0.2239, 8.4500, 0.1000, 0.1000, 0.3981, 0.0460,  new h3d.Vector(0.0000, 0.0000, 0.0000), 1.5849, 0.0320, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 2854.3999, 20.0000, 0.0000, 0x1 );
+	public static var PIPE_RESONANT             = new ReverbPreset( 0.1373, 0.9100, 0.3162, 0.4467, 0.2818, 6.8100, 0.1800, 0.1000, 0.7079, 0.0100,  new h3d.Vector(0.0000, 0.0000, 0.0000), 1.0000, 0.0220, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 2854.3999, 20.0000, 0.0000, 0x0 );
+
+	// Outdoors Presets
+	public static var OUTDOORS_BACKYARD         = new ReverbPreset( 1.0000, 0.4500, 0.3162, 0.2512, 0.5012, 1.1200, 0.3400, 0.4600, 0.4467, 0.0690, new h3d.Vector(0.0000, 0.0000, -0.0000), 0.7079, 0.0230, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2180, 0.3400, 0.2500, 0.0000, 0.9943, 4399.1001, 242.9000, 0.0000, 0x0 );
+	public static var OUTDOORS_ROLLINGPLAINS    = new ReverbPreset( 1.0000, 0.0000, 0.3162, 0.0112, 0.6310, 2.1300, 0.2100, 0.4600, 0.1778, 0.3000, new h3d.Vector(0.0000, 0.0000, -0.0000), 0.4467, 0.0190, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 1.0000, 0.2500, 0.0000, 0.9943, 4399.1001, 242.9000, 0.0000, 0x0 );
+	public static var OUTDOORS_DEEPCANYON       = new ReverbPreset( 1.0000, 0.7400, 0.3162, 0.1778, 0.6310, 3.8900, 0.2100, 0.4600, 0.3162, 0.2230, new h3d.Vector(0.0000, 0.0000, -0.0000), 0.3548, 0.0190, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 1.0000, 0.2500, 0.0000, 0.9943, 4399.1001, 242.9000, 0.0000, 0x0 );
+	public static var OUTDOORS_CREEK            = new ReverbPreset( 1.0000, 0.3500, 0.3162, 0.1778, 0.5012, 2.1300, 0.2100, 0.4600, 0.3981, 0.1150, new h3d.Vector(0.0000, 0.0000, -0.0000), 0.1995, 0.0310, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2180, 0.3400, 0.2500, 0.0000, 0.9943, 4399.1001, 242.9000, 0.0000, 0x0 );
+	public static var OUTDOORS_VALLEY           = new ReverbPreset( 1.0000, 0.2800, 0.3162, 0.0282, 0.1585, 2.8800, 0.2600, 0.3500, 0.1413, 0.2630, new h3d.Vector(0.0000, 0.0000, -0.0000), 0.3981, 0.1000, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.3400, 0.2500, 0.0000, 0.9943, 2854.3999, 107.5000, 0.0000, 0x0 );
+
+	// Mood Presets
+	public static var MOOD_HEAVEN               = new ReverbPreset( 1.0000, 0.9400, 0.3162, 0.7943, 0.4467, 5.0400, 1.1200, 0.5600, 0.2427, 0.0200, new h3d.Vector(0.0000, 0.0000, 0.0000), 1.2589, 0.0290, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0800, 2.7420, 0.0500, 0.9977, 5000.0000, 250.0000, 0.0000, 0x1 );
+	public static var MOOD_HELL                 = new ReverbPreset( 1.0000, 0.5700, 0.3162, 0.3548, 0.4467, 3.5700, 0.4900, 2.0000, 0.0000, 0.0200, new h3d.Vector(0.0000, 0.0000, 0.0000), 1.4125, 0.0300, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1100, 0.0400, 2.1090, 0.5200, 0.9943, 5000.0000, 139.5000, 0.0000, 0x0 );
+	public static var MOOD_MEMORY               = new ReverbPreset( 1.0000, 0.8500, 0.3162, 0.6310, 0.3548, 4.0600, 0.8200, 0.5600, 0.0398, 0.0000, new h3d.Vector(0.0000, 0.0000, 0.0000), 1.1220, 0.0000, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.4740, 0.4500, 0.9886, 5000.0000, 250.0000, 0.0000, 0x0 );
+
+	// Driving Presets
+	public static var DRIVING_COMMENTATOR       = new ReverbPreset( 1.0000, 0.0000, 0.3162, 0.5623, 0.5012, 2.4200, 0.8800, 0.6800, 0.1995, 0.0930, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2512, 0.0170, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 1.0000, 0.2500, 0.0000, 0.9886, 5000.0000, 250.0000, 0.0000, 0x1  );
+	public static var DRIVING_PITGARAGE         = new ReverbPreset( 0.4287, 0.5900, 0.3162, 0.7079, 0.5623, 1.7200, 0.9300, 0.8700, 0.5623, 0.0000, new h3d.Vector(0.0000, 0.0000, 0.0000), 1.2589, 0.0160, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.1100, 0.2500, 0.0000, 0.9943, 5000.0000, 250.0000, 0.0000, 0x0  );
+	public static var DRIVING_INCAR_RACER       = new ReverbPreset( 0.0832, 0.8000, 0.3162, 1.0000, 0.7943, 0.1700, 2.0000, 0.4100, 1.7783, 0.0070, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.7079, 0.0150, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 10268.2002, 251.0000, 0.0000, 0x1 );
+	public static var DRIVING_INCAR_SPORTS      = new ReverbPreset( 0.0832, 0.8000, 0.3162, 0.6310, 1.0000, 0.1700, 0.7500, 0.4100, 1.0000, 0.0100, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.5623, 0.0000, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 10268.2002, 251.0000, 0.0000, 0x1 );
+	public static var DRIVING_INCAR_LUXURY      = new ReverbPreset( 0.2560, 1.0000, 0.3162, 0.1000, 0.5012, 0.1300, 0.4100, 0.4600, 0.7943, 0.0100, new h3d.Vector(0.0000, 0.0000, 0.0000), 1.5849, 0.0100, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 10268.2002, 251.0000, 0.0000, 0x1 );
+	public static var DRIVING_FULLGRANDSTAND    = new ReverbPreset( 1.0000, 1.0000, 0.3162, 0.2818, 0.6310, 3.0100, 1.3700, 1.2800, 0.3548, 0.0900, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1778, 0.0490, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 10420.2002, 250.0000, 0.0000, 0x0 );
+	public static var DRIVING_EMPTYGRANDSTAND   = new ReverbPreset( 1.0000, 1.0000, 0.3162, 1.0000, 0.7943, 4.6200, 1.7500, 1.4000, 0.2082, 0.0900, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2512, 0.0490, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.0000, 0.9943, 10420.2002, 250.0000, 0.0000, 0x0 );
+	public static var DRIVING_TUNNEL            = new ReverbPreset( 1.0000, 0.8100, 0.3162, 0.3981, 0.8913, 3.4200, 0.9400, 1.3100, 0.7079, 0.0510, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.7079, 0.0470, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2140, 0.0500, 0.2500, 0.0000, 0.9943, 5000.0000, 155.3000, 0.0000, 0x1  );
+
+	// City Presets
+	public static var CITY_STREETS              = new ReverbPreset( 1.0000, 0.7800, 0.3162, 0.7079, 0.8913, 1.7900, 1.1200, 0.9100, 0.2818, 0.0460, new h3d.Vector(0.0000, 0.0000, 0.0000 ), 0.1995, 0.0280, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.2000, 0.2500, 0.0000, 0.9943, 5000.0000, 250.0000, 0.0000, 0x1 );
+	public static var CITY_SUBWAY               = new ReverbPreset( 1.0000, 0.7400, 0.3162, 0.7079, 0.8913, 3.0100, 1.2300, 0.9100, 0.7079, 0.0460, new h3d.Vector(0.0000, 0.0000, 0.0000 ), 1.2589, 0.0280, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1250, 0.2100, 0.2500, 0.0000, 0.9943, 5000.0000, 250.0000, 0.0000, 0x1 );
+	public static var CITY_MUSEUM               = new ReverbPreset( 1.0000, 0.8200, 0.3162, 0.1778, 0.1778, 3.2800, 1.4000, 0.5700, 0.2512, 0.0390, new h3d.Vector(0.0000, 0.0000, -0.0000), 0.8913, 0.0340, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1300, 0.1700, 0.2500, 0.0000, 0.9943, 2854.3999, 107.5000, 0.0000, 0x0 );
+	public static var CITY_LIBRARY              = new ReverbPreset( 1.0000, 0.8200, 0.3162, 0.2818, 0.0891, 2.7600, 0.8900, 0.4100, 0.3548, 0.0290, new h3d.Vector(0.0000, 0.0000, -0.0000), 0.8913, 0.0200, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1300, 0.1700, 0.2500, 0.0000, 0.9943, 2854.3999, 107.5000, 0.0000, 0x0 );
+	public static var CITY_UNDERPASS            = new ReverbPreset( 1.0000, 0.8200, 0.3162, 0.4467, 0.8913, 3.5700, 1.1200, 0.9100, 0.3981, 0.0590, new h3d.Vector(0.0000, 0.0000, 0.0000 ), 0.8913, 0.0370, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.1400, 0.2500, 0.0000, 0.9920, 5000.0000, 250.0000, 0.0000, 0x1 );
+	public static var CITY_ABANDONED            = new ReverbPreset( 1.0000, 0.6900, 0.3162, 0.7943, 0.8913, 3.2800, 1.1700, 0.9100, 0.4467, 0.0440, new h3d.Vector(0.0000, 0.0000, 0.0000 ), 0.2818, 0.0240, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.2000, 0.2500, 0.0000, 0.9966, 5000.0000, 250.0000, 0.0000, 0x1 );
+
+	// Misc. Presets
+	public static var DUSTYROOM                 = new ReverbPreset( 0.3645, 0.5600, 0.3162, 0.7943, 0.7079, 1.7900, 0.3800, 0.2100, 0.5012, 0.0020, new h3d.Vector(0.0000, 0.0000, 0.0000), 1.2589, 0.0060, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2020, 0.0500, 0.2500, 0.0000, 0.9886, 13046.0000, 163.3000, 0.0000, 0x1 );
+	public static var CHAPEL                    = new ReverbPreset( 1.0000, 0.8400, 0.3162, 0.5623, 1.0000, 4.6200, 0.6400, 1.2300, 0.4467, 0.0320, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.7943, 0.0490, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.2500, 0.0000, 0.2500, 0.1100, 0.9943, 5000.0000, 250.0000, 0.0000, 0x1  );
+	public static var SMALLWATERROOM            = new ReverbPreset( 1.0000, 0.7000, 0.3162, 0.4477, 1.0000, 1.5100, 1.2500, 1.1400, 0.8913, 0.0200, new h3d.Vector(0.0000, 0.0000, 0.0000), 1.4125, 0.0300, new h3d.Vector(0.0000, 0.0000, 0.0000), 0.1790, 0.1500, 0.8950, 0.1900, 0.9920, 5000.0000, 250.0000, 0.0000, 0x0  );
+}