-
-
Save code-disaster/a14993f38966ba06fa4f579820f89d43 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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