lwjgl/src/java/org/lwjgl/openal/EFXUtil.java

229 lines
9.3 KiB
Java

/*
* Copyright (c) 2002-2010 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.lwjgl.openal;
import static org.lwjgl.openal.AL10.*;
import static org.lwjgl.openal.EFX10.*;
/**
* Utility class for the OpenAL extension ALC_EXT_EFX. Provides functions to check for the extension
* and support of various effects and filters.
* <p>
* Currently supports ALC_EXT_EFX version 1.0 effects and filters.
*
* @author Ciardhubh <ciardhubh[at]ciardhubh.de>
* @version $Revision$
* $Id$
*/
public final class EFXUtil {
/** Constant for testSupportGeneric to check an effect. */
private static final int EFFECT = 1111;
/** Constant for testSupportGeneric to check a filter. */
private static final int FILTER = 2222;
/** Utility class, hidden contructor. */
private EFXUtil() {
}
/**
* Checks if OpenAL implementation is loaded and supports ALC_EXT_EFX.
*
* @return True if ALC_EXT_EFX is supported, false if not.
* @throws OpenALException If OpenAL has not been created yet.
*/
public static boolean isEfxSupported() {
if (!AL.isCreated()) {
throw new OpenALException("OpenAL has not been created.");
}
return ALC10.alcIsExtensionPresent(AL.getDevice(), ALC_EXT_EFX_NAME);
}
/**
* Tests OpenAL to see whether the given effect type is supported. This is done by creating an
* effect of the given type. If creation succeeds the effect is supported.
*
* @param effectType Type of effect whose support is to be tested, e.g. AL_EFFECT_REVERB.
* @return True if it is supported, false if not.
* @throws OpenALException If the request fails due to an AL_OUT_OF_MEMORY error or OpenAL has
* not been created yet.
* @throws IllegalArgumentException effectType is not a valid effect type.
*/
public static boolean isEffectSupported(final int effectType) {
// Make sure type is a real effect.
switch (effectType) {
case AL_EFFECT_NULL:
case AL_EFFECT_EAXREVERB:
case AL_EFFECT_REVERB:
case AL_EFFECT_CHORUS:
case AL_EFFECT_DISTORTION:
case AL_EFFECT_ECHO:
case AL_EFFECT_FLANGER:
case AL_EFFECT_FREQUENCY_SHIFTER:
case AL_EFFECT_VOCAL_MORPHER:
case AL_EFFECT_PITCH_SHIFTER:
case AL_EFFECT_RING_MODULATOR:
case AL_EFFECT_AUTOWAH:
case AL_EFFECT_COMPRESSOR:
case AL_EFFECT_EQUALIZER:
break;
default:
throw new IllegalArgumentException("Unknown or invalid effect type: " + effectType);
}
return testSupportGeneric(EFFECT, effectType);
}
/**
* Tests OpenAL to see whether the given filter type is supported. This is done by creating a
* filter of the given type. If creation succeeds the filter is supported.
*
* @param filterType Type of filter whose support is to be tested, e.g. AL_FILTER_LOWPASS.
* @return True if it is supported, false if not.
* @throws OpenALException If the request fails due to an AL_OUT_OF_MEMORY error or OpenAL has
* not been created yet.
* @throws IllegalArgumentException filterType is not a valid filter type.
*/
public static boolean isFilterSupported(final int filterType) {
// Make sure type is a real filter.
switch (filterType) {
case AL_FILTER_NULL:
case AL_FILTER_LOWPASS:
case AL_FILTER_HIGHPASS:
case AL_FILTER_BANDPASS:
break;
default:
throw new IllegalArgumentException("Unknown or invalid filter type: " + filterType);
}
return testSupportGeneric(FILTER, filterType);
}
/**
* Generic test function to see if an EFX object supports a given kind of type. Works for
* effects and filters.
*
* @param objectType Type of object to test. Must be either EFXUtil.EFFECT or EFXUtil.FILTER.
* @param typeValue OpenAL type the object should be tested for support, e.g. AL_FILTER_LOWPASS
* or AL_EFFECT_REVERB.
* @return True if object supports typeValue, false else.
*/
private static boolean testSupportGeneric(final int objectType, final int typeValue) {
// Check for supported objectType.
switch (objectType) {
case EFFECT:
case FILTER:
break;
default:
throw new IllegalArgumentException("Invalid objectType: " + objectType);
}
boolean supported = false;
if (isEfxSupported()) {
// Try to create object in order to check AL's response.
alGetError();
int genError;
int testObject = 0;
try {
switch (objectType) { // Create object based on type
case EFFECT:
testObject = alGenEffects();
break;
case FILTER:
testObject = alGenFilters();
break;
default:
throw new IllegalArgumentException("Invalid objectType: " + objectType);
}
genError = alGetError();
} catch (final OpenALException debugBuildException) {
// Hack because OpenALException hides the original error code (short of parsing the
// error message String which would break if it gets changed).
if (debugBuildException.getMessage().contains("AL_OUT_OF_MEMORY")) {
genError = AL_OUT_OF_MEMORY;
} else {
genError = AL_INVALID_OPERATION;
}
}
if (genError == AL_NO_ERROR) {
// Successfully created, now try to set type.
alGetError();
int setError;
try {
switch (objectType) { // Set based on object type
case EFFECT:
alEffecti(testObject, AL_EFFECT_TYPE, typeValue);
break;
case FILTER:
alFilteri(testObject, AL_FILTER_TYPE, typeValue);
break;
default:
throw new IllegalArgumentException("Invalid objectType: " + objectType);
}
setError = alGetError();
} catch (final OpenALException debugBuildException) {
// Hack because OpenALException hides the original error code (short of parsing
// the error message String which would break when it gets changed).
setError = AL_INVALID_VALUE;
}
if (setError == AL_NO_ERROR) {
supported = true;
}
// Cleanup
try {
switch (objectType) { // Set based on object type
case EFFECT:
alDeleteEffects(testObject);
break;
case FILTER:
alDeleteFilters(testObject);
break;
default:
throw new IllegalArgumentException("Invalid objectType: " + objectType);
}
} catch (final OpenALException debugBuildException) {
// Don't care about cleanup errors.
}
} else if (genError == AL_OUT_OF_MEMORY) {
throw new OpenALException(genError);
}
}
return supported;
}
}