|
|
|
@ -77,6 +77,10 @@ public class JoalAudioRenderer implements AudioRenderer, Runnable { |
|
|
|
|
|
|
|
|
|
private ALC alc; |
|
|
|
|
private AL al; |
|
|
|
|
|
|
|
|
|
static { |
|
|
|
|
ALut.alutInit(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public JoalAudioRenderer() { |
|
|
|
|
} |
|
|
|
@ -139,10 +143,9 @@ public class JoalAudioRenderer implements AudioRenderer, Runnable { |
|
|
|
|
|
|
|
|
|
public void initInThread() { |
|
|
|
|
try { |
|
|
|
|
ALut.alutInit(); |
|
|
|
|
alc = ALFactory.getALC(); |
|
|
|
|
al = ALFactory.getAL(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Get handle to default device.
|
|
|
|
|
ALCdevice device = alc.alcOpenDevice(null); |
|
|
|
|
if (device == null) { |
|
|
|
@ -159,7 +162,7 @@ public class JoalAudioRenderer implements AudioRenderer, Runnable { |
|
|
|
|
logger.log(Level.FINER, "Audio Vendor: {0}", al.alGetString(ALConstants.AL_VENDOR)); |
|
|
|
|
logger.log(Level.FINER, "Audio Renderer: {0}", al.alGetString(ALConstants.AL_RENDERER)); |
|
|
|
|
logger.log(Level.FINER, "Audio Version: {0}", al.alGetString(ALConstants.AL_VERSION)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Create audio context.
|
|
|
|
|
ALCcontext context = alc.alcCreateContext(device, null); |
|
|
|
|
if (context == null) { |
|
|
|
@ -174,57 +177,57 @@ public class JoalAudioRenderer implements AudioRenderer, Runnable { |
|
|
|
|
throw new ALException("Error making OpenAL context current"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Find maximum # of sources supported by this implementation
|
|
|
|
|
ArrayList<Integer> channelList = new ArrayList<Integer>(); |
|
|
|
|
IntBuffer channelsNioBuffer = Buffers.newDirectIntBuffer(MAX_NUM_CHANNELS); |
|
|
|
|
al.alGenSources(MAX_NUM_CHANNELS, channelsNioBuffer); |
|
|
|
|
for (int i = 0; i < MAX_NUM_CHANNELS; i++) { |
|
|
|
|
int chan = channelsNioBuffer.get(i); |
|
|
|
|
if (chan != 0) { |
|
|
|
|
channelList.add(chan); |
|
|
|
|
// Find maximum # of sources supported by this implementation
|
|
|
|
|
ArrayList<Integer> channelList = new ArrayList<Integer>(); |
|
|
|
|
IntBuffer channelsNioBuffer = Buffers.newDirectIntBuffer(MAX_NUM_CHANNELS); |
|
|
|
|
al.alGenSources(MAX_NUM_CHANNELS, channelsNioBuffer); |
|
|
|
|
for (int i = 0; i < MAX_NUM_CHANNELS; i++) { |
|
|
|
|
int chan = channelsNioBuffer.get(i); |
|
|
|
|
if (chan != 0) { |
|
|
|
|
channelList.add(chan); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
channels = new int[channelList.size()]; |
|
|
|
|
for (int i = 0; i < channels.length; i++) { |
|
|
|
|
channels[i] = channelList.get(i); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ib = BufferUtils.createIntBuffer(channels.length); |
|
|
|
|
chanSrcs = new AudioNode[channels.length]; |
|
|
|
|
|
|
|
|
|
logger.log(Level.INFO, "AudioRenderer supports {0} channels", channels.length); |
|
|
|
|
|
|
|
|
|
supportEfx = alc.alcIsExtensionPresent(device, "ALC_EXT_EFX"); |
|
|
|
|
if (supportEfx) { |
|
|
|
|
ib.position(0).limit(1); |
|
|
|
|
alc.alcGetIntegerv(device, AL.ALC_EFX_MAJOR_VERSION, 1, ib); |
|
|
|
|
int major = ib.get(0); |
|
|
|
|
ib.position(0).limit(1); |
|
|
|
|
alc.alcGetIntegerv(device, AL.ALC_EFX_MINOR_VERSION, 1, ib); |
|
|
|
|
int minor = ib.get(0); |
|
|
|
|
logger.log(Level.INFO, "Audio effect extension version: {0}.{1}", new Object[]{major, minor}); |
|
|
|
|
|
|
|
|
|
alc.alcGetIntegerv(device, AL.ALC_MAX_AUXILIARY_SENDS, 1, ib); |
|
|
|
|
auxSends = ib.get(0); |
|
|
|
|
logger.log(Level.INFO, "Audio max auxilary sends: {0}", auxSends); |
|
|
|
|
|
|
|
|
|
// create slot
|
|
|
|
|
ib.position(0).limit(1); |
|
|
|
|
al.alGenAuxiliaryEffectSlots(1, ib); |
|
|
|
|
reverbFxSlot = ib.get(0); |
|
|
|
|
|
|
|
|
|
// create effect
|
|
|
|
|
ib.position(0).limit(1); |
|
|
|
|
al.alGenEffects(1, ib); |
|
|
|
|
reverbFx = ib.get(0); |
|
|
|
|
al.alEffecti(reverbFx, AL.AL_EFFECT_TYPE, AL.AL_EFFECT_REVERB); |
|
|
|
|
channels = new int[channelList.size()]; |
|
|
|
|
for (int i = 0; i < channels.length; i++) { |
|
|
|
|
channels[i] = channelList.get(i); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// attach reverb effect to effect slot
|
|
|
|
|
al.alAuxiliaryEffectSloti(reverbFxSlot, AL.AL_EFFECTSLOT_EFFECT, reverbFx); |
|
|
|
|
} else { |
|
|
|
|
logger.log(Level.WARNING, "OpenAL EFX not available! Audio effects won't work."); |
|
|
|
|
} |
|
|
|
|
ib = BufferUtils.createIntBuffer(channels.length); |
|
|
|
|
chanSrcs = new AudioNode[channels.length]; |
|
|
|
|
|
|
|
|
|
logger.log(Level.INFO, "AudioRenderer supports {0} channels", channels.length); |
|
|
|
|
|
|
|
|
|
supportEfx = alc.alcIsExtensionPresent(device, "ALC_EXT_EFX"); |
|
|
|
|
if (supportEfx) { |
|
|
|
|
ib.position(0).limit(1); |
|
|
|
|
alc.alcGetIntegerv(device, AL.ALC_EFX_MAJOR_VERSION, 1, ib); |
|
|
|
|
int major = ib.get(0); |
|
|
|
|
ib.position(0).limit(1); |
|
|
|
|
alc.alcGetIntegerv(device, AL.ALC_EFX_MINOR_VERSION, 1, ib); |
|
|
|
|
int minor = ib.get(0); |
|
|
|
|
logger.log(Level.INFO, "Audio effect extension version: {0}.{1}", new Object[]{major, minor}); |
|
|
|
|
|
|
|
|
|
alc.alcGetIntegerv(device, AL.ALC_MAX_AUXILIARY_SENDS, 1, ib); |
|
|
|
|
auxSends = ib.get(0); |
|
|
|
|
logger.log(Level.INFO, "Audio max auxilary sends: {0}", auxSends); |
|
|
|
|
|
|
|
|
|
// create slot
|
|
|
|
|
ib.position(0).limit(1); |
|
|
|
|
al.alGenAuxiliaryEffectSlots(1, ib); |
|
|
|
|
reverbFxSlot = ib.get(0); |
|
|
|
|
|
|
|
|
|
// create effect
|
|
|
|
|
ib.position(0).limit(1); |
|
|
|
|
al.alGenEffects(1, ib); |
|
|
|
|
reverbFx = ib.get(0); |
|
|
|
|
al.alEffecti(reverbFx, AL.AL_EFFECT_TYPE, AL.AL_EFFECT_REVERB); |
|
|
|
|
|
|
|
|
|
// attach reverb effect to effect slot
|
|
|
|
|
al.alAuxiliaryEffectSloti(reverbFxSlot, AL.AL_EFFECTSLOT_EFFECT, reverbFx); |
|
|
|
|
} else { |
|
|
|
|
logger.log(Level.WARNING, "OpenAL EFX not available! Audio effects won't work."); |
|
|
|
|
} |
|
|
|
|
} catch (ALException ex) { |
|
|
|
|
logger.log(Level.SEVERE, "Failed to load audio library", ex); |
|
|
|
|
audioDisabled = true; |
|
|
|
|