Skip to content

Instantly share code, notes, and snippets.

@code-disaster
Created February 21, 2019 09:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save code-disaster/a14993f38966ba06fa4f579820f89d43 to your computer and use it in GitHub Desktop.
Save code-disaster/a14993f38966ba06fa4f579820f89d43 to your computer and use it in GitHub Desktop.
import static org.lwjgl.openal.ALC10.*;
import static org.lwjgl.openal.ALC11.*;
import static org.lwjgl.openal.EXTEfx.ALC_MAX_AUXILIARY_SENDS;
import static org.lwjgl.system.MemoryUtil.NULL;
public class LwjglAudio extends Audio {
long device;
ALCCapabilities deviceCaps;
private long context;
private ALCapabilities capabilities;
public LwjglAudio(AudioAdapter adapter) {
super(adapter);
LwjglAudioFilterReverb.setup();
}
@Override
public Sample createSample(File file) throws IOException {
return new WavSample(file);
}
@Override
public Music createStream(File file) throws IOException {
return new VorbisMusic(file);
}
@Override
public AudioMixer createMixer(int maxChannels) {
return new LwjglAudioMixer(this, maxChannels);
}
@Override
protected void createDeviceAndContext() {
try (MemoryStack stack = MemoryStack.stackPush()) {
int retries = 5;
while (retries > 0) {
if (device == NULL) {
device = ALC10.alcOpenDevice((ByteBuffer) null);
}
if (device != NULL) {
deviceCaps = ALC.createCapabilities(device);
IntBuffer attribs = stack.callocInt(4);
if (deviceCaps.ALC_EXT_EFX) {
attribs.put(ALC_MAX_AUXILIARY_SENDS);
attribs.put(4);
}
context = alcCreateContext(device, attribs);
if (context != NULL) {
break;
}
}
--retries;
if (retries > 0) {
// wait a short while, try again
if (device == NULL) {
log.warn("failed to open AL device, trying again ({} more times)", retries);
} else {
log.warn("failed to create AL context, trying again ({} more times)", retries);
}
try {
Thread.sleep(500);
} catch (InterruptedException ignore) {
// ...
}
}
}
}
if (device == NULL) {
throw new RtLibRuntimeException(log, "failed to open AL device");
}
if (!deviceCaps.OpenALC10) {
throw new RtLibRuntimeException(log, "device does not support OpenALC10");
}
if (!deviceCaps.ALC_EXT_thread_local_context) {
throw new RtLibRuntimeException(log, "device does not support ALC_EXT_thread_local_context");
}
if (!deviceCaps.ALC_EXT_EFX) {
log.warn("device does not support ALC_EXT_EFX");
}
if (context == NULL) {
throw new RtLibRuntimeException(log, "failed to create AL context");
}
alcMakeContextCurrent(context);
EXTThreadLocalContext.alcSetThreadContext(context);
capabilities = AL.createCapabilities(deviceCaps);
AL.setCurrentThread(capabilities);
printInfo(log);
}
@Override
protected void shutdownDeviceAndContext() {
if (context != 0L) {
alcMakeContextCurrent(NULL);
EXTThreadLocalContext.alcSetThreadContext(NULL);
alcDestroyContext(context);
}
if (device != 0L) {
alcCloseDevice(device);
}
}
private void checkALCError(long device) {
int err = alcGetError(device);
if (err != ALC_NO_ERROR) {
throw new RtLibRuntimeException(log, alcGetString(device, err));
}
}
private void printInfo(Logger log) {
log.debug("OpenAL device caps:");
log.debug(" OpenALC10: {}", deviceCaps.OpenALC10);
log.debug(" OpenALC11: {}", deviceCaps.OpenALC11);
log.debug(" ALC_EXT_EFX: {}", deviceCaps.ALC_EXT_EFX);
if (deviceCaps.OpenALC11) {
List<String> devices = ALUtil.getStringList(NULL, ALC_ALL_DEVICES_SPECIFIER);
if (devices != null) {
log.debug("OpenAL devices:");
for (int i = 0; i < devices.size(); i++) {
log.debug(" {}: {}", i, devices.get(i));
}
} else {
checkALCError(NULL);
}
}
String defaultDeviceSpecifier = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
log.debug(" default: {}", defaultDeviceSpecifier != null ? defaultDeviceSpecifier : "unknown");
log.debug("OpenAL device features:");
log.debug(" ALC_FREQUENCY: {} Hz", alcGetInteger(device, ALC_FREQUENCY));
log.debug(" ALC_REFRESH: {} Hz", alcGetInteger(device, ALC_REFRESH));
log.debug(" ALC_SYNC: {}", alcGetInteger(device, ALC_SYNC) == ALC_TRUE);
log.debug(" ALC_MONO_SOURCES: {}", alcGetInteger(device, ALC_MONO_SOURCES));
log.debug(" ALC_STEREO_SOURCES: {}", alcGetInteger(device, ALC_STEREO_SOURCES));
if (deviceCaps.ALC_EXT_EFX) {
log.debug("ALC_EXT_EFX features:");
log.debug(" ALC_MAX_AUXILIARY_SENDS: {}", alcGetInteger(device, ALC_MAX_AUXILIARY_SENDS));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment