|
@@ -87,67 +87,8 @@ public class ALAudioRenderer implements AudioRenderer, Runnable {
|
|
|
this.alc = alc;
|
|
|
this.efx = efx;
|
|
|
}
|
|
|
-
|
|
|
- public void initialize() {
|
|
|
- if (!decoderThread.isAlive()) {
|
|
|
- // Set high priority to avoid buffer starvation.
|
|
|
- decoderThread.setDaemon(true);
|
|
|
- decoderThread.setPriority(Thread.NORM_PRIORITY + 1);
|
|
|
- decoderThread.start();
|
|
|
- } else {
|
|
|
- throw new IllegalStateException("Initialize already called");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private void checkDead() {
|
|
|
- if (decoderThread.getState() == Thread.State.TERMINATED) {
|
|
|
- throw new IllegalStateException("Decoding thread is terminated");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public void run() {
|
|
|
- initInDecoderThread();
|
|
|
-
|
|
|
- // Notify render thread that OAL context is available.
|
|
|
- synchronized (threadLock) {
|
|
|
- threadLock.set(true);
|
|
|
- threadLock.notifyAll();
|
|
|
- }
|
|
|
-
|
|
|
- long updateRateNanos = (long) (UPDATE_RATE * 1000000000);
|
|
|
- mainloop:
|
|
|
- while (true) {
|
|
|
- long startTime = System.nanoTime();
|
|
|
-
|
|
|
- if (Thread.interrupted()) {
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- synchronized (threadLock) {
|
|
|
- updateInDecoderThread(UPDATE_RATE);
|
|
|
- }
|
|
|
-
|
|
|
- long endTime = System.nanoTime();
|
|
|
- long diffTime = endTime - startTime;
|
|
|
-
|
|
|
- if (diffTime < updateRateNanos) {
|
|
|
- long desiredEndTime = startTime + updateRateNanos;
|
|
|
- while (System.nanoTime() < desiredEndTime) {
|
|
|
- try {
|
|
|
- Thread.sleep(1);
|
|
|
- } catch (InterruptedException ex) {
|
|
|
- break mainloop;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- synchronized (threadLock) {
|
|
|
- cleanupInDecoderThread();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public void initInDecoderThread() {
|
|
|
+
|
|
|
+ private void initOpenAL() {
|
|
|
try {
|
|
|
if (!alc.isCreated()) {
|
|
|
alc.createALC();
|
|
@@ -228,8 +169,8 @@ public class ALAudioRenderer implements AudioRenderer, Runnable {
|
|
|
logger.log(Level.WARNING, "OpenAL EFX not available! Audio effects won't work.");
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- public void cleanupInDecoderThread() {
|
|
|
+
|
|
|
+ private void destroyOpenAL() {
|
|
|
if (audioDisabled) {
|
|
|
alc.destroyALC();
|
|
|
return;
|
|
@@ -266,17 +207,73 @@ public class ALAudioRenderer implements AudioRenderer, Runnable {
|
|
|
alc.destroyALC();
|
|
|
}
|
|
|
|
|
|
- public void cleanup() {
|
|
|
- // kill audio thread
|
|
|
+ public void initialize() {
|
|
|
if (decoderThread.isAlive()) {
|
|
|
- decoderThread.interrupt();
|
|
|
- try {
|
|
|
- decoderThread.join();
|
|
|
- } catch (InterruptedException ex) {
|
|
|
+ throw new IllegalStateException("Initialize already called");
|
|
|
+ }
|
|
|
+
|
|
|
+ // Initialize OpenAL context.
|
|
|
+ initOpenAL();
|
|
|
+
|
|
|
+ // Initialize decoder thread.
|
|
|
+ // Set high priority to avoid buffer starvation.
|
|
|
+ decoderThread.setDaemon(true);
|
|
|
+ decoderThread.setPriority(Thread.NORM_PRIORITY + 1);
|
|
|
+ decoderThread.start();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void checkDead() {
|
|
|
+ if (decoderThread.getState() == Thread.State.TERMINATED) {
|
|
|
+ throw new IllegalStateException("Decoding thread is terminated");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void run() {
|
|
|
+ long updateRateNanos = (long) (UPDATE_RATE * 1000000000);
|
|
|
+ mainloop:
|
|
|
+ while (true) {
|
|
|
+ long startTime = System.nanoTime();
|
|
|
+
|
|
|
+ if (Thread.interrupted()) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ synchronized (threadLock) {
|
|
|
+ updateInDecoderThread(UPDATE_RATE);
|
|
|
+ }
|
|
|
+
|
|
|
+ long endTime = System.nanoTime();
|
|
|
+ long diffTime = endTime - startTime;
|
|
|
+
|
|
|
+ if (diffTime < updateRateNanos) {
|
|
|
+ long desiredEndTime = startTime + updateRateNanos;
|
|
|
+ while (System.nanoTime() < desiredEndTime) {
|
|
|
+ try {
|
|
|
+ Thread.sleep(1);
|
|
|
+ } catch (InterruptedException ex) {
|
|
|
+ break mainloop;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ public void cleanup() {
|
|
|
+ // kill audio thread
|
|
|
+ if (!decoderThread.isAlive()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ decoderThread.interrupt();
|
|
|
+ try {
|
|
|
+ decoderThread.join();
|
|
|
+ } catch (InterruptedException ex) {
|
|
|
+ }
|
|
|
+
|
|
|
+ // destroy OpenAL context
|
|
|
+ destroyOpenAL();
|
|
|
+ }
|
|
|
+
|
|
|
private void updateFilter(Filter f) {
|
|
|
int id = f.getId();
|
|
|
if (id == -1) {
|
|
@@ -304,12 +301,6 @@ public class ALAudioRenderer implements AudioRenderer, Runnable {
|
|
|
public void updateSourceParam(AudioSource src, AudioParam param) {
|
|
|
checkDead();
|
|
|
synchronized (threadLock) {
|
|
|
- while (!threadLock.get()) {
|
|
|
- try {
|
|
|
- threadLock.wait();
|
|
|
- } catch (InterruptedException ex) {
|
|
|
- }
|
|
|
- }
|
|
|
if (audioDisabled) {
|
|
|
return;
|
|
|
}
|
|
@@ -536,12 +527,6 @@ public class ALAudioRenderer implements AudioRenderer, Runnable {
|
|
|
public void updateListenerParam(Listener listener, ListenerParam param) {
|
|
|
checkDead();
|
|
|
synchronized (threadLock) {
|
|
|
- while (!threadLock.get()) {
|
|
|
- try {
|
|
|
- threadLock.wait();
|
|
|
- } catch (InterruptedException ex) {
|
|
|
- }
|
|
|
- }
|
|
|
if (audioDisabled) {
|
|
|
return;
|
|
|
}
|
|
@@ -608,12 +593,6 @@ public class ALAudioRenderer implements AudioRenderer, Runnable {
|
|
|
public void setEnvironment(Environment env) {
|
|
|
checkDead();
|
|
|
synchronized (threadLock) {
|
|
|
- while (!threadLock.get()) {
|
|
|
- try {
|
|
|
- threadLock.wait();
|
|
|
- } catch (InterruptedException ex) {
|
|
|
- }
|
|
|
- }
|
|
|
if (audioDisabled || !supportEfx) {
|
|
|
return;
|
|
|
}
|
|
@@ -892,12 +871,6 @@ public class ALAudioRenderer implements AudioRenderer, Runnable {
|
|
|
public void setListener(Listener listener) {
|
|
|
checkDead();
|
|
|
synchronized (threadLock) {
|
|
|
- while (!threadLock.get()) {
|
|
|
- try {
|
|
|
- threadLock.wait();
|
|
|
- } catch (InterruptedException ex) {
|
|
|
- }
|
|
|
- }
|
|
|
if (audioDisabled) {
|
|
|
return;
|
|
|
}
|
|
@@ -933,12 +906,6 @@ public class ALAudioRenderer implements AudioRenderer, Runnable {
|
|
|
public void playSourceInstance(AudioSource src) {
|
|
|
checkDead();
|
|
|
synchronized (threadLock) {
|
|
|
- while (!threadLock.get()) {
|
|
|
- try {
|
|
|
- threadLock.wait();
|
|
|
- } catch (InterruptedException ex) {
|
|
|
- }
|
|
|
- }
|
|
|
if (audioDisabled) {
|
|
|
return;
|
|
|
}
|
|
@@ -976,12 +943,6 @@ public class ALAudioRenderer implements AudioRenderer, Runnable {
|
|
|
public void playSource(AudioSource src) {
|
|
|
checkDead();
|
|
|
synchronized (threadLock) {
|
|
|
- while (!threadLock.get()) {
|
|
|
- try {
|
|
|
- threadLock.wait();
|
|
|
- } catch (InterruptedException ex) {
|
|
|
- }
|
|
|
- }
|
|
|
if (audioDisabled) {
|
|
|
return;
|
|
|
}
|
|
@@ -1018,12 +979,6 @@ public class ALAudioRenderer implements AudioRenderer, Runnable {
|
|
|
public void pauseSource(AudioSource src) {
|
|
|
checkDead();
|
|
|
synchronized (threadLock) {
|
|
|
- while (!threadLock.get()) {
|
|
|
- try {
|
|
|
- threadLock.wait();
|
|
|
- } catch (InterruptedException ex) {
|
|
|
- }
|
|
|
- }
|
|
|
if (audioDisabled) {
|
|
|
return;
|
|
|
}
|
|
@@ -1039,12 +994,6 @@ public class ALAudioRenderer implements AudioRenderer, Runnable {
|
|
|
|
|
|
public void stopSource(AudioSource src) {
|
|
|
synchronized (threadLock) {
|
|
|
- while (!threadLock.get()) {
|
|
|
- try {
|
|
|
- threadLock.wait();
|
|
|
- } catch (InterruptedException ex) {
|
|
|
- }
|
|
|
- }
|
|
|
if (audioDisabled) {
|
|
|
return;
|
|
|
}
|
|
@@ -1140,12 +1089,6 @@ public class ALAudioRenderer implements AudioRenderer, Runnable {
|
|
|
|
|
|
public void deleteAudioData(AudioData ad) {
|
|
|
synchronized (threadLock) {
|
|
|
- while (!threadLock.get()) {
|
|
|
- try {
|
|
|
- threadLock.wait();
|
|
|
- } catch (InterruptedException ex) {
|
|
|
- }
|
|
|
- }
|
|
|
if (audioDisabled) {
|
|
|
return;
|
|
|
}
|