* Fixed issue where setReverbEnabled(false) after setPositional(false) did not actually remove reverb. Reverb is now removed automatically when setPositional(false) per contract of the method.
* Formatted the classes. git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9569 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
5497fcc7e6
commit
9d95528e21
@ -442,9 +442,10 @@ public class AudioNode extends Node {
|
||||
*/
|
||||
public void setReverbEnabled(boolean reverbEnabled) {
|
||||
this.reverbEnabled = reverbEnabled;
|
||||
if (channel >= 0)
|
||||
if (channel >= 0) {
|
||||
getRenderer().updateSourceParam(this, AudioParam.ReverbEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Filter for the reverberations of this audio node.
|
||||
@ -642,9 +643,10 @@ public class AudioNode extends Node {
|
||||
*/
|
||||
public void setPositional(boolean positional) {
|
||||
this.positional = positional;
|
||||
if (channel >= 0)
|
||||
if (channel >= 0) {
|
||||
getRenderer().updateSourceParam(this, AudioParam.IsPositional);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateGeometricState(){
|
||||
|
@ -29,11 +29,10 @@
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package com.jme3.audio.lwjgl;
|
||||
|
||||
import com.jme3.audio.*;
|
||||
import com.jme3.audio.AudioNode.Status;
|
||||
import com.jme3.audio.*;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.util.BufferUtils;
|
||||
import com.jme3.util.NativeObjectManager;
|
||||
@ -45,42 +44,34 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.lwjgl.LWJGLException;
|
||||
import org.lwjgl.openal.*;
|
||||
import static org.lwjgl.openal.AL10.*;
|
||||
import org.lwjgl.openal.*;
|
||||
|
||||
public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(LwjglAudioRenderer.class.getName());
|
||||
|
||||
private final NativeObjectManager objManager = new NativeObjectManager();
|
||||
|
||||
// When multiplied by STREAMING_BUFFER_COUNT, will equal 44100 * 2 * 2
|
||||
// which is exactly 1 second of audio.
|
||||
private static final int BUFFER_SIZE = 35280;
|
||||
private static final int STREAMING_BUFFER_COUNT = 5;
|
||||
|
||||
private final static int MAX_NUM_CHANNELS = 64;
|
||||
private IntBuffer ib = BufferUtils.createIntBuffer(1);
|
||||
private final FloatBuffer fb = BufferUtils.createVector3Buffer(2);
|
||||
private final ByteBuffer nativeBuf = BufferUtils.createByteBuffer(BUFFER_SIZE);
|
||||
private final byte[] arrayBuf = new byte[BUFFER_SIZE];
|
||||
|
||||
private int[] channels;
|
||||
private AudioNode[] chanSrcs;
|
||||
private int nextChan = 0;
|
||||
private ArrayList<Integer> freeChans = new ArrayList<Integer>();
|
||||
|
||||
private Listener listener;
|
||||
private boolean audioDisabled = false;
|
||||
|
||||
private boolean supportEfx = false;
|
||||
private int auxSends = 0;
|
||||
private int reverbFx = -1;
|
||||
private int reverbFxSlot = -1;
|
||||
|
||||
// Update audio 20 times per second
|
||||
private static final float UPDATE_RATE = 0.05f;
|
||||
|
||||
private final Thread audioThread = new Thread(this, "jME3 Audio Thread");
|
||||
private final AtomicBoolean threadLock = new AtomicBoolean(false);
|
||||
|
||||
@ -98,9 +89,10 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
||||
}
|
||||
|
||||
private void checkDead() {
|
||||
if (audioThread.getState() == Thread.State.TERMINATED)
|
||||
if (audioThread.getState() == Thread.State.TERMINATED) {
|
||||
throw new IllegalStateException("Audio thread is terminated");
|
||||
}
|
||||
}
|
||||
|
||||
public void run() {
|
||||
initInThread();
|
||||
@ -110,11 +102,13 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
||||
}
|
||||
|
||||
long updateRateNanos = (long) (UPDATE_RATE * 1000000000);
|
||||
mainloop: while (true){
|
||||
mainloop:
|
||||
while (true) {
|
||||
long startTime = System.nanoTime();
|
||||
|
||||
if (Thread.interrupted())
|
||||
if (Thread.interrupted()) {
|
||||
break;
|
||||
}
|
||||
|
||||
synchronized (threadLock) {
|
||||
updateInThread(UPDATE_RATE);
|
||||
@ -281,8 +275,8 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
||||
EFX10.alFilterf(id, EFX10.AL_LOWPASS_GAIN, lpf.getVolume());
|
||||
EFX10.alFilterf(id, EFX10.AL_LOWPASS_GAINHF, lpf.getHighFreqVolume());
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Filter type unsupported: "+
|
||||
f.getClass().getName());
|
||||
throw new UnsupportedOperationException("Filter type unsupported: "
|
||||
+ f.getClass().getName());
|
||||
}
|
||||
|
||||
f.clearUpdateNeeded();
|
||||
@ -297,8 +291,9 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
}
|
||||
if (audioDisabled)
|
||||
if (audioDisabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
// There is a race condition in AudioNode that can
|
||||
// cause this to be called for a node that has been
|
||||
@ -309,42 +304,48 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
||||
// updateSourceParam() (because the audio stopped playing
|
||||
// on its own right as the volume was set). In this case,
|
||||
// it should be safe to just ignore the update
|
||||
if (src.getChannel() < 0)
|
||||
if (src.getChannel() < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
assert src.getChannel() >= 0;
|
||||
|
||||
int id = channels[src.getChannel()];
|
||||
switch (param) {
|
||||
case Position:
|
||||
if (!src.isPositional())
|
||||
if (!src.isPositional()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3f pos = src.getWorldTranslation();
|
||||
alSource3f(id, AL_POSITION, pos.x, pos.y, pos.z);
|
||||
break;
|
||||
case Velocity:
|
||||
if (!src.isPositional())
|
||||
if (!src.isPositional()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3f vel = src.getVelocity();
|
||||
alSource3f(id, AL_VELOCITY, vel.x, vel.y, vel.z);
|
||||
break;
|
||||
case MaxDistance:
|
||||
if (!src.isPositional())
|
||||
if (!src.isPositional()) {
|
||||
return;
|
||||
}
|
||||
|
||||
alSourcef(id, AL_MAX_DISTANCE, src.getMaxDistance());
|
||||
break;
|
||||
case RefDistance:
|
||||
if (!src.isPositional())
|
||||
if (!src.isPositional()) {
|
||||
return;
|
||||
}
|
||||
|
||||
alSourcef(id, AL_REFERENCE_DISTANCE, src.getRefDistance());
|
||||
break;
|
||||
case ReverbFilter:
|
||||
if (!supportEfx || !src.isPositional() || !src.isReverbEnabled())
|
||||
if (!supportEfx || !src.isPositional() || !src.isReverbEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int filter = EFX10.AL_FILTER_NULL;
|
||||
if (src.getReverbFilter() != null) {
|
||||
@ -357,8 +358,9 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
||||
AL11.alSource3i(id, EFX10.AL_AUXILIARY_SEND_FILTER, reverbFxSlot, 0, filter);
|
||||
break;
|
||||
case ReverbEnabled:
|
||||
if (!supportEfx || !src.isPositional())
|
||||
if (!supportEfx || !src.isPositional()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (src.isReverbEnabled()) {
|
||||
updateSourceParam(src, AudioParam.ReverbFilter);
|
||||
@ -368,10 +370,13 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
||||
break;
|
||||
case IsPositional:
|
||||
if (!src.isPositional()) {
|
||||
// play in headspace
|
||||
// Play in headspace
|
||||
alSourcei(id, AL_SOURCE_RELATIVE, AL_TRUE);
|
||||
alSource3f(id, AL_POSITION, 0, 0, 0);
|
||||
alSource3f(id, AL_VELOCITY, 0, 0, 0);
|
||||
|
||||
// Disable reverb
|
||||
AL11.alSource3i(id, EFX10.AL_AUXILIARY_SEND_FILTER, 0, 0, EFX10.AL_FILTER_NULL);
|
||||
} else {
|
||||
alSourcei(id, AL_SOURCE_RELATIVE, AL_FALSE);
|
||||
updateSourceParam(src, AudioParam.Position);
|
||||
@ -382,21 +387,24 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
||||
}
|
||||
break;
|
||||
case Direction:
|
||||
if (!src.isDirectional())
|
||||
if (!src.isDirectional()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3f dir = src.getDirection();
|
||||
alSource3f(id, AL_DIRECTION, dir.x, dir.y, dir.z);
|
||||
break;
|
||||
case InnerAngle:
|
||||
if (!src.isDirectional())
|
||||
if (!src.isDirectional()) {
|
||||
return;
|
||||
}
|
||||
|
||||
alSourcef(id, AL_CONE_INNER_ANGLE, src.getInnerAngle());
|
||||
break;
|
||||
case OuterAngle:
|
||||
if (!src.isDirectional())
|
||||
if (!src.isDirectional()) {
|
||||
return;
|
||||
}
|
||||
|
||||
alSourcef(id, AL_CONE_OUTER_ANGLE, src.getOuterAngle());
|
||||
break;
|
||||
@ -413,8 +421,9 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
||||
}
|
||||
break;
|
||||
case DryFilter:
|
||||
if (!supportEfx)
|
||||
if (!supportEfx) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (src.getDryFilter() != null) {
|
||||
Filter f = src.getDryFilter();
|
||||
@ -516,8 +525,9 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
}
|
||||
if (audioDisabled)
|
||||
if (audioDisabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (param) {
|
||||
case Position:
|
||||
@ -561,9 +571,9 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
||||
}
|
||||
|
||||
private int newChannel() {
|
||||
if (freeChans.size() > 0)
|
||||
if (freeChans.size() > 0) {
|
||||
return freeChans.remove(0);
|
||||
else if (nextChan < channels.length){
|
||||
} else if (nextChan < channels.length) {
|
||||
return nextChan++;
|
||||
} else {
|
||||
return -1;
|
||||
@ -587,8 +597,9 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
}
|
||||
if (audioDisabled || !supportEfx)
|
||||
if (audioDisabled || !supportEfx) {
|
||||
return;
|
||||
}
|
||||
|
||||
EFX10.alEffectf(reverbFx, EFX10.AL_REVERB_DENSITY, env.getDensity());
|
||||
EFX10.alEffectf(reverbFx, EFX10.AL_REVERB_DIFFUSION, env.getDiffusion());
|
||||
@ -622,8 +633,9 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
if(size == 0)
|
||||
if (size == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nativeBuf.clear();
|
||||
nativeBuf.put(arrayBuf, 0, size);
|
||||
@ -635,8 +647,9 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
||||
}
|
||||
|
||||
private boolean fillStreamingSource(int sourceId, AudioStream stream) {
|
||||
if (!stream.isOpen())
|
||||
if (!stream.isOpen()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean active = true;
|
||||
int processed = alGetSourcei(sourceId, AL_BUFFERS_PROCESSED);
|
||||
@ -656,8 +669,9 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
||||
alSourceQueueBuffers(sourceId, ib);
|
||||
}
|
||||
|
||||
if (!active && stream.isOpen())
|
||||
if (!active && stream.isOpen()) {
|
||||
stream.close();
|
||||
}
|
||||
|
||||
return active;
|
||||
}
|
||||
@ -724,13 +738,15 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
||||
}
|
||||
|
||||
public void updateInThread(float tpf) {
|
||||
if (audioDisabled)
|
||||
if (audioDisabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < channels.length; i++) {
|
||||
AudioNode src = chanSrcs[i];
|
||||
if (src == null)
|
||||
if (src == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int sourceId = channels[i];
|
||||
|
||||
@ -752,8 +768,9 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
||||
AudioStream stream = (AudioStream) src.getAudioData();
|
||||
if (stream.isOpen()) {
|
||||
fillStreamingSource(sourceId, stream);
|
||||
if (stopped)
|
||||
if (stopped) {
|
||||
alSourcePlay(sourceId);
|
||||
}
|
||||
} else {
|
||||
if (stopped) {
|
||||
// became inactive
|
||||
@ -797,8 +814,9 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
}
|
||||
if (audioDisabled)
|
||||
if (audioDisabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.listener != null) {
|
||||
// previous listener no longer associated with current
|
||||
@ -821,13 +839,15 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
}
|
||||
if (audioDisabled)
|
||||
if (audioDisabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (src.getAudioData() instanceof AudioStream)
|
||||
if (src.getAudioData() instanceof AudioStream) {
|
||||
throw new UnsupportedOperationException(
|
||||
"Cannot play instances " +
|
||||
"of audio streams. Use playSource() instead.");
|
||||
"Cannot play instances "
|
||||
+ "of audio streams. Use playSource() instead.");
|
||||
}
|
||||
|
||||
if (src.getAudioData().isUpdateNeeded()) {
|
||||
updateAudioData(src.getAudioData());
|
||||
@ -835,8 +855,9 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
||||
|
||||
// create a new index for an audio-channel
|
||||
int index = newChannel();
|
||||
if (index == -1)
|
||||
if (index == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
int sourceId = channels[index];
|
||||
|
||||
@ -852,7 +873,6 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void playSource(AudioNode src) {
|
||||
checkDead();
|
||||
synchronized (threadLock) {
|
||||
@ -862,8 +882,9 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
}
|
||||
if (audioDisabled)
|
||||
if (audioDisabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
//assert src.getStatus() == Status.Stopped || src.getChannel() == -1;
|
||||
|
||||
@ -881,8 +902,9 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
||||
src.setChannel(index);
|
||||
|
||||
AudioData data = src.getAudioData();
|
||||
if (data.isUpdateNeeded())
|
||||
if (data.isUpdateNeeded()) {
|
||||
updateAudioData(data);
|
||||
}
|
||||
|
||||
chanSrcs[index] = src;
|
||||
setSourceParams(channels[index], src, false);
|
||||
@ -894,7 +916,6 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void pauseSource(AudioNode src) {
|
||||
checkDead();
|
||||
synchronized (threadLock) {
|
||||
@ -904,8 +925,9 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
}
|
||||
if (audioDisabled)
|
||||
if (audioDisabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (src.getStatus() == Status.Playing) {
|
||||
assert src.getChannel() != -1;
|
||||
@ -916,7 +938,6 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void stopSource(AudioNode src) {
|
||||
synchronized (threadLock) {
|
||||
while (!threadLock.get()) {
|
||||
@ -925,8 +946,9 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
}
|
||||
if (audioDisabled)
|
||||
if (audioDisabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (src.getStatus() != Status.Stopped) {
|
||||
int chan = src.getChannel();
|
||||
@ -954,20 +976,22 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
||||
private int convertFormat(AudioData ad) {
|
||||
switch (ad.getBitsPerSample()) {
|
||||
case 8:
|
||||
if (ad.getChannels() == 1)
|
||||
if (ad.getChannels() == 1) {
|
||||
return AL_FORMAT_MONO8;
|
||||
else if (ad.getChannels() == 2)
|
||||
} else if (ad.getChannels() == 2) {
|
||||
return AL_FORMAT_STEREO8;
|
||||
}
|
||||
|
||||
break;
|
||||
case 16:
|
||||
if (ad.getChannels() == 1)
|
||||
if (ad.getChannels() == 1) {
|
||||
return AL_FORMAT_MONO16;
|
||||
else
|
||||
} else {
|
||||
return AL_FORMAT_STEREO16;
|
||||
}
|
||||
throw new UnsupportedOperationException("Unsupported channels/bits combination: "+
|
||||
"bits="+ad.getBitsPerSample()+", channels="+ad.getChannels());
|
||||
}
|
||||
throw new UnsupportedOperationException("Unsupported channels/bits combination: "
|
||||
+ "bits=" + ad.getBitsPerSample() + ", channels=" + ad.getChannels());
|
||||
}
|
||||
|
||||
private void updateAudioBuffer(AudioBuffer ab) {
|
||||
@ -1028,8 +1052,9 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
}
|
||||
if (audioDisabled)
|
||||
if (audioDisabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ad instanceof AudioBuffer) {
|
||||
AudioBuffer ab = (AudioBuffer) ad;
|
||||
@ -1052,5 +1077,4 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user