From 035068e77676b94c72626e8bf47b108598d5d613 Mon Sep 17 00:00:00 2001 From: Brian Matzon Date: Tue, 6 Jan 2004 19:22:12 +0000 Subject: [PATCH] New EAX model implemented - needs more testing --- src/java/org/lwjgl/openal/eax/BaseEAX.java | 15 +- src/java/org/lwjgl/openal/eax/CoreEAX.java | 22 +- .../lwjgl/openal/eax/EAXBufferProperties.java | 273 +++++++++++++----- .../openal/eax/EAXListenerProperties.java | 243 +++++++++++++--- src/java/org/lwjgl/test/openal/EAXTest.java | 264 +++++++++++++++-- .../lwjgl/test/openal/MovingSoundTest.java | 2 - src/native/common/extal.h | 15 +- .../common/org_lwjgl_openal_eax_CoreEAX.cpp | 69 ++--- .../common/org_lwjgl_openal_eax_CoreEAX.h | 30 +- 9 files changed, 702 insertions(+), 231 deletions(-) diff --git a/src/java/org/lwjgl/openal/eax/BaseEAX.java b/src/java/org/lwjgl/openal/eax/BaseEAX.java index 88f18b7e..31942585 100644 --- a/src/java/org/lwjgl/openal/eax/BaseEAX.java +++ b/src/java/org/lwjgl/openal/eax/BaseEAX.java @@ -52,12 +52,6 @@ public abstract class BaseEAX { initialize(); } - /** - * Override to provide any initialization code after creation. - */ - protected static void init() { - } - /** * Static initialization */ @@ -79,7 +73,7 @@ public abstract class BaseEAX { throw new Exception("EAX instance could not be created."); } created = true; - init(); + CoreEAX.init(); } /** @@ -104,4 +98,11 @@ public abstract class BaseEAX { * Native method the destroy the EAX */ protected static native void nDestroy(); + + /** + * @return true if EAX has been created + */ + public static boolean isCreated() { + return created; + } } \ No newline at end of file diff --git a/src/java/org/lwjgl/openal/eax/CoreEAX.java b/src/java/org/lwjgl/openal/eax/CoreEAX.java index c671a3db..53517fbd 100644 --- a/src/java/org/lwjgl/openal/eax/CoreEAX.java +++ b/src/java/org/lwjgl/openal/eax/CoreEAX.java @@ -44,17 +44,16 @@ import java.nio.Buffer; public class CoreEAX extends BaseEAX implements BaseEAXConstants { /** GUID for buffer */ - public static int BUFFER_GUID; + public static final int BUFFER_GUID = 1; /** GUID for listener */ - public static int LISTENER_GUID; + public static final int LISTENER_GUID = 2; /** * Load extensions */ - protected static void init() { + protected static void init() { determineAvailableExtensions(); - setGUID(); } /** @@ -62,11 +61,6 @@ public class CoreEAX extends BaseEAX implements BaseEAXConstants { */ protected static native void determineAvailableExtensions(); - /** - * Sets the GUID's for the buffer and listener objects - */ - protected static native void setGUID(); - /** * Retrieves an EAX Value * @@ -77,7 +71,10 @@ public class CoreEAX extends BaseEAX implements BaseEAXConstants { * @param size size of area being written to * @return OpenAL Error code */ - public static native int eaxGet(int propertySetID, int property, int source, Buffer data, int size); + public static int eaxGet(int propertySetID, int property, int source, Buffer data, int size) { + return neaxGet(propertySetID, property, source, data, data.position(), size); + } + private static native int neaxGet(int propertySetID, int property, int source, Buffer data, int position, int size); /** * Sets an EAX Value @@ -89,5 +86,8 @@ public class CoreEAX extends BaseEAX implements BaseEAXConstants { * @param size size of area being written to * @return OpenAL Error code */ - public static native int eaxSet(int propertySetID, int property, int source, Buffer data, int size); + public static int eaxSet(int propertySetID, int property, int source, Buffer data, int size) { + return neaxSet(propertySetID, property, source, data, data.position(), size); + } + private static native int neaxSet(int propertySetID, int property, int source, Buffer data, int position, int size); } \ No newline at end of file diff --git a/src/java/org/lwjgl/openal/eax/EAXBufferProperties.java b/src/java/org/lwjgl/openal/eax/EAXBufferProperties.java index b1e685be..ffa5a4b0 100644 --- a/src/java/org/lwjgl/openal/eax/EAXBufferProperties.java +++ b/src/java/org/lwjgl/openal/eax/EAXBufferProperties.java @@ -45,12 +45,21 @@ import java.nio.ByteOrder; * @version $Revision$ */ public class EAXBufferProperties { + + /** Whether auto commit has been anabled */ + private boolean autoCommit = true; + + /** Current source being operated on */ + private int currentSource = -1; /** ByteBuffer representing EAXBUFFERPROPERTIES */ protected ByteBuffer eaxBufferProperties; /** size needed by ByteBuffer to contain EAXBUFFERPROPERTIES */ protected static int EAXBUFFERPROPERTIES_SIZE; + + // EAX values and offsets + // ======================================================== /** direct path level offset */ protected static int direct_offset; @@ -181,48 +190,193 @@ public class EAXBufferProperties { (EAXBUFFER_FLAGS_DIRECTHFAUTO | EAXBUFFER_FLAGS_ROOMAUTO | EAXBUFFER_FLAGS_ROOMHFAUTO); + + // ------------------------------------------------------- static { System.loadLibrary(org.lwjgl.Sys.getLibraryName()); EAXBUFFERPROPERTIES_SIZE = sizeOfEaxBufferProperties(); assignOffsets(); } - + + /** + * Creates a new EAXBufferProperties object + */ public EAXBufferProperties() { eaxBufferProperties = ByteBuffer.allocateDirect(EAXBUFFERPROPERTIES_SIZE); eaxBufferProperties.order(ByteOrder.nativeOrder()); } - + /** - * Sets an EAX Value - * - * @param property property being queried - * @param source the source to be queried + * Sets the current source on which to perform effects + * + * @param source Source on which to perform effects */ - public void eaxSet(int property, int source) { - EAX.eaxSet( - CoreEAX.BUFFER_GUID, - property, - source, - eaxBufferProperties, - EAXBUFFERPROPERTIES_SIZE); + public void setCurrentSource(int source) { + currentSource = source; } - + /** - * Sets an EAX Value - * - * @param property property being queried - * @param source the source to be queried + * Retrieves the current source + * + * @return Source on which effects are being performed */ - public void eaxGet(int property, int source) { + public int getCurrentSource() { + return currentSource; + } + + /** + * Loads current EAX values from current source + */ + public void loadEAXValues() { EAX.eaxGet( - CoreEAX.BUFFER_GUID, - property, - source, - eaxBufferProperties, - EAXBUFFERPROPERTIES_SIZE); + CoreEAX.BUFFER_GUID, + EAXBUFFER_ALLPARAMETERS, + currentSource, + eaxBufferProperties, + EAXBUFFERPROPERTIES_SIZE); } + + /** + * Resets this buffer property to default values + */ + public void reset() { + boolean commitValue = autoCommit; + + // disable autocommit + autoCommit = false; + + // set values + setDirect(EAXBUFFER_DEFAULTDIRECT); + setDirectHF(EAXBUFFER_DEFAULTDIRECTHF); + setRoom(EAXBUFFER_DEFAULTROOM); + setRoomHF(EAXBUFFER_DEFAULTROOMHF); + setRoomRolloffFactor(EAXBUFFER_DEFAULTROOMROLLOFFFACTOR); + setObstruction(EAXBUFFER_DEFAULTOBSTRUCTION); + setObstructionLFRatio(EAXBUFFER_DEFAULTOBSTRUCTIONLFRATIO); + setOcclusion(EAXBUFFER_DEFAULTOCCLUSION); + setOcclusionLFRatio(EAXBUFFER_DEFAULTOCCLUSIONLFRATIO); + setOcclusionRoomRatio(EAXBUFFER_DEFAULTOCCLUSIONROOMRATIO); + setOutsideVolumeHF(EAXBUFFER_DEFAULTOUTSIDEVOLUMEHF); + setAirAbsorptionFactor(EAXBUFFER_DEFAULTAIRABSORPTIONFACTOR); + setFlags(EAXBUFFER_DEFAULTFLAGS); + + // reset auto commit + autoCommit = commitValue; + } + + + /** + * Commits any changes + */ + public void commit() { + // call eaxSet with Buffer guid, setting all parameters + EAX.eaxSet( + CoreEAX.BUFFER_GUID, EAXBUFFER_ALLPARAMETERS, + currentSource, eaxBufferProperties, EAXBUFFERPROPERTIES_SIZE); + } + + /** + * Tests whether auto commit is enabled or not + * + * @return true if auto commit is inabled + */ + public boolean isAutoCommitEnabled() { + return autoCommit; + } + + /** + * Enabled or disables auto commit + * + * @param enabled True to enable, false to disable + */ + public void setAutoCommit(boolean enabled) { + autoCommit = enabled; + } + + /** + * Performs auto commit, if enabled + */ + private final void autoCommit() { + if(autoCommit) { + commit(); + } + } + + /** + * Retrieves the size of the containing ByteBuffer + */ + public static int getSize() { + return EAXBUFFERPROPERTIES_SIZE; + } + + /** + * Returns a String representation of the EAXBufferProperties object + * + * @return String representation of the EAXBufferProperties object + */ + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("EAXBufferProperties ["); + sb.append("lDirect = "); + sb.append(getDirect()); + sb.append(", "); + + sb.append("lDirectHF = "); + sb.append(getDirectHF()); + sb.append(", "); + + sb.append("lRoom = "); + sb.append(getRoom()); + sb.append(", "); + + sb.append("lRoomHF = "); + sb.append(getRoomHF()); + sb.append(", "); + + sb.append("flRoomRolloffFactor = "); + sb.append(getRoomRolloffFactor()); + sb.append(", "); + + sb.append("lObstruction = "); + sb.append(getObstruction()); + sb.append(", "); + + sb.append("flObstructionLFRatio = "); + sb.append(getObstructionLFRatio()); + sb.append(", "); + + sb.append("lOcclusion = "); + sb.append(getOcclusion()); + sb.append(", "); + + sb.append("flOcclusionLFRatio = "); + sb.append(getOcclusionLFRatio()); + sb.append(", "); + + sb.append("flOcclusionRoomRatio = "); + sb.append(getOcclusionRoomRatio()); + sb.append(", "); + + sb.append("lOutsideVolumeHF = "); + sb.append(getOutsideVolumeHF()); + sb.append(", "); + + sb.append("flAirAbsorptionFactor = "); + sb.append(getAirAbsorptionFactor()); + sb.append(", "); + + sb.append("dwFlags = "); + sb.append(getFlags()); + + sb.append("]"); + return sb.toString(); + } + + // Getters and Setters of struct + // ========================================================================== + /** * Retireves the direct path level * @@ -239,6 +393,7 @@ public class EAXBufferProperties { */ public void setDirect(int direct) { eaxBufferProperties.putInt(direct_offset, direct); + autoCommit(); } /** @@ -257,6 +412,7 @@ public class EAXBufferProperties { */ public void setDirectHF(int directHF) { eaxBufferProperties.putInt(directHF_offset, directHF); + autoCommit(); } /** @@ -275,6 +431,7 @@ public class EAXBufferProperties { */ public void setRoom(int room) { eaxBufferProperties.putInt(room_offset, room); + autoCommit(); } /** @@ -293,6 +450,7 @@ public class EAXBufferProperties { */ public void setRoomHF(int roomHF) { eaxBufferProperties.putInt(roomHF_offset, roomHF); + autoCommit(); } /** @@ -311,6 +469,7 @@ public class EAXBufferProperties { */ public void setRoomRolloffFactor(float roomRolloffFactor) { eaxBufferProperties.putFloat(roomRolloffFactor_offset, roomRolloffFactor); + autoCommit(); } /** @@ -329,6 +488,7 @@ public class EAXBufferProperties { */ public void setObstruction(int obstruction) { eaxBufferProperties.putInt(obstruction_offset, obstruction); + autoCommit(); } /** @@ -347,6 +507,7 @@ public class EAXBufferProperties { */ public void setObstructionLFRatio(float obstructionLFRatio) { eaxBufferProperties.putFloat(obstructionLFRatio_offset, obstructionLFRatio); + autoCommit(); } /** @@ -365,6 +526,7 @@ public class EAXBufferProperties { */ public void setOcclusion(int occlusion) { eaxBufferProperties.putInt(occlusion_offset, occlusion); + autoCommit(); } /** @@ -383,6 +545,7 @@ public class EAXBufferProperties { */ public void setOcclusionLFRatio(float occlusionLFRatio) { eaxBufferProperties.putFloat(occlusionLFRatio_offset, occlusionLFRatio); + autoCommit(); } /** @@ -401,6 +564,7 @@ public class EAXBufferProperties { */ public void setOcclusionRoomRatio(float occlusionRoomRatio) { eaxBufferProperties.putFloat(occlusionRoomRatio_offset, occlusionRoomRatio); + autoCommit(); } /** @@ -419,6 +583,7 @@ public class EAXBufferProperties { */ public void setOutsideVolumeHF(int outsideVolumeHF) { eaxBufferProperties.putInt(outsideVolumeHF_offset, outsideVolumeHF); + autoCommit(); } /** @@ -436,9 +601,8 @@ public class EAXBufferProperties { * @param airAbsorptionFactor multiplier for DSPROPERTY_EAXLISTENER_AIRABSORPTIONHF to set to */ public void setAirAbsorptionFactor(float airAbsorptionFactor) { - eaxBufferProperties.putFloat( - airAbsorptionFactor_offset, - airAbsorptionFactor); + eaxBufferProperties.putFloat(airAbsorptionFactor_offset, airAbsorptionFactor); + autoCommit(); } /** @@ -457,15 +621,11 @@ public class EAXBufferProperties { */ public void setFlags(int flags) { eaxBufferProperties.putInt(flags_offset, flags); + autoCommit(); } - - /** - * Retrieves the size of the containing ByteBuffer - */ - public static int getSize() { - return EAXBUFFERPROPERTIES_SIZE; - } - + + // -------------------------------------------------------------------------- + /** * Retrieves the size of the EAXBUFFERPROPERTIES */ @@ -474,46 +634,5 @@ public class EAXBufferProperties { /** * Sets the offsets to the fields */ - protected static native void assignOffsets(); - - /** - * Retrieves the size of the property - * - * @param property Property to determine size of - * @return size of property - */ - private static int getSizeOfProperty(int property) { - switch (property) { - case EAXBufferProperties.EAXBUFFER_NONE : - return 0; - - /* long */ - case EAXBufferProperties.EAXBUFFER_DIRECT : - case EAXBufferProperties.EAXBUFFER_DIRECTHF : - case EAXBufferProperties.EAXBUFFER_ROOM : - case EAXBufferProperties.EAXBUFFER_ROOMHF : - case EAXBufferProperties.EAXBUFFER_OBSTRUCTION : - case EAXBufferProperties.EAXBUFFER_OCCLUSION : - case EAXBufferProperties.EAXBUFFER_OUTSIDEVOLUMEHF : - - /* float */ - case EAXBufferProperties.EAXBUFFER_ROOMROLLOFFFACTOR : - case EAXBufferProperties.EAXBUFFER_OBSTRUCTIONLFRATIO : - case EAXBufferProperties.EAXBUFFER_OCCLUSIONLFRATIO : - case EAXBufferProperties.EAXBUFFER_OCCLUSIONROOMRATIO : - case EAXBufferProperties.EAXBUFFER_AIRABSORPTIONFACTOR : - - /* unsigned long */ - case EAXBufferProperties.EAXBUFFER_FLAGS : - return 4; - - case EAXBufferProperties.EAXBUFFER_ALLPARAMETERS : - return EAXBufferProperties.EAXBUFFERPROPERTIES_SIZE; - - default : - throw new IllegalArgumentException( - "No such property '" + property + "'"); - - } - } + protected static native void assignOffsets(); } \ No newline at end of file diff --git a/src/java/org/lwjgl/openal/eax/EAXListenerProperties.java b/src/java/org/lwjgl/openal/eax/EAXListenerProperties.java index 140669bf..e9f8621e 100644 --- a/src/java/org/lwjgl/openal/eax/EAXListenerProperties.java +++ b/src/java/org/lwjgl/openal/eax/EAXListenerProperties.java @@ -43,12 +43,18 @@ import java.nio.ByteOrder; * @version $Revision$ */ public class EAXListenerProperties { + + /** Whether auto commit has been anabled */ + private boolean autoCommit = true; /** ByteBuffer representing EAXLISTENERPROPERTIES */ protected ByteBuffer eaxListenerProperties; /** size needed by ByteBuffer to contain EAXLISTENERPROPERTIES */ protected static int EAXLISTENERPROPERTIES_SIZE; + + // EAX values and offsets + // ======================================================== /** room effect level offset */ protected static int room_offset; @@ -201,6 +207,9 @@ public class EAXListenerProperties { | EAXLISTENERFLAGS_REVERBSCALE | EAXLISTENERFLAGS_REVERBDELAYSCALE | EAXLISTENERFLAGS_DECAYHFLIMIT); + + // ------------------------------------------------------- + static { System.loadLibrary(org.lwjgl.Sys.getLibraryName()); EAXLISTENERPROPERTIES_SIZE = sizeOfEaxListenerProperties(); @@ -212,36 +221,163 @@ public class EAXListenerProperties { ByteBuffer.allocateDirect(EAXLISTENERPROPERTIES_SIZE); eaxListenerProperties.order(ByteOrder.nativeOrder()); } - + /** - * Sets an EAX Value - * - * @param property property being queried - * @param source the source to be queried + * Loads current EAX values */ - public void eaxSet(int property, int source) { - EAX.eaxSet( - CoreEAX.LISTENER_GUID, - property, - source, - eaxListenerProperties, - EAXLISTENERPROPERTIES_SIZE); - } - - /** - * Gets an EAX Value - * - * @param property property being queried - * @param source the source to be queried - */ - public void eaxGet(int property, int source) { + public void loadEAXValues() { EAX.eaxGet( - CoreEAX.LISTENER_GUID, - property, - source, - eaxListenerProperties, - EAXLISTENERPROPERTIES_SIZE); + CoreEAX.LISTENER_GUID, + EAXLISTENER_ALLPARAMETERS, + 0, + eaxListenerProperties, + EAXLISTENERPROPERTIES_SIZE ); + } + + /** + * Resets this buffer property to default values + */ + public void reset() { + boolean commitValue = autoCommit; + + // disable autocommit + autoCommit = false; + + // set values + setRoom(EAXLISTENER_DEFAULTROOM); + setRoomHF(EAXLISTENER_DEFAULTROOMHF); + setRoomRolloffFactor(EAXLISTENER_DEFAULTROOMROLLOFFFACTOR); + setDecayTime(EAXLISTENER_DEFAULTDECAYTIME); + setDecayTimeHFRatio(EAXLISTENER_DEFAULTDECAYHFRATIO); + setReflections(EAXLISTENER_DEFAULTREFLECTIONS); + setReflectionsDelay(EAXLISTENER_DEFAULTREFLECTIONSDELAY); + setReverb(EAXLISTENER_DEFAULTREVERB); + setReverbDelay(EAXLISTENER_DEFAULTREVERBDELAY); + setEnvironment(EAXLISTENER_DEFAULTENVIRONMENT); + setEnvironmentSize(EAXLISTENER_DEFAULTENVIRONMENTSIZE); + setEnvironmentDiffusion(EAXLISTENER_DEFAULTENVIRONMENTDIFFUSION); + setAirAbsorptionFactor(EAXLISTENER_DEFAULTAIRABSORPTIONHF); + setFlags(EAXLISTENER_DEFAULTFLAGS); + + // reset auto commit + autoCommit = commitValue; } + + + /** + * Commits any changes + */ + public void commit() { + // call eaxSet with Listener guid, setting all parameters + EAX.eaxSet( + CoreEAX.LISTENER_GUID, EAXLISTENER_ALLPARAMETERS | EAXLISTENER_IMMEDIATE, + 0, eaxListenerProperties, EAXLISTENERPROPERTIES_SIZE); + } + + /** + * Tests whether auto commit is enabled or not + * + * @return true if auto commit is inabled + */ + public boolean isAutoCommitEnabled() { + return autoCommit; + } + + /** + * Enabled or disables auto commit + * + * @param enabled True to enable, false to disable + */ + public void setAutoCommit(boolean enabled) { + autoCommit = enabled; + } + + /** + * Performs auto commit, if enabled + */ + private final void autoCommit() { + if(autoCommit) { + commit(); + } + } + + /** + * Retrieves the size of the containing ByteBuffer + */ + public int getSize() { + return EAXLISTENERPROPERTIES_SIZE; + } + + /** + * Returns a String representation of the EAXBufferProperties object + * + * @return String representation of the EAXBufferProperties object + */ + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("EAXListenerProperties ["); + + sb.append("lRoom = "); + sb.append(getRoom()); + sb.append(", "); + + sb.append("lRoomHF = "); + sb.append(getRoomHF()); + sb.append(", "); + + sb.append("flRoomRolloffFactor = "); + sb.append(getRoomRolloffFactor()); + sb.append(", "); + + sb.append("flDecayTime = "); + sb.append(getDecayTime()); + sb.append(", "); + + sb.append("flDecayHFRatio = "); + sb.append(getDecayTimeHFRatio()); + sb.append(", "); + + sb.append("lReflections = "); + sb.append(getReflections()); + sb.append(", "); + + sb.append("flReflectionsDelay = "); + sb.append(getReflectionsDelay()); + sb.append(", "); + + sb.append("lReverb = "); + sb.append(getReverb()); + sb.append(", "); + + sb.append("flReverbDelay = "); + sb.append(getReverbDelay()); + sb.append(", "); + + sb.append("dwEnvironment = "); + sb.append(getEnvironment()); + sb.append(", "); + + sb.append("flEnvironmentSize = "); + sb.append(getEnvironmentSize()); + sb.append(", "); + + sb.append("flEnvironmentDiffusion = "); + sb.append(getEnvironmentDiffusion()); + sb.append(", "); + + sb.append("flAirAbsorptionHF = "); + sb.append(getAirAbsorptionHF()); + sb.append(", "); + + sb.append("dwFlags = "); + sb.append(getFlags()); + + sb.append("]"); + return sb.toString(); + } + + // Getters and Setters of struct + // ========================================================================== /** * Retireves the room effect level @@ -259,6 +395,7 @@ public class EAXListenerProperties { */ public void setRoom(int room) { eaxListenerProperties.putInt(room_offset, room); + autoCommit(); } /** @@ -277,6 +414,7 @@ public class EAXListenerProperties { */ public void setRoomHF(int roomHF) { eaxListenerProperties.putInt(roomHF_offset, roomHF); + autoCommit(); } /** @@ -295,6 +433,7 @@ public class EAXListenerProperties { */ public void setRoomRolloffFactor(float roomRolloffFactor) { eaxListenerProperties.putFloat(roomRolloffFactor_offset, roomRolloffFactor); + autoCommit(); } /** @@ -313,6 +452,7 @@ public class EAXListenerProperties { */ public void setDecayTime(float decayTime) { eaxListenerProperties.putFloat(decayTime_offset, decayTime); + autoCommit(); } /** @@ -331,6 +471,7 @@ public class EAXListenerProperties { */ public void setDecayTimeHFRatio(float decayTimeHFRatio) { eaxListenerProperties.putFloat(decayHFRatio_offset, decayTimeHFRatio); + autoCommit(); } /** @@ -349,6 +490,7 @@ public class EAXListenerProperties { */ public void setReflections(int reflections) { eaxListenerProperties.putInt(reflections_offset, reflections); + autoCommit(); } /** @@ -367,6 +509,7 @@ public class EAXListenerProperties { */ public void setReflectionsDelay(float reflectionsDelay) { eaxListenerProperties.putFloat(reflectionsDelay_offset, reflectionsDelay); + autoCommit(); } /** @@ -385,6 +528,7 @@ public class EAXListenerProperties { */ public void setReverb(int reverb) { eaxListenerProperties.putInt(reverb_offset, reverb); + autoCommit(); } /** @@ -403,6 +547,7 @@ public class EAXListenerProperties { */ public void setReverbDelay(float reverbDelay) { eaxListenerProperties.putFloat(reverbDelay_offset, reverbDelay); + autoCommit(); } /** @@ -421,6 +566,22 @@ public class EAXListenerProperties { */ public void setEnvironment(int environment) { eaxListenerProperties.putInt(environment_offset, environment); + + // we need to handle environment differently than all other + // values on auto commit, since it cannot be single handely set + // using ALLPARAMETERS + // + // To set the environment specifically we need to pass + // only the environment value and its size. Also pass the + // EAXLISTENER_ENVIRONMENT value (and since we're committing IMMEDIATE too) + if (autoCommit) { + EAX.eaxSet( + CoreEAX.LISTENER_GUID, EAXLISTENER_ENVIRONMENT | EAXLISTENER_IMMEDIATE, + 0, eaxListenerProperties.position(environment_offset), 4); + + // rewind buffer + eaxListenerProperties.rewind(); + } } /** @@ -439,6 +600,22 @@ public class EAXListenerProperties { */ public void setEnvironmentSize(float environmentSize) { eaxListenerProperties.putFloat(environmentSize_offset, environmentSize); + + // we need to handle environment size differently than all other + // values on auto commit, since it cannot be single handely set + // using ALLPARAMETERS + // + // To set the environment size specifically we need to pass + // only the environment size value and its size. Also pass the + // EAXLISTENER_ENVIRONMENTSIZE value (and since we're committing IMMEDIATE too) + if (autoCommit) { + EAX.eaxSet( + CoreEAX.LISTENER_GUID, EAXLISTENER_ENVIRONMENTSIZE | EAXLISTENER_IMMEDIATE, + 0, eaxListenerProperties.position(environmentSize_offset), 4); + + // rewind buffer + eaxListenerProperties.rewind(); + } } /** @@ -456,9 +633,8 @@ public class EAXListenerProperties { * @param environmentDiffusion environment diffusion to set to */ public void setEnvironmentDiffusion(float environmentDiffusion) { - eaxListenerProperties.putFloat( - environmentDiffusion_offset, - environmentDiffusion); + eaxListenerProperties.putFloat(environmentDiffusion_offset, environmentDiffusion); + autoCommit(); } /** @@ -477,6 +653,7 @@ public class EAXListenerProperties { */ public void setAirAbsorptionFactor(float airAbsorptionHF) { eaxListenerProperties.putFloat(airAbsorptionHF_offset, airAbsorptionHF); + autoCommit(); } /** @@ -495,14 +672,10 @@ public class EAXListenerProperties { */ public void setFlags(int flags) { eaxListenerProperties.putInt(flags_offset, flags); + autoCommit(); } - /** - * Retrieves the size of the containing ByteBuffer - */ - public int getSize() { - return EAXLISTENERPROPERTIES_SIZE; - } + // -------------------------------------------------------------------------- /** * Retrieves the size of the EAXLISTENERPROPERTIES diff --git a/src/java/org/lwjgl/test/openal/EAXTest.java b/src/java/org/lwjgl/test/openal/EAXTest.java index 2f0ecfd8..37de9507 100644 --- a/src/java/org/lwjgl/test/openal/EAXTest.java +++ b/src/java/org/lwjgl/test/openal/EAXTest.java @@ -31,7 +31,14 @@ */ package org.lwjgl.test.openal; -import org.lwjgl.openal.eax.EAX; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.IntBuffer; + +import org.lwjgl.openal.eax.*; +import org.lwjgl.openal.*; +import org.lwjgl.Sys; /** * $Id$ @@ -42,39 +49,240 @@ import org.lwjgl.openal.eax.EAX; * @version $Revision$ */ public class EAXTest extends BasicTest { + + /** OpenAL buffers */ + private IntBuffer soundBuffers = createIntBuffer(1); + + /** OpenAL sources */ + private IntBuffer soundSources = createIntBuffer(1); + + /** Listener EAX property object */ + private EAXListenerProperties listenerProperties; + + /** Buffer EAX property object */ + private EAXBufferProperties bufferProperties; + + /** + * Creates an instance of EAXTest + */ + public EAXTest() { + super(); + } + + /** + * Runs the actual test, using supplied arguments + */ + protected void execute(String[] args) { + try { + System.out.print("Testing EAX support..."); + EAX.create(); + System.out.println("supported!"); + } catch (Exception e) { + System.out.println("not supported!"); + } - /** - * Creates an instance of EAXTest - */ - public EAXTest() { - super(); + try { + AL.create(); + AL.alGetError(); // clear any errors + } catch(Exception e) { + System.out.println("Unable to initialize OpenAL"); } - /** - * Runs the actual test, using supplied arguments - */ - protected void execute(String[] args) { - try { - System.out.print("Testing EAX support..."); - EAX.create(); - System.out.println("supported!"); - } catch (Exception e) { - System.out.println("no supported!"); + // continue with test if EAX is supported + if (EAX.isCreated() && AL.isCreated() && initialize()) { + runTest(); + + // kill sources and buffers + AL.alSourceStop(soundSources.get(0)); + AL.alDeleteSources(soundSources); + AL.alDeleteBuffers(soundBuffers); + + EAX.destroy(); + } + + //shutdown + alExit(); + + System.out.println("test done."); + } + + private boolean initialize() { + // creating buffers + Sys.log("Creating buffers"); + AL.alGenBuffers(soundBuffers); + soundBuffers.rewind(); + + // creating sources + Sys.log("Creating sources"); + AL.alGenSources(soundSources); + soundSources.rewind(); + + // load sound files (left, center, right).wav + Sys.log("Loading Footsteps.wav"); + WaveData footsteps = WaveData.create("Footsteps.wav"); + AL.alBufferData(soundBuffers.get(0), footsteps.format, footsteps.data, footsteps.data.capacity(), footsteps.samplerate); + AL.alSourcef(soundSources.get(0), AL.AL_PITCH, 1.0f); + AL.alSourcef(soundSources.get(0), AL.AL_GAIN, 1.0f); + AL.alSourcei(soundSources.get(0), AL.AL_BUFFER, soundBuffers.get(0)); + AL.alSourcei(soundSources.get(0), AL.AL_LOOPING, AL.AL_TRUE); + + // create eax property objects + listenerProperties = new EAXListenerProperties(); + bufferProperties = new EAXBufferProperties(); + + // set buffer to work on source 0 + bufferProperties.setCurrentSource(soundSources.get(0)); + + return AL.alGetError() == AL.AL_NO_ERROR; + } + + /** + * Runs the actual EAXTest + */ + private void runTest() { + boolean running = true; + char key; + + assert AL.alIsBuffer(soundBuffers.get(0)) : "Failed to validate buffer"; + + // handle menu + do { + printMenu(); + key = readInput(); + + switch (key) { + // play sound + case '1' : { + AL.alSourcePlay(soundSources.get(0)); + break; + } + + // stop sound + case '2' : { + AL.alSourceStop(soundSources.get(0)); + break; + } + + // add reverb + case '3' : { + listenerProperties.setEnvironment(EAX.EAX_ENVIRONMENT_HANGAR); + break; + } + + // remove reverb + case '4' : { + listenerProperties.setEnvironment(EAX.EAX_ENVIRONMENT_GENERIC); + break; + } + + // add occlusion + case '5' : { + bufferProperties.setOcclusion(bufferProperties.getOcclusion()-5000); + break; + } + + // remove occlusion + case '6' : { + bufferProperties.setOcclusion(bufferProperties.getOcclusion()+5000); + break; + } + + // add obstruction + case '7' : { + bufferProperties.setObstruction(bufferProperties.getObstruction()-5000); + break; + } + + // remove obstruction + case '8' : { + bufferProperties.setObstruction(bufferProperties.getObstruction()+5000); + break; + } + + // commit eax values + case 'c' : { + bufferProperties.commit(); + listenerProperties.commit(); + break; + } + + // toggle autocommit + case 't' : { + bufferProperties.setAutoCommit(!bufferProperties.isAutoCommitEnabled()); + listenerProperties.setAutoCommit(!listenerProperties.isAutoCommitEnabled()); + System.out.println("\n[Buffer] Auto Commit is now: " + bufferProperties.isAutoCommitEnabled()); + System.out.println("\n[Listen] Auto Commit is now: " + listenerProperties.isAutoCommitEnabled()); + break; } - //shutdown - alExit(); + // show current eax values + case 's' : { + System.out.println(bufferProperties); + System.out.println(listenerProperties); + break; + } - System.out.println("test done."); - } + // load current eax values + case 'l' : { + bufferProperties.loadEAXValues(); + listenerProperties.loadEAXValues(); + break; + } + + // reset to default values + case 'r' : { + bufferProperties.reset(); + listenerProperties.reset(); + break; + } + + // quit demo + case 'q' : { + running = false; + break; + } + } + } while (running); + } + + private void printMenu() { + System.out.println(""); + System.out.println("EAXTest menu, please select an option from the following list:"); + System.out.println("1: Play looping sound"); + System.out.println("2: Stop looping sound"); + System.out.println("3: Add reverberation effect"); + System.out.println("4: Remove reverberation effect"); + System.out.println("5: Add occlusion effect"); + System.out.println("6: Remove occlusion effect"); + System.out.println("7: Add obstruction effect"); + System.out.println("8: Remove obstruction effect"); + + System.out.println("C: Commit current eax values"); + System.out.println("L: Load current values"); + System.out.println("T: Toggle autocomit"); + System.out.println("R: Reset to inital values"); + System.out.println("S: Show current values"); - /** - * main entry point - * - * @param args String array containing arguments - */ - public static void main(String[] args) { - EAXTest eaxTest = new EAXTest(); - eaxTest.execute(args); + System.out.println("Q: Quit demo"); + System.out.print("Input: "); + } + + private char readInput() { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + try { + return br.readLine().toLowerCase().charAt(0); + } catch (IOException ioe) { + return 'q'; } + } + + /** + * main entry point + * + * @param args String array containing arguments + */ + public static void main(String[] args) { + EAXTest eaxTest = new EAXTest(); + eaxTest.execute(args); + } } \ No newline at end of file diff --git a/src/java/org/lwjgl/test/openal/MovingSoundTest.java b/src/java/org/lwjgl/test/openal/MovingSoundTest.java index e5d751b7..570a25ee 100644 --- a/src/java/org/lwjgl/test/openal/MovingSoundTest.java +++ b/src/java/org/lwjgl/test/openal/MovingSoundTest.java @@ -185,10 +185,8 @@ public class MovingSoundTest extends BasicTest { if(Keyboard.isKeyDown(Keyboard.KEY_E)) { if(eaxApplied) { eaxListenerProp.setEnvironment(EAX.EAX_ENVIRONMENT_GENERIC); - eaxListenerProp.eaxSet(EAXListenerProperties.EAXLISTENER_ENVIRONMENT, 0); } else { eaxListenerProp.setEnvironment(EAX.EAX_ENVIRONMENT_HANGAR); - eaxListenerProp.eaxSet(EAXListenerProperties.EAXLISTENER_ENVIRONMENT, 0); } eaxApplied = !eaxApplied; } diff --git a/src/native/common/extal.h b/src/native/common/extal.h index 89f72c7b..9a3a2d0c 100644 --- a/src/native/common/extal.h +++ b/src/native/common/extal.h @@ -128,17 +128,12 @@ typedef void ALCvoid; #endif #ifdef _WIN32 -DEFINE_GUID(DSPROPSETID_EAX20_ListenerProperties, - 0x306a6a8, - 0xb224, - 0x11d2, - 0x99, 0xe5, 0x0, 0x0, 0xe8, 0xd8, 0xc7, 0x22); +// EAX 2.0 GUIDs +const GUID DSPROPSETID_EAX20_ListenerProperties + = { 0x306a6a8, 0xb224, 0x11d2, { 0x99, 0xe5, 0x0, 0x0, 0xe8, 0xd8, 0xc7, 0x22 } }; -DEFINE_GUID(DSPROPSETID_EAX20_BufferProperties, - 0x306a6a7, - 0xb224, - 0x11d2, - 0x99, 0xe5, 0x0, 0x0, 0xe8, 0xd8, 0xc7, 0x22); +const GUID DSPROPSETID_EAX20_BufferProperties + = { 0x306a6a7, 0xb224, 0x11d2, {0x99, 0xe5, 0x0, 0x0, 0xe8, 0xd8, 0xc7, 0x22 } }; #endif #define INITGUID diff --git a/src/native/common/org_lwjgl_openal_eax_CoreEAX.cpp b/src/native/common/org_lwjgl_openal_eax_CoreEAX.cpp index 92172c8e..ae623c6f 100644 --- a/src/native/common/org_lwjgl_openal_eax_CoreEAX.cpp +++ b/src/native/common/org_lwjgl_openal_eax_CoreEAX.cpp @@ -42,26 +42,20 @@ /* OpenAL includes */ #include "checkALerror.h" +#include "common_tools.h" #include "extal.h" -/** - * Throws an OAL exception with the specified message - */ -void ThrowException(JNIEnv *env, const char* message) { - jclass cls = env->FindClass("org/lwjgl/openal/OpenALException"); - env->ThrowNew(cls, message); -} - /* * Determines available EAX extensions */ JNIEXPORT void JNICALL Java_org_lwjgl_openal_eax_CoreEAX_determineAvailableExtensions (JNIEnv *env, jclass clazz) { #ifdef _WIN32 + bool EAXSupported = false; //check that we have a current context if(alcGetCurrentContext() == NULL) { - ThrowException(env, "Unable to determine EAX Extensions: No current context"); + throwOpenALException(env, "Unable to determine EAX Extensions: No current context"); } //check for extension, and assign if available @@ -73,25 +67,10 @@ JNIEXPORT void JNICALL Java_org_lwjgl_openal_eax_CoreEAX_determineAvailableExten //throw exception if no EAX support if(EAXSupported != true) { - ThrowException(env, "Unable to determine EAX Extensions"); + throwOpenALException(env, "Unable to determine EAX Extensions"); } #else - ThrowException(env, "EAX extensions not supported"); -#endif -} - -JNIEXPORT void JNICALL Java_org_lwjgl_openal_eax_CoreEAX_setGUID (JNIEnv *env, jclass clazz) { -#ifdef _WIN32 - //get class/fields - jclass eax_class = env->FindClass("org/lwjgl/openal/eax/CoreEAX"); - jfieldID eaxBuffer_field = env->GetStaticFieldID(eax_class, "BUFFER_GUID", "I"); - jfieldID eaxListener_field = env->GetStaticFieldID(eax_class, "LISTENER_GUID", "I"); - - //set fields - env->SetStaticIntField(eax_class, eaxBuffer_field, (jint) &DSPROPSETID_EAX20_BufferProperties); - env->SetStaticIntField(eax_class, eaxListener_field, (jint) &DSPROPSETID_EAX20_ListenerProperties); -#else - ThrowException(env, "EAX extensions not supported"); + throwOpenALException(env, "EAX extensions not supported"); #endif } @@ -102,18 +81,20 @@ JNIEXPORT void JNICALL Java_org_lwjgl_openal_eax_CoreEAX_setGUID (JNIEnv *env, j * ALenum EAXGet(const struct _GUID *propertySetID,ALuint property,ALuint source,ALvoid * *value,ALuint size); */ -JNIEXPORT jint JNICALL Java_org_lwjgl_openal_eax_CoreEAX_eaxGet (JNIEnv *env, jclass clazz, jint propertySetID, jint property, jint source, jobject value, jint size) { +JNIEXPORT jint JNICALL Java_org_lwjgl_openal_eax_CoreEAX_neaxGet (JNIEnv *env, jclass clazz, jint propertySetID, jint property, jint source, jobject value, jint offset, jint size) { #ifdef _WIN32 - /* - jint result = (jint) eaxGet((const struct _GUID*)propertySetID, (ALuint) property, (ALuint) source, (ALvoid*) env->GetDirectBufferAddress(value), (ALuint) size); - CHECK_AL_ERROR + jint result = 0; + // determine buffer or listener + if (propertySetID == org_lwjgl_openal_eax_CoreEAX_BUFFER_GUID) { + result = (jint) eaxGet(&DSPROPSETID_EAX20_BufferProperties, (ALuint) property, (ALuint) source, (ALvoid*) (offset + (const char*) env->GetDirectBufferAddress(value)), (ALuint) size); + } else if (propertySetID == org_lwjgl_openal_eax_CoreEAX_LISTENER_GUID) { + result = (jint) eaxGet(&DSPROPSETID_EAX20_ListenerProperties, (ALuint) property, (ALuint) source, (ALvoid*) (offset + (const char*) env->GetDirectBufferAddress(value)), (ALuint) size); + } + CHECK_AL_ERROR return result; - */ - printf("Method currently deactivated. Fixed soon\n"); - return -1; #else - ThrowException(env, "EAX extensions not supported"); + throwOpenALException(env, "EAX extensions not supported"); return 0; #endif } @@ -125,18 +106,20 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_openal_eax_CoreEAX_eaxGet (JNIEnv *env, jc * ALenum EAXSet(const struct _GUID *propertySetID,ALuint property,ALuint source,ALvoid * *value,ALuint size); */ -JNIEXPORT jint JNICALL Java_org_lwjgl_openal_eax_CoreEAX_eaxSet (JNIEnv *env, jclass clazz, jint propertySetID, jint property, jint source, jobject value, jint size) { +JNIEXPORT jint JNICALL Java_org_lwjgl_openal_eax_CoreEAX_neaxSet (JNIEnv *env, jclass clazz, jint propertySetID, jint property, jint source, jobject value, jint offset, jint size) { #ifdef _WIN32 - /* - jint result = (jint) eaxSet((const struct _GUID*)propertySetID, (ALuint) property, (ALuint) source, env->GetDirectBufferAddress(value), (ALuint) size); - CHECK_AL_ERROR - + jint result = 0; + + // determine buffer or listener + if (propertySetID == org_lwjgl_openal_eax_CoreEAX_BUFFER_GUID) { + result = (jint) eaxSet(&DSPROPSETID_EAX20_BufferProperties, (ALuint) (property), source, (ALvoid*) (offset + (const char*) env->GetDirectBufferAddress(value)), (ALuint) size); + } else if (propertySetID == org_lwjgl_openal_eax_CoreEAX_LISTENER_GUID) { + result = (jint) eaxSet(&DSPROPSETID_EAX20_ListenerProperties, (ALuint) (property), source, (ALvoid*) (offset + (const char*) env->GetDirectBufferAddress(value)), (ALuint) size); + } + CHECK_AL_ERROR return result; - */ - printf("Method currently deactivated. Fixed soon\n"); - return -1; #else - ThrowException(env, "EAX extensions not supported"); + throwOpenALException(env, "EAX extensions not supported"); return 0; #endif } diff --git a/src/native/common/org_lwjgl_openal_eax_CoreEAX.h b/src/native/common/org_lwjgl_openal_eax_CoreEAX.h index d25c5b48..7c49338a 100644 --- a/src/native/common/org_lwjgl_openal_eax_CoreEAX.h +++ b/src/native/common/org_lwjgl_openal_eax_CoreEAX.h @@ -8,8 +8,10 @@ extern "C" { #endif /* Inaccessible static: created */ -/* Inaccessible static: BUFFER_GUID */ -/* Inaccessible static: LISTENER_GUID */ +#undef org_lwjgl_openal_eax_CoreEAX_BUFFER_GUID +#define org_lwjgl_openal_eax_CoreEAX_BUFFER_GUID 1L +#undef org_lwjgl_openal_eax_CoreEAX_LISTENER_GUID +#define org_lwjgl_openal_eax_CoreEAX_LISTENER_GUID 2L /* * Class: org_lwjgl_openal_eax_CoreEAX * Method: determineAvailableExtensions @@ -20,27 +22,19 @@ JNIEXPORT void JNICALL Java_org_lwjgl_openal_eax_CoreEAX_determineAvailableExten /* * Class: org_lwjgl_openal_eax_CoreEAX - * Method: setGUID - * Signature: ()V + * Method: neaxGet + * Signature: (IIILjava/nio/Buffer;II)I */ -JNIEXPORT void JNICALL Java_org_lwjgl_openal_eax_CoreEAX_setGUID - (JNIEnv *, jclass); +JNIEXPORT jint JNICALL Java_org_lwjgl_openal_eax_CoreEAX_neaxGet + (JNIEnv *, jclass, jint, jint, jint, jobject, jint, jint); /* * Class: org_lwjgl_openal_eax_CoreEAX - * Method: eaxGet - * Signature: (IIILjava/nio/Buffer;I)I + * Method: neaxSet + * Signature: (IIILjava/nio/Buffer;II)I */ -JNIEXPORT jint JNICALL Java_org_lwjgl_openal_eax_CoreEAX_eaxGet - (JNIEnv *, jclass, jint, jint, jint, jobject, jint); - -/* - * Class: org_lwjgl_openal_eax_CoreEAX - * Method: eaxSet - * Signature: (IIILjava/nio/Buffer;I)I - */ -JNIEXPORT jint JNICALL Java_org_lwjgl_openal_eax_CoreEAX_eaxSet - (JNIEnv *, jclass, jint, jint, jint, jobject, jint); +JNIEXPORT jint JNICALL Java_org_lwjgl_openal_eax_CoreEAX_neaxSet + (JNIEnv *, jclass, jint, jint, jint, jobject, jint, jint); #ifdef __cplusplus }