diff options
author | Phil Burk <[email protected]> | 2015-12-14 09:24:48 -0800 |
---|---|---|
committer | Phil Burk <[email protected]> | 2015-12-14 09:24:48 -0800 |
commit | 43228d631ed31e47d8bfceb6b5c9c9e0621a122b (patch) | |
tree | 0ae4d851d0dc48cb45b869e58f196068aadb5f7f | |
parent | dc2096655c55064b1880121b13e8f3d6f9bf4f30 (diff) | |
parent | f4e31fd760d364e10648a8a59dd90a0922ef2aa8 (diff) |
Merge pull request #13 from philburk/clearcmd
Add clearCommandQueue() to Synthesizer.
-rw-r--r-- | src/com/jsyn/Synthesizer.java | 26 | ||||
-rw-r--r-- | src/com/jsyn/engine/SynthesisEngine.java | 29 | ||||
-rw-r--r-- | src/com/softsynth/shared/time/ScheduledQueue.java | 12 | ||||
-rw-r--r-- | tests/com/jsyn/engine/TestEngine.java | 37 |
4 files changed, 76 insertions, 28 deletions
diff --git a/src/com/jsyn/Synthesizer.java b/src/com/jsyn/Synthesizer.java index 9b7c6c9..ca23ee8 100644 --- a/src/com/jsyn/Synthesizer.java +++ b/src/com/jsyn/Synthesizer.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. @@ -24,7 +24,7 @@ import com.softsynth.shared.time.TimeStamp; /** * A synthesizer used by JSyn to generate audio. The synthesizer executes a network of unit * generators to create an audio signal. - * + * * @author Phil Burk (C) 2010 Mobileer Inc */ public interface Synthesizer { @@ -40,14 +40,14 @@ public interface Synthesizer { /** * Starts a background thread that generates audio using the specified frame rate and two stereo * output channels. - * + * * @param frameRate in Hertz */ public void start(int frameRate); /** * Starts the synthesizer using specific audio devices. - * + * * @param frameRate in Hertz * @param inputDeviceID obtained from an {@link AudioDeviceManager} or pass * AudioDeviceManager.USE_DEFAULT_DEVICE @@ -71,7 +71,7 @@ public interface Synthesizer { /** * An AudioDeviceManager is an interface to audio hardware. It might be implemented using * JavaSound or a wrapper around PortAudio. - * + * * @return audio device manager being used by the synthesizer. */ public AudioDeviceManager getAudioDeviceManager(); @@ -82,7 +82,7 @@ public interface Synthesizer { /** * Add a unit generator to the synthesizer so it can be played. This is required before starting * or connecting a unit generator into a network. - * + * * @param ugen a unit generator to be executed by the synthesizer */ public void add(UnitGenerator ugen); @@ -136,7 +136,7 @@ public interface Synthesizer { * If set true then the synthesizer will generate audio in real-time. Set it true for live * audio. If false then JSyn will run in non-real-time mode. This can be used to generate audio * to be written to a file. The default is true. - * + * * @param realTime */ public void setRealTime(boolean realTime); @@ -155,7 +155,7 @@ public interface Synthesizer { /** * This count is not reset if you stop and restart. - * + * * @return number of frames synthesized */ public long getFrameCount(); @@ -170,6 +170,12 @@ public interface Synthesizer { public void queueCommand(ScheduledCommand command); /** + * Clear all scheduled commands from the queue. + * Commands will be discarded. + */ + public void clearCommandQueue(); + + /** * @return true if the Synthesizer has been started */ public boolean isRunning(); @@ -178,7 +184,7 @@ public interface Synthesizer { * Add a task that will get run on the Audio Thread before it generates a new block of Audio. * This task must be very quick and should not perform any blocking operations. If you are not * certain that you need an Audio rate task then don't use this. - * + * * @param blockTask */ public void addAudioTask(Runnable task); diff --git a/src/com/jsyn/engine/SynthesisEngine.java b/src/com/jsyn/engine/SynthesisEngine.java index 119435f..8413e29 100644 --- a/src/com/jsyn/engine/SynthesisEngine.java +++ b/src/com/jsyn/engine/SynthesisEngine.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. @@ -48,7 +48,7 @@ import com.softsynth.shared.time.TimeStamp; /** * Internal implementation of JSyn Synthesizer. The public API is in the Synthesizer interface. This * class might be used directly internally. - * + * * @author Phil Burk (C) 2009 Mobileer Inc * @see Synthesizer */ @@ -57,11 +57,11 @@ public class SynthesisEngine implements Runnable, Synthesizer { private final static int FRAMES_PER_BUFFER = Synthesizer.FRAMES_PER_BLOCK * BLOCKS_PER_BUFFER; public static final int DEFAULT_FRAME_RATE = 44100; - private AudioDeviceManager audioDeviceManager; + private final AudioDeviceManager audioDeviceManager; private AudioDeviceOutputStream audioOutputStream; private AudioDeviceInputStream audioInputStream; private Thread audioThread; - private ScheduledQueue<ScheduledCommand> commandQueue = new ScheduledQueue<ScheduledCommand>(); + private final ScheduledQueue<ScheduledCommand> commandQueue = new ScheduledQueue<ScheduledCommand>(); private volatile boolean go; private InterleavingBuffer inputBuffer; @@ -75,16 +75,16 @@ public class SynthesisEngine implements Runnable, Synthesizer { private double framePeriod = 1.0 / frameRate; // List of all units added to the synth. - private ArrayList<UnitGenerator> allUnitList = new ArrayList<UnitGenerator>(); + private final ArrayList<UnitGenerator> allUnitList = new ArrayList<UnitGenerator>(); // List of running units. - private ArrayList<UnitGenerator> runningUnitList = new ArrayList<UnitGenerator>(); + private final ArrayList<UnitGenerator> runningUnitList = new ArrayList<UnitGenerator>(); // List of units stopping because of autoStop. - private ArrayList<UnitGenerator> stoppingUnitList = new ArrayList<UnitGenerator>(); + private final ArrayList<UnitGenerator> stoppingUnitList = new ArrayList<UnitGenerator>(); private LoadAnalyzer loadAnalyzer; // private int numOutputChannels; // private int numInputChannels; - private CopyOnWriteArrayList<Runnable> audioTasks = new CopyOnWriteArrayList<Runnable>(); + private final CopyOnWriteArrayList<Runnable> audioTasks = new CopyOnWriteArrayList<Runnable>(); /** A fraction corresponding to exactly -96 dB. */ public static final double DB96 = (1.0 / 63095.73444801943); /** A fraction that is approximately -90.3 dB. Defined as 1 bit of an S16. */ @@ -122,7 +122,7 @@ public class SynthesisEngine implements Runnable, Synthesizer { /** * If set true then audio data will be pulled from the output ports of connected unit * generators. The final unit in a tree of units needs to be start()ed. - * + * * @param pullDataEnabled */ public void setPullDataEnabled(boolean pullDataEnabled) { @@ -140,7 +140,7 @@ public class SynthesisEngine implements Runnable, Synthesizer { } class InterleavingBuffer { - private double[] interleavedBuffer; + private final double[] interleavedBuffer; ChannelBlockBuffer[] blockBuffers; InterleavingBuffer(int framesPerBuffer, int framesPerBlock, int samplesPerFrame) { @@ -184,7 +184,7 @@ public class SynthesisEngine implements Runnable, Synthesizer { } class ChannelBlockBuffer { - private double[] values; + private final double[] values; ChannelBlockBuffer(int framesPerBlock) { values = new double[framesPerBlock]; @@ -415,6 +415,11 @@ public class SynthesisEngine implements Runnable, Synthesizer { scheduleCommand(timeStamp, command); } + @Override + public void clearCommandQueue() { + commandQueue.clear(); + } + private void clearBlockBuffers() { outputBuffer.clear(); } diff --git a/src/com/softsynth/shared/time/ScheduledQueue.java b/src/com/softsynth/shared/time/ScheduledQueue.java index d074487..367e4f8 100644 --- a/src/com/softsynth/shared/time/ScheduledQueue.java +++ b/src/com/softsynth/shared/time/ScheduledQueue.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. @@ -22,10 +22,10 @@ import java.util.SortedMap; import java.util.TreeMap; /** - * @author Phil Burk, (C) 2009 Mobileer Inc + * Store objects in time sorted order. */ public class ScheduledQueue<T> { - private SortedMap<TimeStamp, List<T>> timeNodes; + private final SortedMap<TimeStamp, List<T>> timeNodes; public ScheduledQueue() { timeNodes = new TreeMap<TimeStamp, List<T>>(); @@ -74,6 +74,10 @@ public class ScheduledQueue<T> { return next; } + public synchronized void clear() { + timeNodes.clear(); + } + public TimeStamp getNextTime() { return timeNodes.firstKey(); } diff --git a/tests/com/jsyn/engine/TestEngine.java b/tests/com/jsyn/engine/TestEngine.java index b633bc1..9572f3d 100644 --- a/tests/com/jsyn/engine/TestEngine.java +++ b/tests/com/jsyn/engine/TestEngine.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. @@ -18,6 +18,7 @@ package com.jsyn.engine; import junit.framework.TestCase; +import com.jsyn.unitgen.Add; import com.jsyn.unitgen.LineOut; import com.jsyn.unitgen.PitchDetector; import com.jsyn.unitgen.SineOscillator; @@ -177,4 +178,36 @@ public class TestEngine extends TestCase { } + + public void testScheduler() throws InterruptedException { + SynthesisEngine synth = new SynthesisEngine(); + synth.setRealTime(false); + Add adder = new Add(); + synth.add(adder); + synth.start(); + adder.start(); + adder.inputA.set(4.0); + adder.inputB.set(10.0); + synth.sleepFor(0.1); + assertEquals("simple add", 14.0, adder.output.get(), 0.01); + + // Schedule a set() in the near future. + double time = synth.getCurrentTime(); + adder.inputA.set(7.0, time + 1.0); + synth.sleepFor(0.5); + assertEquals("before scheduled set", 14.0, adder.output.get(), 0.01); + synth.sleepFor(1.0); + assertEquals("after scheduled set", 17.0, adder.output.get(), 0.01); + + // Schedule a set() in the near future then cancel it. + time = synth.getCurrentTime(); + adder.inputA.set(5.0, time + 1.0); + synth.sleepFor(0.5); + assertEquals("before scheduled set", 17.0, adder.output.get(), 0.01); + synth.clearCommandQueue(); + synth.sleepFor(1.0); + assertEquals("after canceled set", 17.0, adder.output.get(), 0.01); + + synth.stop(); + } } |