aboutsummaryrefslogtreecommitdiffstats
path: root/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/com/jsyn/io/AudioFifo.java48
-rw-r--r--src/main/java/com/jsyn/util/StreamingThread.java15
-rw-r--r--src/main/java/com/jsyn/util/WaveRecorder.java8
3 files changed, 43 insertions, 28 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
diff --git a/src/main/java/com/jsyn/util/StreamingThread.java b/src/main/java/com/jsyn/util/StreamingThread.java
index 682f476..7377698 100644
--- a/src/main/java/com/jsyn/util/StreamingThread.java
+++ b/src/main/java/com/jsyn/util/StreamingThread.java
@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -23,7 +23,7 @@ import com.jsyn.io.AudioOutputStream;
/**
* Read from an AudioInputStream and write to an AudioOutputStream as a background thread.
- *
+ *
* @author Phil Burk (C) 2011 Mobileer Inc
*/
public class StreamingThread extends Thread {
@@ -47,17 +47,18 @@ public class StreamingThread extends Thread {
try {
transportModel.firePositionChanged(framePosition);
transportModel.fireStateChanged(TransportModel.STATE_RUNNING);
- int framesToRead = geteFramesToRead(buffer);
+ int framesToRead = getFramesToRead(buffer);
while (go && (framesToRead > 0)) {
int samplesToRead = framesToRead * samplesPerFrame;
while (samplesToRead > 0) {
int samplesRead = inputStream.read(buffer, 0, samplesToRead);
outputStream.write(buffer, 0, samplesRead);
samplesToRead -= samplesRead;
+ if (samplesRead < samplesToRead) break; // stream closed
}
framePosition += framesToRead;
transportModel.firePositionChanged(framePosition);
- framesToRead = geteFramesToRead(buffer);
+ framesToRead = getFramesToRead(buffer);
}
transportModel.fireStateChanged(TransportModel.STATE_STOPPED);
} catch (IOException e) {
@@ -65,7 +66,7 @@ public class StreamingThread extends Thread {
}
}
- private int geteFramesToRead(double[] buffer) {
+ private int getFramesToRead(double[] buffer) {
if (maxFrames > 0) {
long numToRead = maxFrames - framePosition;
if (numToRead < 0) {
@@ -85,7 +86,7 @@ public class StreamingThread extends Thread {
/**
* Only call this before the thread has started.
- *
+ *
* @param framesPerBuffer
*/
public void setFramesPerBuffer(int framesPerBuffer) {
diff --git a/src/main/java/com/jsyn/util/WaveRecorder.java b/src/main/java/com/jsyn/util/WaveRecorder.java
index 8008d1d..d189f06 100644
--- a/src/main/java/com/jsyn/util/WaveRecorder.java
+++ b/src/main/java/com/jsyn/util/WaveRecorder.java
@@ -24,7 +24,8 @@ import com.jsyn.Synthesizer;
import com.jsyn.ports.UnitInputPort;
/**
- * Connect a unit generator to the input. Then start() recording. The signal will be written to a
+ * Connect a unit generator to the input. Then start() recording.
+ * The signal will be written to a
* WAV format file that can be read by other programs.
*
* @author Phil Burk (C) 2011 Mobileer Inc
@@ -60,7 +61,8 @@ public class WaveRecorder {
* @param bitsPerSample 16 or 24
* @throws FileNotFoundException
*/
- public WaveRecorder(Synthesizer synth, File outputFile, int samplesPerFrame, int bitsPerSample)
+ public WaveRecorder(Synthesizer synth, File outputFile,
+ int samplesPerFrame, int bitsPerSample)
throws FileNotFoundException {
this.synth = synth;
reader = new AudioStreamReader(synth, samplesPerFrame);
@@ -86,10 +88,12 @@ public class WaveRecorder {
public void stop() {
if (thread != null) {
+ reader.close();
thread.requestStop();
try {
thread.join(500);
} catch (InterruptedException ignored) {
+ System.out.println("join() " + ignored);
}
thread = null;
}