diff options
Diffstat (limited to 'src/main')
-rw-r--r-- | src/main/java/com/jsyn/io/AudioFifo.java | 48 | ||||
-rw-r--r-- | src/main/java/com/jsyn/util/StreamingThread.java | 15 | ||||
-rw-r--r-- | src/main/java/com/jsyn/util/WaveRecorder.java | 8 |
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; } |