diff options
author | Phil Burk <[email protected]> | 2016-11-27 13:39:42 -0800 |
---|---|---|
committer | Phil Burk <[email protected]> | 2016-11-27 13:39:42 -0800 |
commit | ff5e1fb0794cc65c32a7d9f51d03eba841eba4ad (patch) | |
tree | d85f0687742a8865ba12ce21c1ac4c95ab9de1b1 | |
parent | a6583e89166f7477a675cf3094a91b303ba7850a (diff) |
Check for bounds when sample or envelope data is queued.
Add unit test.
Fix: #15
-rw-r--r-- | src/com/jsyn/ports/QueueDataCommand.java | 32 | ||||
-rw-r--r-- | tests/com/jsyn/ports/TestQueuedDataPort.java | 39 |
2 files changed, 54 insertions, 17 deletions
diff --git a/src/com/jsyn/ports/QueueDataCommand.java b/src/com/jsyn/ports/QueueDataCommand.java index 52025ae..c23fbcd 100644 --- a/src/com/jsyn/ports/QueueDataCommand.java +++ b/src/com/jsyn/ports/QueueDataCommand.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,7 +22,7 @@ import com.softsynth.shared.time.ScheduledCommand; /** * A command that can be used to queue SequentialData to a UnitDataQueuePort. Here is an example of * queuing data with a callback using this command. - * + * * <pre> * <code> * // Queue an envelope with a completion callback. @@ -36,9 +36,9 @@ import com.softsynth.shared.time.ScheduledCommand; * synth.queueCommand( command ); * </code> * </pre> - * + * * The callback will be passed QueueDataEvents. - * + * * <pre> * <code> * class TestQueueCallback implements UnitDataQueueCallback @@ -47,12 +47,12 @@ import com.softsynth.shared.time.ScheduledCommand; * { * System.out.println("CALLBACK: Envelope started."); * } - * + * * public void looped( QueueDataEvent event ) * { * System.out.println("CALLBACK: Envelope looped."); * } - * + * * public void finished( QueueDataEvent event ) * { * System.out.println("CALLBACK: Envelope finished."); @@ -60,7 +60,7 @@ import com.softsynth.shared.time.ScheduledCommand; * } * </code> * </pre> - * + * * @author Phil Burk 2009 Mobileer Inc */ public abstract class QueueDataCommand extends QueueDataEvent implements ScheduledCommand { @@ -75,7 +75,11 @@ public abstract class QueueDataCommand extends QueueDataEvent implements Schedul int numFrames) { super(port); - assert ((startFrame + numFrames) <= sequentialData.getNumFrames()); + if ((startFrame + numFrames) > sequentialData.getNumFrames()) { + throw new IllegalArgumentException("tried to queue past end of data, " + (startFrame + numFrames)); + } else if (startFrame < 0) { + throw new IllegalArgumentException("tried to queue before start of data, " + startFrame); + } this.sequentialData = sequentialData; this.currentData = sequentialData; crossfadeData = new SequentialDataCrossfade(); @@ -89,7 +93,7 @@ public abstract class QueueDataCommand extends QueueDataEvent implements Schedul /** * If true then this item will be skipped if other items are queued after it. This flag allows * you to queue lots of small pieces of sound without making the queue very long. - * + * * @param skipIfOthers */ public void setSkipIfOthers(boolean skipIfOthers) { @@ -101,7 +105,7 @@ public abstract class QueueDataCommand extends QueueDataEvent implements Schedul * better to use this flag than to clear the queue from the application because there could be a * gap before the next item is available. This is most useful when combined with * setCrossFadeIn(). - * + * * @param immediate */ public void setImmediate(boolean immediate) { @@ -134,7 +138,7 @@ public abstract class QueueDataCommand extends QueueDataEvent implements Schedul /** * Stop the unit that contains this port after this command has finished. - * + * * @param autoStop */ public void setAutoStop(boolean autoStop) { @@ -145,7 +149,7 @@ public abstract class QueueDataCommand extends QueueDataEvent implements Schedul * Set how many time the block should be repeated after the first time. For example, if you set * numLoops to zero the block will only be played once. If you set numLoops to one the block * will be played twice. - * + * * @param numLoops number of times to loop back */ public void setNumLoops(int numLoops) { @@ -156,7 +160,7 @@ public abstract class QueueDataCommand extends QueueDataEvent implements Schedul * Number of frames to cross fade from the previous block to this block. This can be used to * avoid pops when making abrupt transitions. There must be frames available after the end of * the previous block to use for crossfading. The crossfade is linear. - * + * * @param size */ public void setCrossFadeIn(int size) { diff --git a/tests/com/jsyn/ports/TestQueuedDataPort.java b/tests/com/jsyn/ports/TestQueuedDataPort.java index 8c4714b..e229038 100644 --- a/tests/com/jsyn/ports/TestQueuedDataPort.java +++ b/tests/com/jsyn/ports/TestQueuedDataPort.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. @@ -27,7 +27,7 @@ import com.jsyn.unitgen.FixedRateMonoReader; /** * Test sample and envelope queuing and looping. - * + * * @author Phil Burk, (C) 2009 Mobileer Inc */ public class TestQueuedDataPort extends TestCase { @@ -96,6 +96,39 @@ public class TestQueuedDataPort extends TestCase { assertEquals("end empty", false, dataQueue.hasMore()); } + public void testQueueOutOfBounds() { + float[] data = { + 0.4f, 1.9f, 22.7f + }; + FloatSample sample = new FloatSample(data.length, 1); + sample.write(data); + + UnitDataQueuePort dataQueue = new UnitDataQueuePort("test"); + boolean caught = false; + try { + queueDirect(dataQueue, sample, 0, sample.getNumFrames() + 1); // should cause an error! + } catch(IllegalArgumentException e) { + caught = true; + } + assertTrue("expect exception when we go past end of the array", caught); + + caught = false; + try { + queueDirect(dataQueue, sample, 1, sample.getNumFrames()); // should cause an error! + } catch(IllegalArgumentException e) { + caught = true; + } + assertTrue("expect exception when we go past end of the array", caught); + + caught = false; + try { + queueDirect(dataQueue, sample, -1, sample.getNumFrames()); // should cause an error! + } catch(IllegalArgumentException e) { + caught = true; + } + assertTrue("expect exception when we start before beginning of the array", caught); + } + public void testQueueMultiple() { short[] data = { 234, 17777, -9876, 4567, -14287 |