diff options
author | RubbaBoy <[email protected]> | 2020-07-06 02:33:28 -0400 |
---|---|---|
committer | Phil Burk <[email protected]> | 2020-10-30 11:19:34 -0700 |
commit | 46888fae6eb7b1dd386f7af7d101ead99ae61981 (patch) | |
tree | 8969bbfd68d2fb5c0d8b86da49ec2eca230a72ab /src/main/java/com/jsyn/unitgen/InterpolatingDelay.java | |
parent | c51e92e813dd481603de078f0778e1f75db2ab05 (diff) |
Restructured project, added gradle, JUnit, logger, and more
Added Gradle (and removed ant), modernized testing via the JUnit framework, moved standalone examples from the tests directory to a separate module, removed sparsely used Java logger and replaced it with SLF4J. More work could be done, however this is a great start to greatly improving the health of the codebase.
Diffstat (limited to 'src/main/java/com/jsyn/unitgen/InterpolatingDelay.java')
-rw-r--r-- | src/main/java/com/jsyn/unitgen/InterpolatingDelay.java | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/src/main/java/com/jsyn/unitgen/InterpolatingDelay.java b/src/main/java/com/jsyn/unitgen/InterpolatingDelay.java new file mode 100644 index 0000000..24de4f9 --- /dev/null +++ b/src/main/java/com/jsyn/unitgen/InterpolatingDelay.java @@ -0,0 +1,117 @@ +/* + * Copyright 1997 Phil Burk, Mobileer Inc + * + * 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. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.jsyn.unitgen; + +import com.jsyn.ports.UnitInputPort; + +/** + * InterpolatingDelay + * <P> + * InterpolatingDelay provides a variable time delay with an input and output. The internal data + * format is 32-bit floating point. The amount of delay can be varied from 0.0 to a time in seconds + * corresponding to the numFrames allocated. The fractional delay values are calculated by linearly + * interpolating between adjacent values in the delay line. + * <P> + * This unit can be used to implement time varying delay effects such as a flanger or a chorus. It + * can also be used to implement physical models of acoustic instruments, or other tunable delay + * based resonant systems. + * <P> + * + * @author (C) 1997-2011 Phil Burk, Mobileer Inc + * @see Delay + */ + +public class InterpolatingDelay extends UnitFilter { + /** + * Delay time in seconds. This value will converted to frames and clipped between zero and the + * numFrames value passed to allocate(). The minimum and default delay time is 0.0. + */ + public UnitInputPort delay; + + private float[] buffer; + private int cursor; + private int numFrames; + + public InterpolatingDelay() { + addPort(delay = new UnitInputPort("Delay")); + } + + /** + * Allocate memory for the delay buffer. For a 2 second delay at 44100 Hz sample rate you will + * need at least 88200 samples. + * + * @param numFrames size of the float array to hold the delayed samples + */ + public void allocate(int numFrames) { + this.numFrames = numFrames; + // Allocate extra frame for guard point to speed up interpolation. + buffer = new float[numFrames + 1]; + } + + @Override + public void generate(int start, int limit) { + double[] inputs = input.getValues(); + double[] outputs = output.getValues(); + double[] delays = delay.getValues(); + + for (int i = start; i < limit; i++) { + // This should be at the beginning of the loop + // because the guard point should == buffer[0]. + if (cursor == numFrames) { + // Write guard point! Must allocate one extra sample. + buffer[numFrames] = (float) inputs[i]; + cursor = 0; + } + + buffer[cursor] = (float) inputs[i]; + + /* Convert delay time to a clipped frame offset. */ + double delayFrames = delays[i] * getFrameRate(); + + // Clip to zero delay. + if (delayFrames <= 0.0) { + outputs[i] = buffer[cursor]; + } else { + // Clip to maximum delay. + if (delayFrames >= numFrames) { + delayFrames = numFrames - 1; + } + + // Calculate fractional index into delay buffer. + double readIndex = cursor - delayFrames; + if (readIndex < 0.0) { + readIndex += numFrames; + } + // setup for interpolation. + // We know readIndex is > 0 so we do not need to call floor(). + int iReadIndex = (int) readIndex; + double frac = readIndex - iReadIndex; + + // Get adjacent values relying on guard point to prevent overflow. + double val0 = buffer[iReadIndex]; + double val1 = buffer[iReadIndex + 1]; + + // Interpolate new value. + outputs[i] = val0 + (frac * (val1 - val0)); + } + + cursor += 1; + } + + } + +} |