aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/com/jsyn/io/AudioFifo.java
diff options
context:
space:
mode:
authorPhil Burk <[email protected]>2022-01-30 12:14:35 -0700
committerGitHub <[email protected]>2022-01-30 11:14:35 -0800
commite792b44d99676a363bc5e6e6d5c42881e756f956 (patch)
treecad74da4bf7e2d12052f943bf51256c340502c41 /src/main/java/com/jsyn/io/AudioFifo.java
parentc43a8e222c9a51046c2b11c9549ffa76204d1eb5 (diff)
WaveRecorder: fix hang in StreamingThread (#106)
The read() could hang forever waiting for data when the WaveRecorder was stopped. Now it terminates the thread. Also fix bug in AudioFifo when partially full. It would not read any data! Fixes #105
Diffstat (limited to 'src/main/java/com/jsyn/io/AudioFifo.java')
-rw-r--r--src/main/java/com/jsyn/io/AudioFifo.java48
1 files changed, 29 insertions, 19 deletions
diff --git a/src/main/java/com/jsyn/io/AudioFifo.java b/src/main/java/com/jsyn/io/AudioFifo.java
index 0c563e4..b7321c6 100644
--- a/src/main/java/com/jsyn/io/AudioFifo.java
+++ b/src/main/java/com/jsyn/io/AudioFifo.java
@@ -37,6 +37,7 @@ public class AudioFifo implements AudioInputStream, AudioOutputStream {
private int sizeMask;
private boolean writeWaitEnabled = true;
private boolean readWaitEnabled = true;
+ private volatile boolean mOpen = true;
final Lock lock = new ReentrantLock();
final Condition notFull = lock.newCondition();
final Condition notEmpty = lock.newCondition();
@@ -69,7 +70,12 @@ public class AudioFifo implements AudioInputStream, AudioOutputStream {
@Override
public void close() {
- // TODO Maybe we should tell any thread that is waiting that the FIFO is closed.
+ // Tell any thread that is waiting that the FIFO is closed.
+ mOpen = false;
+ lock.lock();
+ notEmpty.signal();
+ notFull.signal();
+ lock.unlock();
}
@Override
@@ -78,20 +84,22 @@ public class AudioFifo implements AudioInputStream, AudioOutputStream {
if (readWaitEnabled) {
lock.lock();
try {
- while (available() < 1) {
+ while (mOpen && available() < 1) {
try {
notEmpty.await();
} catch (InterruptedException e) {
return Double.NaN;
}
}
- value = readOneInternal();
+ if (mOpen) {
+ value = readOneInternal();
+ }
} finally {
lock.unlock();
}
} else {
- if (readIndex != writeIndex) {
+ if (mOpen && readIndex != writeIndex) {
value = readOneInternal();
}
}
@@ -116,7 +124,7 @@ public class AudioFifo implements AudioInputStream, AudioOutputStream {
if (writeWaitEnabled) {
lock.lock();
try {
- while (available() == buffer.length)
+ while (mOpen && available() == buffer.length)
{
try {
notFull.await();
@@ -124,7 +132,9 @@ public class AudioFifo implements AudioInputStream, AudioOutputStream {
return; // Silently fail
}
}
- writeOneInternal(value);
+ if (mOpen) {
+ writeOneInternal(value);
+ }
} finally {
lock.unlock();
}
@@ -154,20 +164,20 @@ public class AudioFifo implements AudioInputStream, AudioOutputStream {
@Override
public int read(double[] buffer, int start, int count) {
- if (readWaitEnabled) {
- for (int i = 0; i < count; i++) {
- buffer[i + start] = read();
- }
- } else {
- if (available() < count) {
- count = available();
- } else {
- for (int i = 0; i < count; i++) {
- buffer[i + start] = read();
- }
- }
+ if (!mOpen) {
+ return 0;
+ }
+ if (!readWaitEnabled) {
+ count = Math.min(available(), count);
+ }
+ int numRead = 0;
+ for (int i = 0; mOpen && i < count; i++) {
+ double value = read();
+ if (value == Double.NaN) break;
+ buffer[i + start] = value;
+ numRead++;
}
- return count;
+ return numRead;
}
@Override