aboutsummaryrefslogtreecommitdiffstats
path: root/src/com/jsyn
diff options
context:
space:
mode:
authorRubbaBoy <[email protected]>2020-07-06 02:33:28 -0400
committerPhil Burk <[email protected]>2020-10-30 11:19:34 -0700
commit46888fae6eb7b1dd386f7af7d101ead99ae61981 (patch)
tree8969bbfd68d2fb5c0d8b86da49ec2eca230a72ab /src/com/jsyn
parentc51e92e813dd481603de078f0778e1f75db2ab05 (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/com/jsyn')
-rw-r--r--src/com/jsyn/JSyn.java78
-rw-r--r--src/com/jsyn/Synthesizer.java202
-rw-r--r--src/com/jsyn/apps/AboutJSyn.java114
-rw-r--r--src/com/jsyn/apps/InstrumentTester.java205
-rw-r--r--src/com/jsyn/data/AudioSample.java108
-rw-r--r--src/com/jsyn/data/DoubleTable.java109
-rw-r--r--src/com/jsyn/data/FloatSample.java164
-rw-r--r--src/com/jsyn/data/Function.java35
-rw-r--r--src/com/jsyn/data/HammingWindow.java41
-rw-r--r--src/com/jsyn/data/HannWindow.java36
-rw-r--r--src/com/jsyn/data/SampleMarker.java30
-rw-r--r--src/com/jsyn/data/SegmentedEnvelope.java125
-rw-r--r--src/com/jsyn/data/SequentialData.java97
-rw-r--r--src/com/jsyn/data/SequentialDataCommon.java136
-rw-r--r--src/com/jsyn/data/ShortSample.java123
-rw-r--r--src/com/jsyn/data/SpectralWindow.java21
-rw-r--r--src/com/jsyn/data/SpectralWindowFactory.java55
-rw-r--r--src/com/jsyn/data/Spectrum.java97
-rw-r--r--src/com/jsyn/devices/AudioDeviceFactory.java93
-rw-r--r--src/com/jsyn/devices/AudioDeviceInputStream.java31
-rw-r--r--src/com/jsyn/devices/AudioDeviceManager.java120
-rw-r--r--src/com/jsyn/devices/AudioDeviceOutputStream.java30
-rw-r--r--src/com/jsyn/devices/javasound/JavaSoundAudioDevice.java431
-rw-r--r--src/com/jsyn/devices/javasound/MidiDeviceTools.java80
-rw-r--r--src/com/jsyn/devices/jportaudio/JPortAudioDevice.java259
-rw-r--r--src/com/jsyn/engine/LoadAnalyzer.java61
-rw-r--r--src/com/jsyn/engine/MultiTable.java230
-rw-r--r--src/com/jsyn/engine/SynthesisEngine.java698
-rw-r--r--src/com/jsyn/exceptions/ChannelMismatchException.java35
-rw-r--r--src/com/jsyn/instruments/DrumWoodFM.java159
-rw-r--r--src/com/jsyn/instruments/DualOscillatorSynthVoice.java301
-rw-r--r--src/com/jsyn/instruments/JSynInstrumentLibrary.java48
-rw-r--r--src/com/jsyn/instruments/NoiseHit.java114
-rw-r--r--src/com/jsyn/instruments/SubtractiveSynthVoice.java182
-rw-r--r--src/com/jsyn/instruments/WaveShapingVoice.java187
-rw-r--r--src/com/jsyn/io/AudioFifo.java204
-rw-r--r--src/com/jsyn/io/AudioInputStream.java46
-rw-r--r--src/com/jsyn/io/AudioOutputStream.java29
-rw-r--r--src/com/jsyn/midi/MessageParser.java147
-rw-r--r--src/com/jsyn/midi/MidiConstants.java84
-rw-r--r--src/com/jsyn/midi/MidiSynthesizer.java118
-rw-r--r--src/com/jsyn/package.html17
-rw-r--r--src/com/jsyn/ports/ConnectableInput.java38
-rw-r--r--src/com/jsyn/ports/ConnectableOutput.java23
-rw-r--r--src/com/jsyn/ports/GettablePort.java27
-rw-r--r--src/com/jsyn/ports/InputMixingBlockPart.java112
-rw-r--r--src/com/jsyn/ports/PortBlockPart.java205
-rw-r--r--src/com/jsyn/ports/QueueDataCommand.java170
-rw-r--r--src/com/jsyn/ports/QueueDataEvent.java80
-rw-r--r--src/com/jsyn/ports/SequentialDataCrossfade.java139
-rw-r--r--src/com/jsyn/ports/SettablePort.java28
-rw-r--r--src/com/jsyn/ports/UnitBlockPort.java110
-rw-r--r--src/com/jsyn/ports/UnitDataQueueCallback.java31
-rw-r--r--src/com/jsyn/ports/UnitDataQueuePort.java466
-rw-r--r--src/com/jsyn/ports/UnitFunctionPort.java48
-rw-r--r--src/com/jsyn/ports/UnitGatePort.java158
-rw-r--r--src/com/jsyn/ports/UnitInputPort.java254
-rw-r--r--src/com/jsyn/ports/UnitOutputPort.java103
-rw-r--r--src/com/jsyn/ports/UnitPort.java85
-rw-r--r--src/com/jsyn/ports/UnitSpectralInputPort.java83
-rw-r--r--src/com/jsyn/ports/UnitSpectralOutputPort.java69
-rw-r--r--src/com/jsyn/ports/UnitVariablePort.java64
-rw-r--r--src/com/jsyn/ports/package.html13
-rw-r--r--src/com/jsyn/scope/AudioScope.java101
-rw-r--r--src/com/jsyn/scope/AudioScopeModel.java157
-rw-r--r--src/com/jsyn/scope/AudioScopeProbe.java94
-rw-r--r--src/com/jsyn/scope/DefaultWaveTraceModel.java48
-rw-r--r--src/com/jsyn/scope/MultiChannelScopeProbeUnit.java246
-rw-r--r--src/com/jsyn/scope/TriggerModel.java67
-rw-r--r--src/com/jsyn/scope/WaveTraceModel.java27
-rw-r--r--src/com/jsyn/scope/swing/AudioScopeProbeView.java45
-rw-r--r--src/com/jsyn/scope/swing/AudioScopeView.java112
-rw-r--r--src/com/jsyn/scope/swing/MultipleWaveDisplay.java58
-rw-r--r--src/com/jsyn/scope/swing/ScopeControlPanel.java46
-rw-r--r--src/com/jsyn/scope/swing/ScopeProbePanel.java82
-rw-r--r--src/com/jsyn/scope/swing/ScopeTriggerPanel.java47
-rw-r--r--src/com/jsyn/scope/swing/WaveTraceView.java122
-rw-r--r--src/com/jsyn/swing/ASCIIMusicKeyboard.java193
-rw-r--r--src/com/jsyn/swing/DoubleBoundedRangeModel.java86
-rw-r--r--src/com/jsyn/swing/DoubleBoundedRangeSlider.java101
-rw-r--r--src/com/jsyn/swing/DoubleBoundedTextField.java94
-rw-r--r--src/com/jsyn/swing/EnvelopeEditorBox.java573
-rw-r--r--src/com/jsyn/swing/EnvelopeEditorPanel.java164
-rw-r--r--src/com/jsyn/swing/EnvelopePoints.java234
-rw-r--r--src/com/jsyn/swing/ExponentialRangeModel.java105
-rw-r--r--src/com/jsyn/swing/InstrumentBrowser.java117
-rw-r--r--src/com/jsyn/swing/JAppletFrame.java65
-rw-r--r--src/com/jsyn/swing/PortBoundedRangeModel.java45
-rw-r--r--src/com/jsyn/swing/PortControllerFactory.java60
-rw-r--r--src/com/jsyn/swing/PortModelFactory.java64
-rw-r--r--src/com/jsyn/swing/PresetSelectionListener.java23
-rw-r--r--src/com/jsyn/swing/RotaryController.java335
-rw-r--r--src/com/jsyn/swing/RotaryTextController.java53
-rw-r--r--src/com/jsyn/swing/SoundTweaker.java122
-rw-r--r--src/com/jsyn/swing/XYController.java132
-rw-r--r--src/com/jsyn/unitgen/Add.java50
-rw-r--r--src/com/jsyn/unitgen/AsymptoticRamp.java81
-rw-r--r--src/com/jsyn/unitgen/BrownNoise.java75
-rw-r--r--src/com/jsyn/unitgen/ChannelIn.java59
-rw-r--r--src/com/jsyn/unitgen/ChannelOut.java62
-rw-r--r--src/com/jsyn/unitgen/Circuit.java122
-rw-r--r--src/com/jsyn/unitgen/Compare.java38
-rw-r--r--src/com/jsyn/unitgen/ContinuousRamp.java91
-rw-r--r--src/com/jsyn/unitgen/CrossFade.java60
-rw-r--r--src/com/jsyn/unitgen/Delay.java57
-rw-r--r--src/com/jsyn/unitgen/Divide.java53
-rw-r--r--src/com/jsyn/unitgen/DualInTwoOut.java59
-rw-r--r--src/com/jsyn/unitgen/EdgeDetector.java44
-rw-r--r--src/com/jsyn/unitgen/EnvelopeAttackDecay.java145
-rw-r--r--src/com/jsyn/unitgen/EnvelopeDAHDSR.java294
-rw-r--r--src/com/jsyn/unitgen/ExponentialRamp.java104
-rw-r--r--src/com/jsyn/unitgen/FFT.java36
-rw-r--r--src/com/jsyn/unitgen/FFTBase.java86
-rw-r--r--src/com/jsyn/unitgen/FilterAllPass.java62
-rw-r--r--src/com/jsyn/unitgen/FilterBandPass.java44
-rw-r--r--src/com/jsyn/unitgen/FilterBandStop.java49
-rw-r--r--src/com/jsyn/unitgen/FilterBiquad.java156
-rw-r--r--src/com/jsyn/unitgen/FilterBiquadCommon.java99
-rw-r--r--src/com/jsyn/unitgen/FilterBiquadShelf.java111
-rw-r--r--src/com/jsyn/unitgen/FilterFourPoles.java185
-rw-r--r--src/com/jsyn/unitgen/FilterHighPass.java46
-rw-r--r--src/com/jsyn/unitgen/FilterHighShelf.java38
-rw-r--r--src/com/jsyn/unitgen/FilterLowPass.java65
-rw-r--r--src/com/jsyn/unitgen/FilterLowShelf.java40
-rw-r--r--src/com/jsyn/unitgen/FilterOnePole.java62
-rw-r--r--src/com/jsyn/unitgen/FilterOnePoleOneZero.java68
-rw-r--r--src/com/jsyn/unitgen/FilterOneZero.java65
-rw-r--r--src/com/jsyn/unitgen/FilterPeakingEQ.java68
-rw-r--r--src/com/jsyn/unitgen/FilterStateVariable.java120
-rw-r--r--src/com/jsyn/unitgen/FilterTwoPoles.java66
-rw-r--r--src/com/jsyn/unitgen/FilterTwoPolesTwoZeros.java79
-rw-r--r--src/com/jsyn/unitgen/FixedRateMonoReader.java52
-rw-r--r--src/com/jsyn/unitgen/FixedRateMonoWriter.java54
-rw-r--r--src/com/jsyn/unitgen/FixedRateStereoReader.java59
-rw-r--r--src/com/jsyn/unitgen/FixedRateStereoWriter.java60
-rw-r--r--src/com/jsyn/unitgen/FourWayFade.java94
-rw-r--r--src/com/jsyn/unitgen/FunctionEvaluator.java76
-rw-r--r--src/com/jsyn/unitgen/FunctionOscillator.java58
-rw-r--r--src/com/jsyn/unitgen/Grain.java89
-rw-r--r--src/com/jsyn/unitgen/GrainCommon.java32
-rw-r--r--src/com/jsyn/unitgen/GrainEnvelope.java52
-rw-r--r--src/com/jsyn/unitgen/GrainFarm.java178
-rw-r--r--src/com/jsyn/unitgen/GrainScheduler.java44
-rw-r--r--src/com/jsyn/unitgen/GrainSource.java36
-rw-r--r--src/com/jsyn/unitgen/GrainSourceSine.java51
-rw-r--r--src/com/jsyn/unitgen/IFFT.java36
-rw-r--r--src/com/jsyn/unitgen/ImpulseOscillator.java59
-rw-r--r--src/com/jsyn/unitgen/ImpulseOscillatorBL.java39
-rw-r--r--src/com/jsyn/unitgen/Integrate.java82
-rw-r--r--src/com/jsyn/unitgen/InterpolatingDelay.java117
-rw-r--r--src/com/jsyn/unitgen/Latch.java53
-rw-r--r--src/com/jsyn/unitgen/LatchZeroCrossing.java72
-rw-r--r--src/com/jsyn/unitgen/LineIn.java51
-rw-r--r--src/com/jsyn/unitgen/LineOut.java57
-rw-r--r--src/com/jsyn/unitgen/LinearRamp.java94
-rw-r--r--src/com/jsyn/unitgen/Maximum.java42
-rw-r--r--src/com/jsyn/unitgen/Minimum.java43
-rw-r--r--src/com/jsyn/unitgen/MixerMono.java77
-rw-r--r--src/com/jsyn/unitgen/MixerMonoRamped.java54
-rw-r--r--src/com/jsyn/unitgen/MixerStereo.java94
-rw-r--r--src/com/jsyn/unitgen/MixerStereoRamped.java71
-rw-r--r--src/com/jsyn/unitgen/MonoStreamWriter.java49
-rw-r--r--src/com/jsyn/unitgen/MorphingOscillatorBL.java72
-rw-r--r--src/com/jsyn/unitgen/MultiPassThrough.java70
-rw-r--r--src/com/jsyn/unitgen/Multiply.java64
-rw-r--r--src/com/jsyn/unitgen/MultiplyAdd.java57
-rw-r--r--src/com/jsyn/unitgen/Pan.java64
-rw-r--r--src/com/jsyn/unitgen/PanControl.java61
-rw-r--r--src/com/jsyn/unitgen/ParabolicEnvelope.java110
-rw-r--r--src/com/jsyn/unitgen/PassThrough.java38
-rw-r--r--src/com/jsyn/unitgen/PeakFollower.java87
-rw-r--r--src/com/jsyn/unitgen/PhaseShifter.java90
-rw-r--r--src/com/jsyn/unitgen/PinkNoise.java128
-rw-r--r--src/com/jsyn/unitgen/PitchDetector.java115
-rw-r--r--src/com/jsyn/unitgen/PitchToFrequency.java26
-rw-r--r--src/com/jsyn/unitgen/PowerOfTwo.java108
-rw-r--r--src/com/jsyn/unitgen/PulseOscillator.java59
-rw-r--r--src/com/jsyn/unitgen/PulseOscillatorBL.java61
-rw-r--r--src/com/jsyn/unitgen/RaisedCosineEnvelope.java73
-rw-r--r--src/com/jsyn/unitgen/RangeConverter.java50
-rw-r--r--src/com/jsyn/unitgen/RectangularWindow.java39
-rw-r--r--src/com/jsyn/unitgen/RedNoise.java80
-rw-r--r--src/com/jsyn/unitgen/SampleGrainFarm.java71
-rw-r--r--src/com/jsyn/unitgen/SampleGrainSource.java69
-rw-r--r--src/com/jsyn/unitgen/SawtoothOscillator.java47
-rw-r--r--src/com/jsyn/unitgen/SawtoothOscillatorBL.java65
-rw-r--r--src/com/jsyn/unitgen/SawtoothOscillatorDPW.java76
-rw-r--r--src/com/jsyn/unitgen/SchmidtTrigger.java83
-rw-r--r--src/com/jsyn/unitgen/Select.java56
-rw-r--r--src/com/jsyn/unitgen/SequentialDataReader.java38
-rw-r--r--src/com/jsyn/unitgen/SequentialDataWriter.java44
-rw-r--r--src/com/jsyn/unitgen/SineOscillator.java85
-rw-r--r--src/com/jsyn/unitgen/SineOscillatorPhaseModulated.java74
-rw-r--r--src/com/jsyn/unitgen/SpectralFFT.java130
-rw-r--r--src/com/jsyn/unitgen/SpectralFilter.java130
-rw-r--r--src/com/jsyn/unitgen/SpectralIFFT.java92
-rw-r--r--src/com/jsyn/unitgen/SpectralProcessor.java73
-rw-r--r--src/com/jsyn/unitgen/SquareOscillator.java49
-rw-r--r--src/com/jsyn/unitgen/SquareOscillatorBL.java48
-rw-r--r--src/com/jsyn/unitgen/StereoStreamWriter.java53
-rw-r--r--src/com/jsyn/unitgen/StochasticGrainScheduler.java43
-rw-r--r--src/com/jsyn/unitgen/Subtract.java42
-rw-r--r--src/com/jsyn/unitgen/TriangleOscillator.java59
-rw-r--r--src/com/jsyn/unitgen/TunableFilter.java41
-rw-r--r--src/com/jsyn/unitgen/TwoInDualOut.java56
-rw-r--r--src/com/jsyn/unitgen/UnitBinaryOperator.java41
-rw-r--r--src/com/jsyn/unitgen/UnitFilter.java47
-rw-r--r--src/com/jsyn/unitgen/UnitGate.java54
-rw-r--r--src/com/jsyn/unitgen/UnitGenerator.java355
-rw-r--r--src/com/jsyn/unitgen/UnitOscillator.java93
-rw-r--r--src/com/jsyn/unitgen/UnitSink.java43
-rw-r--r--src/com/jsyn/unitgen/UnitSource.java30
-rw-r--r--src/com/jsyn/unitgen/UnitStreamWriter.java53
-rw-r--r--src/com/jsyn/unitgen/UnitVoice.java59
-rw-r--r--src/com/jsyn/unitgen/Unzipper.java47
-rw-r--r--src/com/jsyn/unitgen/VariableRateDataReader.java29
-rw-r--r--src/com/jsyn/unitgen/VariableRateMonoReader.java115
-rw-r--r--src/com/jsyn/unitgen/VariableRateStereoReader.java113
-rw-r--r--src/com/jsyn/unitgen/WhiteNoise.java56
-rw-r--r--src/com/jsyn/unitgen/ZeroCrossingCounter.java61
-rw-r--r--src/com/jsyn/util/AudioSampleLoader.java42
-rw-r--r--src/com/jsyn/util/AudioStreamReader.java85
-rw-r--r--src/com/jsyn/util/AutoCorrelator.java293
-rw-r--r--src/com/jsyn/util/Instrument.java38
-rw-r--r--src/com/jsyn/util/InstrumentLibrary.java32
-rw-r--r--src/com/jsyn/util/JavaSoundSampleLoader.java149
-rw-r--r--src/com/jsyn/util/JavaTools.java59
-rw-r--r--src/com/jsyn/util/MultiChannelSynthesizer.java404
-rw-r--r--src/com/jsyn/util/NumericOutput.java187
-rw-r--r--src/com/jsyn/util/PolyphonicInstrument.java155
-rw-r--r--src/com/jsyn/util/PseudoRandom.java89
-rw-r--r--src/com/jsyn/util/RecursiveSequenceGenerator.java214
-rw-r--r--src/com/jsyn/util/SampleLoader.java230
-rw-r--r--src/com/jsyn/util/SignalCorrelator.java48
-rw-r--r--src/com/jsyn/util/StreamingThread.java121
-rw-r--r--src/com/jsyn/util/TransportListener.java31
-rw-r--r--src/com/jsyn/util/TransportModel.java67
-rw-r--r--src/com/jsyn/util/VoiceAllocator.java258
-rw-r--r--src/com/jsyn/util/VoiceDescription.java68
-rw-r--r--src/com/jsyn/util/VoiceOperation.java7
-rw-r--r--src/com/jsyn/util/WaveFileWriter.java293
-rw-r--r--src/com/jsyn/util/WaveRecorder.java134
-rw-r--r--src/com/jsyn/util/soundfile/AIFFFileParser.java227
-rw-r--r--src/com/jsyn/util/soundfile/AudioFileParser.java129
-rw-r--r--src/com/jsyn/util/soundfile/ChunkHandler.java49
-rw-r--r--src/com/jsyn/util/soundfile/CustomSampleLoader.java60
-rw-r--r--src/com/jsyn/util/soundfile/IFFParser.java307
-rw-r--r--src/com/jsyn/util/soundfile/WAVEFileParser.java334
248 files changed, 0 insertions, 24850 deletions
diff --git a/src/com/jsyn/JSyn.java b/src/com/jsyn/JSyn.java
deleted file mode 100644
index bbc2891..0000000
--- a/src/com/jsyn/JSyn.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright 2010 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;
-
-import java.sql.Date;
-import java.util.GregorianCalendar;
-
-import com.jsyn.devices.AudioDeviceManager;
-import com.jsyn.engine.SynthesisEngine;
-
-/**
- * JSyn Synthesizer for Java. Use this factory class to create a synthesizer. This code demonstrates
- * how to start playing a sine wave:
- *
- * <pre><code>
- // Create a context for the synthesizer.
- synth = JSyn.createSynthesizer();
-
- // Start synthesizer using default stereo output at 44100 Hz.
- synth.start();
-
- // Add a tone generator.
- synth.add( osc = new SineOscillator() );
- // Add a stereo audio output unit.
- synth.add( lineOut = new LineOut() );
-
- // Connect the oscillator to both channels of the output.
- osc.output.connect( 0, lineOut.input, 0 );
- osc.output.connect( 0, lineOut.input, 1 );
-
- // Set the frequency and amplitude for the sine wave.
- osc.frequency.set( 345.0 );
- osc.amplitude.set( 0.6 );
-
- // We only need to start the LineOut. It will pull data from the oscillator.
- lineOut.start();
-</code> </pre>
- *
- * @author Phil Burk (C) 2010 Mobileer Inc
- */
-public class JSyn {
- // Update these for every release.
- private final static int VERSION_MAJOR = 16;
- private final static int VERSION_MINOR = 8;
- private final static int VERSION_REVISION = 1;
- public final static int BUILD_NUMBER = 464;
- private final static long BUILD_TIME = new GregorianCalendar(2017,
- GregorianCalendar.OCTOBER, 16).getTime().getTime();
-
- public final static String VERSION = VERSION_MAJOR + "." + VERSION_MINOR + "."
- + VERSION_REVISION;
- public final static int VERSION_CODE = (VERSION_MAJOR << 16) + (VERSION_MINOR << 8)
- + VERSION_REVISION;
- public final static String VERSION_TEXT = "V" + VERSION + " (build " + BUILD_NUMBER + ", "
- + (new Date(BUILD_TIME)) + ")";
-
- public static Synthesizer createSynthesizer() {
- return new SynthesisEngine();
- }
-
- public static Synthesizer createSynthesizer(AudioDeviceManager audioDeviceManager) {
- return new SynthesisEngine(audioDeviceManager);
- }
-}
diff --git a/src/com/jsyn/Synthesizer.java b/src/com/jsyn/Synthesizer.java
deleted file mode 100644
index bfabb4c..0000000
--- a/src/com/jsyn/Synthesizer.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright 2010 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;
-
-import com.jsyn.devices.AudioDeviceManager;
-import com.jsyn.unitgen.UnitGenerator;
-import com.softsynth.shared.time.ScheduledCommand;
-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 {
-
- public final static int FRAMES_PER_BLOCK = 8;
-
- /**
- * Starts a background thread that generates audio using the default frame rate of 44100 and two
- * stereo output channels.
- */
- public void start();
-
- /**
- * 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.
- * <p>
- * Note that using more than 2 channels will probably require the use of JPortAudio because
- * JavaSound currently does not support more than two channels.
- * JPortAudio is available at
- * <a href="http://www.softsynth.com/jsyn/developers/download.php">http://www.softsynth.com/jsyn/developers/download.php</a>.
- * <p>
- * If you use more than 2 inputs or outputs then you will probably want to use {@link com.jsyn.unitgen.ChannelIn}
- * or {@link com.jsyn.unitgen.ChannelOut}, which can be associated with any indexed channel.
- *
- * @param frameRate in Hertz
- * @param inputDeviceID obtained from an {@link AudioDeviceManager} or pass
- * AudioDeviceManager.USE_DEFAULT_DEVICE
- * @param numInputChannels 0 for no input, 1 for mono, 2 for stereo, etcetera
- * @param ouputDeviceID obtained from an AudioDeviceManager or pass
- * AudioDeviceManager.USE_DEFAULT_DEVICE
- * @param numOutputChannels 0 for no output, 1 for mono, 2 for stereo, etcetera
- */
- public void start(int frameRate, int inputDeviceID, int numInputChannels, int ouputDeviceID,
- int numOutputChannels);
-
- /** @return JSyn version as a string */
- public String getVersion();
-
- /** @return version as an integer that always increases */
- public int getVersionCode();
-
- /** Stops the background thread that generates the audio. */
- public void stop();
-
- /**
- * 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();
-
- /** @return the frame rate in samples per second */
- public int getFrameRate();
-
- /**
- * 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);
-
- /** Removes a unit generator added using add(). */
- public void remove(UnitGenerator ugen);
-
- /** @return the current audio time in seconds */
- public double getCurrentTime();
-
- /**
- * Start a unit generator at the specified time. This is not needed if a unit generator's output
- * is connected to other units. Typically you only need to start units that have no outputs, for
- * example LineOut or ChannelOut.
- */
- public void startUnit(UnitGenerator unit, double time);
-
- public void startUnit(UnitGenerator unit, TimeStamp timeStamp);
-
- /**
- * The startUnit and stopUnit methods are mainly for internal use.
- * Please call unit.start() or unit.stop() instead.
- * @param unit
- */
- public void startUnit(UnitGenerator unit);
-
- public void stopUnit(UnitGenerator unit, double time);
-
- public void stopUnit(UnitGenerator unit, TimeStamp timeStamp);
-
- /**
- * The startUnit and stopUnit methods are mainly for internal use.
- * Please call unit.start() or unit.stop() instead.
- * @param unit
- */
- public void stopUnit(UnitGenerator unit);
-
- /**
- * Sleep until the specified audio time is reached. In non-real-time mode, this will enable the
- * synthesizer to run.
- */
- public void sleepUntil(double time) throws InterruptedException;
-
- /**
- * Sleep for the specified audio time duration. In non-real-time mode, this will enable the
- * synthesizer to run.
- */
- public void sleepFor(double duration) throws InterruptedException;
-
- /**
- * 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);
-
- /** Is JSyn running in real-time mode? */
- public boolean isRealTime();
-
- /** Create a TimeStamp using the current audio time. */
- public TimeStamp createTimeStamp();
-
- /** @return the current CPU usage as a fraction between 0.0 and 1.0 */
- public double getUsage();
-
- /** @return inverse of frameRate, to avoid expensive divides */
- public double getFramePeriod();
-
- /**
- * This count is not reset if you stop and restart.
- *
- * @return number of frames synthesized
- */
- public long getFrameCount();
-
- /** Queue a command to be processed at a specific time in the background audio thread. */
- public void scheduleCommand(TimeStamp timeStamp, ScheduledCommand command);
-
- /** Queue a command to be processed at a specific time in the background audio thread. */
- public void scheduleCommand(double time, ScheduledCommand command);
-
- /** Queue a command to be processed as soon as possible in the background audio thread. */
- 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();
-
- /**
- * Add a task that will be run repeatedly on the Audio Thread before it generates every 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 task
- */
- public void addAudioTask(Runnable task);
-
- public void removeAudioTask(Runnable task);
-
-}
diff --git a/src/com/jsyn/apps/AboutJSyn.java b/src/com/jsyn/apps/AboutJSyn.java
deleted file mode 100644
index e6c1fbd..0000000
--- a/src/com/jsyn/apps/AboutJSyn.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * 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.apps;
-
-import java.awt.GridLayout;
-
-import javax.swing.JApplet;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.SwingConstants;
-
-import com.jsyn.JSyn;
-import com.jsyn.Synthesizer;
-import com.jsyn.swing.JAppletFrame;
-import com.jsyn.swing.PortControllerFactory;
-import com.jsyn.unitgen.LineOut;
-import com.jsyn.unitgen.LinearRamp;
-import com.jsyn.unitgen.SineOscillator;
-import com.jsyn.unitgen.UnitOscillator;
-
-/**
- * Show the version of JSyn and play some sine waves. This program will be run if you double click
- * the JSyn jar file.
- *
- * @author Phil Burk (C) 2011 Mobileer Inc
- */
-public class AboutJSyn extends JApplet {
- private static final long serialVersionUID = -2704222221111608377L;
- private Synthesizer synth;
- private UnitOscillator osc1;
- private UnitOscillator osc2;
- private LinearRamp lag;
- private LineOut lineOut;
-
- @Override
- public void init() {
- synth = JSyn.createSynthesizer();
-
- // Add a tone generator.
- synth.add(osc1 = new SineOscillator());
- synth.add(osc2 = new SineOscillator());
- // Add a lag to smooth out amplitude changes and avoid pops.
- synth.add(lag = new LinearRamp());
- // Add an output mixer.
- synth.add(lineOut = new LineOut());
- // Connect the oscillator to the output.
- osc1.output.connect(0, lineOut.input, 0);
- osc2.output.connect(0, lineOut.input, 1);
-
- // Arrange the faders in a stack.
- setLayout(new GridLayout(0, 1));
-
- JPanel infoPanel = new JPanel();
- infoPanel.setLayout(new GridLayout(0, 1));
- infoPanel.add(new JLabel("About: " + synth, SwingConstants.CENTER));
- infoPanel.add(new JLabel("From: http://www.softsynth.com/", SwingConstants.CENTER));
- infoPanel.add(new JLabel("(C) 1997-2011 Mobileer Inc", SwingConstants.CENTER));
- add(infoPanel);
-
- // Set the minimum, current and maximum values for the port.
- lag.output.connect(osc1.amplitude);
- lag.output.connect(osc2.amplitude);
- lag.input.setup(0.001, 0.5, 1.0);
- lag.time.set(0.1);
- lag.input.setName("Amplitude");
- add(PortControllerFactory.createExponentialPortSlider(lag.input));
-
- osc1.frequency.setup(50.0, 300.0, 3000.0);
- osc1.frequency.setName("Frequency (Left)");
- add(PortControllerFactory.createExponentialPortSlider(osc1.frequency));
- osc2.frequency.setup(50.0, 302.0, 3000.0);
- osc2.frequency.setName("Frequency (Right)");
- add(PortControllerFactory.createExponentialPortSlider(osc2.frequency));
- validate();
- }
-
- @Override
- public void start() {
- // Start synthesizer using default stereo output at 44100 Hz.
- synth.start();
- // We only need to start the LineOut. It will pull data from the
- // oscillator.
- lineOut.start();
- }
-
- @Override
- public void stop() {
- synth.stop();
- }
-
- /* Can be run as either an application or as an applet. */
- public static void main(String args[]) {
- AboutJSyn applet = new AboutJSyn();
- JAppletFrame frame = new JAppletFrame("About JSyn", applet);
- frame.setSize(440, 300);
- frame.setVisible(true);
- frame.test();
- }
-
-}
diff --git a/src/com/jsyn/apps/InstrumentTester.java b/src/com/jsyn/apps/InstrumentTester.java
deleted file mode 100644
index 6e347cd..0000000
--- a/src/com/jsyn/apps/InstrumentTester.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright 2012 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.apps;
-
-import java.awt.BorderLayout;
-import java.io.IOException;
-
-import javax.sound.midi.MidiDevice;
-import javax.sound.midi.MidiMessage;
-import javax.sound.midi.MidiUnavailableException;
-import javax.sound.midi.Receiver;
-import javax.swing.JApplet;
-
-import com.jsyn.JSyn;
-import com.jsyn.Synthesizer;
-import com.jsyn.devices.javasound.MidiDeviceTools;
-import com.jsyn.instruments.JSynInstrumentLibrary;
-import com.jsyn.midi.MessageParser;
-import com.jsyn.swing.InstrumentBrowser;
-import com.jsyn.swing.JAppletFrame;
-import com.jsyn.swing.PresetSelectionListener;
-import com.jsyn.swing.SoundTweaker;
-import com.jsyn.unitgen.LineOut;
-import com.jsyn.unitgen.UnitSource;
-import com.jsyn.unitgen.UnitVoice;
-import com.jsyn.util.PolyphonicInstrument;
-import com.jsyn.util.VoiceDescription;
-import com.softsynth.math.AudioMath;
-import com.softsynth.shared.time.TimeStamp;
-
-/**
- * Let the user select an instrument using the InstrumentBrowser and play
- * them using the ASCII keyboard or with MIDI.
- * Sound parameters can be tweaked using faders.
- *
- * @author Phil Burk (C) 2012 Mobileer Inc
- */
-public class InstrumentTester extends JApplet {
- private static final long serialVersionUID = -2704222221111608377L;
- private Synthesizer synth;
- private LineOut lineOut;
- private SoundTweaker tweaker;
- protected PolyphonicInstrument instrument;
- private MyParser messageParser;
-
- class MyParser extends MessageParser {
-
- @Override
- public void controlChange(int channel, int index, int value) {
- }
-
- @Override
- public void noteOff(int channel, int noteNumber, int velocity) {
- instrument.noteOff(noteNumber, synth.createTimeStamp());
- }
-
- @Override
- public void noteOn(int channel, int noteNumber, int velocity) {
- double frequency = AudioMath.pitchToFrequency(noteNumber);
- double amplitude = velocity / (4 * 128.0);
- TimeStamp timeStamp = synth.createTimeStamp();
- instrument.noteOn(noteNumber, frequency, amplitude, timeStamp);
- }
-
- }
-
- // Write a Receiver to get the messages from a Transmitter.
- class CustomReceiver implements Receiver {
- @Override
- public void close() {
- System.out.print("Closed.");
- }
-
- @Override
- public void send(MidiMessage message, long timeStamp) {
- byte[] bytes = message.getMessage();
- messageParser.parse(bytes);
- }
- }
-
- public int setupMidiKeyboard() throws MidiUnavailableException, IOException, InterruptedException {
- messageParser = new MyParser();
-
- int result = 2;
- MidiDevice keyboard = MidiDeviceTools.findKeyboard();
- Receiver receiver = new CustomReceiver();
- // Just use default synthesizer.
- if (keyboard != null) {
- // If you forget to open them you will hear no sound.
- keyboard.open();
- // Put the receiver in the transmitter.
- // This gives fairly low latency playing.
- keyboard.getTransmitter().setReceiver(receiver);
- System.out.println("Play MIDI keyboard: " + keyboard.getDeviceInfo().getDescription());
- result = 0;
- } else {
- System.out.println("Could not find a keyboard.");
- }
- return result;
- }
-
- @Override
- public void init() {
- setLayout(new BorderLayout());
-
- synth = JSyn.createSynthesizer();
- synth.add(lineOut = new LineOut());
-
- InstrumentBrowser browser = new InstrumentBrowser(new JSynInstrumentLibrary());
- browser.addPresetSelectionListener(new PresetSelectionListener() {
-
- @Override
- public void presetSelected(VoiceDescription voiceDescription, int presetIndex) {
- UnitVoice[] voices = new UnitVoice[8];
- for (int i = 0; i < voices.length; i++) {
- voices[i] = voiceDescription.createUnitVoice();
- }
- instrument = new PolyphonicInstrument(voices);
- synth.add(instrument);
- instrument.usePreset(presetIndex, synth.createTimeStamp());
- String title = voiceDescription.getVoiceClassName() + ": "
- + voiceDescription.getPresetNames()[presetIndex];
- useSource(instrument, title);
- }
- });
- add(browser, BorderLayout.NORTH);
-
- try {
- setupMidiKeyboard();
- } catch (MidiUnavailableException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
-
- validate();
- }
-
- private void useSource(UnitSource voice, String title) {
-
- lineOut.input.disconnectAll(0);
- lineOut.input.disconnectAll(1);
-
- // Connect the source to both left and right output.
- voice.getOutput().connect(0, lineOut.input, 0);
- voice.getOutput().connect(0, lineOut.input, 1);
-
- if (tweaker != null) {
- remove(tweaker);
- }
- try {
- if (synth.isRunning()) {
- synth.sleepFor(0.1);
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- tweaker = new SoundTweaker(synth, title, voice);
- add(tweaker, BorderLayout.CENTER);
- validate();
- }
-
- @Override
- public void start() {
- // Start synthesizer using default stereo output at 44100 Hz.
- synth.start();
- // We only need to start the LineOut. It will pull data from the
- // oscillator.
- lineOut.start();
- }
-
- @Override
- public void stop() {
- synth.stop();
- }
-
- /* Can be run as either an application or as an applet. */
- public static void main(String args[]) {
- InstrumentTester applet = new InstrumentTester();
- JAppletFrame frame = new JAppletFrame("InstrumentTester", applet);
- frame.setSize(600, 800);
- frame.setVisible(true);
- frame.test();
- }
-
-}
diff --git a/src/com/jsyn/data/AudioSample.java b/src/com/jsyn/data/AudioSample.java
deleted file mode 100644
index dcbbae5..0000000
--- a/src/com/jsyn/data/AudioSample.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright 2010 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.data;
-
-import java.util.ArrayList;
-
-/**
- * Base class for FloatSample and ShortSample.
- *
- * @author Phil Burk (C) 2010 Mobileer Inc
- */
-public abstract class AudioSample extends SequentialDataCommon {
- protected int numFrames;
- protected int channelsPerFrame = 1;
- private double frameRate = 44100.0;
- private double pitch;
- private ArrayList<SampleMarker> markers;
-
- public abstract void allocate(int numFrames, int channelsPerFrame);
-
- @Override
- public double getRateScaler(int index, double synthesisRate) {
- return 1.0;
- }
-
- public double getFrameRate() {
- return frameRate;
- }
-
- public void setFrameRate(double f) {
- this.frameRate = f;
- }
-
- @Override
- public int getNumFrames() {
- return numFrames;
- }
-
- @Override
- public int getChannelsPerFrame() {
- return channelsPerFrame;
- }
-
- public void setChannelsPerFrame(int channelsPerFrame) {
- this.channelsPerFrame = channelsPerFrame;
- }
-
- /**
- * Set the recorded pitch as a fractional MIDI semitone value where 60 is Middle C.
- *
- * @param pitch
- */
- public void setPitch(double pitch) {
- this.pitch = pitch;
- }
-
- public double getPitch() {
- return pitch;
- }
-
- public int getMarkerCount() {
- if (markers == null)
- return 0;
- else
- return markers.size();
- }
-
- public SampleMarker getMarker(int index) {
- if (markers == null)
- return null;
- else
- return markers.get(index);
- }
-
- /**
- * Add a marker that will be stored sorted by position. This is normally used internally by the
- * SampleLoader.
- *
- * @param marker
- */
- public void addMarker(SampleMarker marker) {
- if (markers == null)
- markers = new ArrayList<SampleMarker>();
- int idx = markers.size();
- for (int k = 0; k < markers.size(); k++) {
- SampleMarker cue = markers.get(k);
- if (cue.position > marker.position) {
- idx = k;
- break;
- }
- }
- markers.add(idx, marker);
- }
-}
diff --git a/src/com/jsyn/data/DoubleTable.java b/src/com/jsyn/data/DoubleTable.java
deleted file mode 100644
index ca64c94..0000000
--- a/src/com/jsyn/data/DoubleTable.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright 2010 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.data;
-
-import com.jsyn.exceptions.ChannelMismatchException;
-
-/**
- * Evaluate a Function by interpolating between the values in a table. This can be used for
- * wavetable lookup or waveshaping.
- *
- * @author Phil Burk (C) 2010 Mobileer Inc
- */
-public class DoubleTable implements Function {
- private double[] table;
-
- public DoubleTable(int numFrames) {
- allocate(numFrames);
- }
-
- public DoubleTable(double[] data) {
- allocate(data.length);
- write(data);
- }
-
- public DoubleTable(ShortSample shortSample) {
- if (shortSample.getChannelsPerFrame() != 1) {
- throw new ChannelMismatchException("DoubleTable can only be built from mono samples.");
- }
- short[] buffer = new short[256];
- int framesLeft = shortSample.getNumFrames();
- allocate(framesLeft);
- int cursor = 0;
- while (framesLeft > 0) {
- int numTransfer = framesLeft;
- if (numTransfer > buffer.length) {
- numTransfer = buffer.length;
- }
- shortSample.read(cursor, buffer, 0, numTransfer);
- write(cursor, buffer, 0, numTransfer);
- cursor += numTransfer;
- framesLeft -= numTransfer;
- }
- }
-
- public void allocate(int numFrames) {
- table = new double[numFrames];
- }
-
- public int length() {
- return table.length;
- }
-
- public void write(double[] data) {
- write(0, data, 0, data.length);
- }
-
- public void write(int startFrame, short[] data, int startIndex, int numFrames) {
- for (int i = 0; i < numFrames; i++) {
- table[startFrame + i] = data[startIndex + i] * (1.0 / 32768.0);
- }
- }
-
- public void write(int startFrame, double[] data, int startIndex, int numFrames) {
- for (int i = 0; i < numFrames; i++) {
- table[startFrame + i] = data[startIndex + i];
- }
- }
-
- /**
- * Treat the double array as a lookup table with a domain of -1.0 to 1.0. If the input is out of
- * range then the output will clip to the end values.
- *
- * @param input
- * @return interpolated value from table
- */
- @Override
- public double evaluate(double input) {
- double interp;
- if (input < -1.0) {
- interp = table[0];
- } else if (input < 1.0) {
- double fractionalIndex = (table.length - 1) * (input - (-1.0)) / 2.0;
- // We don't need floor() because fractionalIndex >= 0.0
- int index = (int) fractionalIndex;
- double fraction = fractionalIndex - index;
-
- double s1 = table[index];
- double s2 = table[index + 1];
- interp = ((s2 - s1) * fraction) + s1;
- } else {
- interp = table[table.length - 1];
- }
- return interp;
- }
-}
diff --git a/src/com/jsyn/data/FloatSample.java b/src/com/jsyn/data/FloatSample.java
deleted file mode 100644
index 2d8c973..0000000
--- a/src/com/jsyn/data/FloatSample.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright 2010 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.data;
-
-import com.jsyn.unitgen.FixedRateMonoReader;
-import com.jsyn.unitgen.FixedRateStereoReader;
-import com.jsyn.unitgen.VariableRateMonoReader;
-import com.jsyn.unitgen.VariableRateStereoReader;
-import com.jsyn.util.SampleLoader;
-
-/**
- * Store multi-channel floating point audio data in an interleaved buffer. The values are stored as
- * 32-bit floats. You can play samples using one of the readers, for example VariableRateMonoReader.
- *
- * @author Phil Burk (C) 2010 Mobileer Inc
- * @see SampleLoader
- * @see FixedRateMonoReader
- * @see FixedRateStereoReader
- * @see VariableRateMonoReader
- * @see VariableRateStereoReader
- */
-public class FloatSample extends AudioSample implements Function {
- private float[] buffer;
-
- public FloatSample() {
- }
-
- /** Constructor for mono samples. */
- public FloatSample(int numFrames) {
- this(numFrames, 1);
- }
-
- /** Constructor for mono samples with data. */
- public FloatSample(float[] data) {
- this(data.length, 1);
- write(data);
- }
-
- /** Constructor for multi-channel samples with data. */
- public FloatSample(float[] data, int channelsPerFrame) {
- this(data.length / channelsPerFrame, channelsPerFrame);
- write(data);
- }
-
- /**
- * Create a silent sample with enough memory to hold the audio data. The number of sample
- * numbers in the array will be numFrames*channelsPerFrame.
- *
- * @param numFrames number of sample groups. A stereo frame contains 2 samples.
- * @param channelsPerFrame 1 for mono, 2 for stereo
- */
- public FloatSample(int numFrames, int channelsPerFrame) {
- allocate(numFrames, channelsPerFrame);
- }
-
- /**
- * Allocate memory to hold the audio data. The number of sample numbers in the array will be
- * numFrames*channelsPerFrame.
- *
- * @param numFrames number of sample groups. A stereo frame contains 2 samples.
- * @param channelsPerFrame 1 for mono, 2 for stereo
- */
- @Override
- public void allocate(int numFrames, int channelsPerFrame) {
- buffer = new float[numFrames * channelsPerFrame];
- this.numFrames = numFrames;
- this.channelsPerFrame = channelsPerFrame;
- }
-
- /**
- * Note that in a stereo sample, a frame has two values.
- *
- * @param startFrame index of frame in the sample
- * @param data data to be written
- * @param startIndex index of first value in array
- * @param numFrames
- */
- public void write(int startFrame, float[] data, int startIndex, int numFrames) {
- int numSamplesToWrite = numFrames * channelsPerFrame;
- int firstSampleIndexToWrite = startFrame * channelsPerFrame;
- System.arraycopy(data, startIndex, buffer, firstSampleIndexToWrite, numSamplesToWrite);
- }
-
- /**
- * Note that in a stereo sample, a frame has two values.
- *
- * @param startFrame index of frame in the sample
- * @param data array to receive the data from the sample
- * @param startIndex index of first location in array to start filling
- * @param numFrames
- */
- public void read(int startFrame, float[] data, int startIndex, int numFrames) {
- int numSamplesToRead = numFrames * channelsPerFrame;
- int firstSampleIndexToRead = startFrame * channelsPerFrame;
- System.arraycopy(buffer, firstSampleIndexToRead, data, startIndex, numSamplesToRead);
- }
-
- /**
- * Write the entire array to the sample. The sample data must have already been allocated with
- * enough room to contain the data.
- *
- * @param data
- */
- public void write(float[] data) {
- write(0, data, 0, data.length / getChannelsPerFrame());
- }
-
- public void read(float[] data) {
- read(0, data, 0, data.length / getChannelsPerFrame());
- }
-
- @Override
- public double readDouble(int index) {
- return buffer[index];
- }
-
- @Override
- public void writeDouble(int index, double value) {
- buffer[index] = (float) value;
- }
-
- /**
- * Interpolate between two adjacent samples.
- * Note that this will only work for mono, single channel samples.
- *
- * @param fractionalIndex must be >=0 and < (size-1)
- */
- public double interpolate(double fractionalIndex) {
- int index = (int) fractionalIndex;
- float phase = (float) (fractionalIndex - index);
- float source = buffer[index];
- float target = buffer[index + 1];
- return ((target - source) * phase) + source;
- }
-
- /**
- * Note that this will only work for mono, single channel samples.
- */
- @Override
- public double evaluate(double input) {
- // Input ranges from -1 to +1
- // Map it to range of sample with guard point.
- double normalizedInput = (input + 1.0) * 0.5;
- // Clip so it does not go out of range of the sample.
- if (normalizedInput < 0.0) normalizedInput = 0.0;
- else if (normalizedInput > 1.0) normalizedInput = 1.0;
- double fractionalIndex = (getNumFrames() - 1.01) * normalizedInput;
- return interpolate(fractionalIndex);
- }
-}
diff --git a/src/com/jsyn/data/Function.java b/src/com/jsyn/data/Function.java
deleted file mode 100644
index c0e6566..0000000
--- a/src/com/jsyn/data/Function.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2010 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.data;
-
-import com.jsyn.unitgen.FunctionEvaluator;
-import com.jsyn.unitgen.FunctionOscillator;
-
-/**
- * @author Phil Burk (C) 2010 Mobileer Inc
- * @see FunctionEvaluator
- * @see FunctionOscillator
- */
-public interface Function {
- /**
- * Convert an input value to an output value.
- *
- * @param input
- * @return generated value
- */
- public double evaluate(double input);
-}
diff --git a/src/com/jsyn/data/HammingWindow.java b/src/com/jsyn/data/HammingWindow.java
deleted file mode 100644
index d8e1238..0000000
--- a/src/com/jsyn/data/HammingWindow.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2009 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.data;
-
-public class HammingWindow implements SpectralWindow {
- private double[] data;
-
- /** Construct a generalized Hamming Window */
- public HammingWindow(int length, double alpha, double beta) {
- data = new double[length];
- double scaler = 2.0 * Math.PI / (length - 1);
- for (int i = 0; i < length; i++) {
- data[i] = alpha - (beta * (Math.cos(i * scaler)));
- }
- }
-
- /** Traditional Hamming Window with alpha = 25/46 and beta = 21/46 */
- public HammingWindow(int length) {
- this(length, 25.0 / 46.0, 21.0 / 46.0);
- }
-
- @Override
- public double get(int index) {
- return data[index];
- }
-
-}
diff --git a/src/com/jsyn/data/HannWindow.java b/src/com/jsyn/data/HannWindow.java
deleted file mode 100644
index 878d07c..0000000
--- a/src/com/jsyn/data/HannWindow.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2013 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.data;
-
-import com.jsyn.unitgen.SpectralFFT;
-import com.jsyn.unitgen.SpectralIFFT;
-
-/**
- * A HammingWindow with alpha and beta = 0.5.
- *
- * @author Phil Burk (C) 2013 Mobileer Inc
- * @see SpectralWindow
- * @see SpectralFFT
- * @see SpectralIFFT
- */
-public class HannWindow extends HammingWindow {
-
- public HannWindow(int length) {
- super(length, 0.5, 0.5);
- }
-
-}
diff --git a/src/com/jsyn/data/SampleMarker.java b/src/com/jsyn/data/SampleMarker.java
deleted file mode 100644
index d3db1d4..0000000
--- a/src/com/jsyn/data/SampleMarker.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright 2012 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.data;
-
-/**
- * A marker for an audio sample.
- *
- * @author (C) 2012 Phil Burk, Mobileer Inc
- */
-
-public class SampleMarker {
- /** Sample frame index. */
- public int position;
- public String name;
- public String comment;
-}
diff --git a/src/com/jsyn/data/SegmentedEnvelope.java b/src/com/jsyn/data/SegmentedEnvelope.java
deleted file mode 100644
index efdfd89..0000000
--- a/src/com/jsyn/data/SegmentedEnvelope.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright 2010 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.data;
-
-import com.jsyn.unitgen.EnvelopeDAHDSR;
-import com.jsyn.unitgen.VariableRateMonoReader;
-
-/**
- * Store an envelope as a series of line segments. Each line is described as a duration and a target
- * value. The envelope can be played using a {@link VariableRateMonoReader}. Here is an example that
- * generates an envelope that looks like a traditional ADSR envelope.
- *
- * <pre>
- * <code>
- * // Create an amplitude envelope and fill it with data.
- * double[] ampData = {
- * 0.02, 0.9, // duration,value pair 0, "attack"
- * 0.10, 0.5, // pair 1, "decay"
- * 0.50, 0.0 // pair 2, "release"
- * };
- * SegmentedEnvelope ampEnvelope = new SegmentedEnvelope( ampData );
- *
- * // Hang at end of decay segment to provide a "sustain" segment.
- * ampEnvelope.setSustainBegin( 1 );
- * ampEnvelope.setSustainEnd( 1 );
- *
- * // Play the envelope using queueOn so that it uses the sustain and release information.
- * synth.add( ampEnv = new VariableRateMonoReader() );
- * ampEnv.dataQueue.queueOn( ampEnvelope );
- * </code>
- * </pre>
- *
- * As an alternative you could use an {@link EnvelopeDAHDSR}.
- *
- * @author Phil Burk (C) 2010 Mobileer Inc
- * @see VariableRateMonoReader
- * @see EnvelopeDAHDSR
- */
-public class SegmentedEnvelope extends SequentialDataCommon {
- private double[] buffer;
-
- public SegmentedEnvelope(int maxFrames) {
- allocate(maxFrames);
- }
-
- public SegmentedEnvelope(double[] pairs) {
- this(pairs.length / 2);
- write(pairs);
- }
-
- public void allocate(int maxFrames) {
- buffer = new double[maxFrames * 2];
- this.maxFrames = maxFrames;
- this.numFrames = 0;
- }
-
- /**
- * Write frames of envelope data. A frame consists of a duration and a value.
- *
- * @param startFrame Index of frame in envelope to write to.
- * @param data Pairs of duration and value.
- * @param startIndex Index of frame in data[] to read from.
- * @param numToWrite Number of frames (pairs) to write.
- */
- public void write(int startFrame, double[] data, int startIndex, int numToWrite) {
- System.arraycopy(data, startIndex * 2, buffer, startFrame * 2, numToWrite * 2);
- if ((startFrame + numToWrite) > numFrames) {
- numFrames = startFrame + numToWrite;
- }
- }
-
- public void read(int startFrame, double[] data, int startIndex, int numToRead) {
- System.arraycopy(buffer, startFrame * 2, data, startIndex * 2, numToRead * 2);
- }
-
- public void write(double[] data) {
- write(0, data, 0, data.length / 2);
- }
-
- public void read(double[] data) {
- read(0, data, 0, data.length / 2);
- }
-
- /** Read the value of an envelope, not the duration. */
- @Override
- public double readDouble(int index) {
- return buffer[(index * 2) + 1];
- }
-
- @Override
- public void writeDouble(int index, double value) {
- buffer[(index * 2) + 1] = value;
- if ((index + 1) > numFrames) {
- numFrames = index + 1;
- }
- }
-
- @Override
- public double getRateScaler(int index, double synthesisPeriod) {
- double duration = buffer[index * 2];
- if (duration < synthesisPeriod) {
- duration = synthesisPeriod;
- }
- return 1.0 / duration;
- }
-
- @Override
- public int getChannelsPerFrame() {
- return 1;
- }
-}
diff --git a/src/com/jsyn/data/SequentialData.java b/src/com/jsyn/data/SequentialData.java
deleted file mode 100644
index 0deb5c9..0000000
--- a/src/com/jsyn/data/SequentialData.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright 2010 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.data;
-
-import com.jsyn.unitgen.FixedRateMonoReader;
-import com.jsyn.unitgen.FixedRateMonoWriter;
-import com.jsyn.unitgen.FixedRateStereoReader;
-import com.jsyn.unitgen.FixedRateStereoWriter;
-import com.jsyn.unitgen.VariableRateMonoReader;
-import com.jsyn.unitgen.VariableRateStereoReader;
-
-/**
- * Interface for objects that can be read and/or written by index. The index is not stored
- * internally so they can be shared by multiple readers.
- *
- * @author Phil Burk (C) 2010 Mobileer Inc
- * @see FixedRateMonoReader
- * @see FixedRateStereoReader
- * @see FixedRateMonoWriter
- * @see FixedRateStereoWriter
- * @see VariableRateMonoReader
- * @see VariableRateStereoReader
- */
-public interface SequentialData {
- /**
- * Write a value at the given index.
- *
- * @param index sample index is ((frameIndex * channelsPerFrame) + channelIndex)
- * @param value the value to be written
- */
- void writeDouble(int index, double value);
-
- /**
- * Read a value from the sample independently from the internal storage format.
- *
- * @param index sample index is ((frameIndex * channelsPerFrame) + channelIndex)
- */
-
- double readDouble(int index);
-
- /***
- * @return Beginning of sustain loop or -1 if no loop.
- */
- public int getSustainBegin();
-
- /**
- * SustainEnd value is the frame index of the frame just past the end of the loop. The number of
- * frames included in the loop is (SustainEnd - SustainBegin).
- *
- * @return End of sustain loop or -1 if no loop.
- */
- public int getSustainEnd();
-
- /***
- * @return Beginning of release loop or -1 if no loop.
- */
- public int getReleaseBegin();
-
- /***
- * @return End of release loop or -1 if no loop.
- */
- public int getReleaseEnd();
-
- /**
- * Get rate to play the data. In an envelope this correspond to the inverse of the frame
- * duration and would vary frame to frame. For an audio sample it is 1.0.
- *
- * @param index
- * @param synthesisRate
- * @return rate to scale the playback speed.
- */
- double getRateScaler(int index, double synthesisRate);
-
- /**
- * @return For a stereo sample, return 2.
- */
- int getChannelsPerFrame();
-
- /**
- * @return The number of valid frames that can be read.
- */
- int getNumFrames();
-}
diff --git a/src/com/jsyn/data/SequentialDataCommon.java b/src/com/jsyn/data/SequentialDataCommon.java
deleted file mode 100644
index 5cc51df..0000000
--- a/src/com/jsyn/data/SequentialDataCommon.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright 2010 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.data;
-
-/**
- * Abstract base class for envelopes and samples that adds sustain and release loops.
- *
- * @author Phil Burk (C) 2010 Mobileer Inc
- */
-public abstract class SequentialDataCommon implements SequentialData {
- protected int numFrames;
- protected int maxFrames;
- private int sustainBegin = -1;
- private int sustainEnd = -1;
- private int releaseBegin = -1;
- private int releaseEnd = -1;
-
- @Override
- public abstract void writeDouble(int index, double value);
-
- @Override
- public abstract double readDouble(int index);
-
- @Override
- public abstract double getRateScaler(int index, double synthesisRate);
-
- @Override
- public abstract int getChannelsPerFrame();
-
- /**
- * @return Maximum number of frames of data.
- */
- public int getMaxFrames() {
- return maxFrames;
- }
-
- /**
- * Set number of frames of data. Input will be clipped to maxFrames. This is useful when
- * changing the contents of a sample or envelope.
- */
- public void setNumFrames(int numFrames) {
- if (numFrames > maxFrames)
- numFrames = maxFrames;
- this.numFrames = numFrames;
- }
-
- @Override
- public int getNumFrames() {
- return numFrames;
- }
-
- // JavaDocs will be copied from SequentialData
-
- @Override
- public int getSustainBegin() {
- return this.sustainBegin;
- }
-
- @Override
- public int getSustainEnd() {
- return this.sustainEnd;
- }
-
- @Override
- public int getReleaseBegin() {
- return this.releaseBegin;
- }
-
- @Override
- public int getReleaseEnd() {
- return this.releaseEnd;
- }
-
- /**
- * Set beginning of a sustain loop. When UnitDataQueuePort.queueOn() is called,
- * if the loop is set then the attack portion will be queued followed by this sustain
- * region using queueLoop().
- * The number of frames in the loop will be (SustainEnd - SustainBegin).
- * <p>
- * For a steady sustain level, like in an ADSR envelope, set SustainBegin and
- * SustainEnd to the same frame.
- * <p>
- * For a sustain that is modulated, include two or more frames in the loop.
- *
- * @param sustainBegin
- */
- public void setSustainBegin(int sustainBegin) {
- this.sustainBegin = sustainBegin;
- }
-
- /**
- * SustainEnd value is the frame index of the frame just past the end of the loop.
- * The number of frames included in the loop is (SustainEnd - SustainBegin).
- *
- * @param sustainEnd
- */
- public void setSustainEnd(int sustainEnd) {
- this.sustainEnd = sustainEnd;
- }
-
- /**
- * The release loop behaves like the sustain loop but it is triggered
- * by UnitDataQueuePort.queueOff().
- *
- * @param releaseBegin
- */
- public void setReleaseBegin(int releaseBegin) {
- this.releaseBegin = releaseBegin;
- }
-
- /**
- * ReleaseEnd value is the frame index of the frame just past the end of the loop.
- * The number of frames included in the loop is (ReleaseEnd - ReleaseBegin).
- *
- * @param releaseEnd
- */
-
- public void setReleaseEnd(int releaseEnd) {
- this.releaseEnd = releaseEnd;
- }
-
-}
diff --git a/src/com/jsyn/data/ShortSample.java b/src/com/jsyn/data/ShortSample.java
deleted file mode 100644
index 4a4110e..0000000
--- a/src/com/jsyn/data/ShortSample.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright 2010 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.data;
-
-import com.jsyn.engine.SynthesisEngine;
-import com.jsyn.unitgen.FixedRateMonoReader;
-import com.jsyn.unitgen.FixedRateStereoReader;
-import com.jsyn.unitgen.VariableRateMonoReader;
-import com.jsyn.unitgen.VariableRateStereoReader;
-import com.jsyn.util.SampleLoader;
-
-/**
- * Store multi-channel short audio data in an interleaved buffer.
- *
- * @author Phil Burk (C) 2010 Mobileer Inc
- * @see SampleLoader
- * @see FixedRateMonoReader
- * @see FixedRateStereoReader
- * @see VariableRateMonoReader
- * @see VariableRateStereoReader
- */
-public class ShortSample extends AudioSample {
- private short[] buffer;
-
- public ShortSample() {
- }
-
- public ShortSample(int numFrames, int channelsPerFrame) {
- allocate(numFrames, channelsPerFrame);
- }
-
- /** Constructor for mono samples with data. */
- public ShortSample(short[] data) {
- this(data.length, 1);
- write(data);
- }
-
- /** Constructor for multi-channel samples with data. */
- public ShortSample(short[] data, int channelsPerFrame) {
- this(data.length / channelsPerFrame, channelsPerFrame);
- write(data);
- }
-
- @Override
- public void allocate(int numFrames, int channelsPerFrame) {
- buffer = new short[numFrames * channelsPerFrame];
- this.numFrames = numFrames;
- this.channelsPerFrame = channelsPerFrame;
- }
-
- /**
- * Note that in a stereo sample, a frame has two values.
- *
- * @param startFrame index of frame in the sample
- * @param data data to be written
- * @param startIndex index of first value in array
- * @param numFrames
- */
- public void write(int startFrame, short[] data, int startIndex, int numFrames) {
- int numSamplesToWrite = numFrames * channelsPerFrame;
- int firstSampleIndexToWrite = startFrame * channelsPerFrame;
- System.arraycopy(data, startIndex, buffer, firstSampleIndexToWrite, numSamplesToWrite);
- }
-
- /**
- * Note that in a stereo sample, a frame has two values.
- *
- * @param startFrame index of frame in the sample
- * @param data array to receive the data from the sample
- * @param startIndex index of first location in array to start filling
- * @param numFrames
- */
- public void read(int startFrame, short[] data, int startIndex, int numFrames) {
- int numSamplesToRead = numFrames * channelsPerFrame;
- int firstSampleIndexToRead = startFrame * channelsPerFrame;
- System.arraycopy(buffer, firstSampleIndexToRead, data, startIndex, numSamplesToRead);
- }
-
- public void write(short[] data) {
- write(0, data, 0, data.length);
- }
-
- public void read(short[] data) {
- read(0, data, 0, data.length);
- }
-
- public short readShort(int index) {
- return buffer[index];
- }
-
- public void writeShort(int index, short value) {
- buffer[index] = value;
- }
-
- /** Read a sample converted to a double in the range -1.0 to almost 1.0. */
- @Override
- public double readDouble(int index) {
- return SynthesisEngine.convertShortToDouble(buffer[index]);
- }
-
- /**
- * Write a double that will be clipped to the range -1.0 to almost 1.0 and converted to a short.
- */
- @Override
- public void writeDouble(int index, double value) {
- buffer[index] = SynthesisEngine.convertDoubleToShort(value);
- }
-
-}
diff --git a/src/com/jsyn/data/SpectralWindow.java b/src/com/jsyn/data/SpectralWindow.java
deleted file mode 100644
index 0fcfac4..0000000
--- a/src/com/jsyn/data/SpectralWindow.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright 2009 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.data;
-
-public interface SpectralWindow {
- public double get(int index);
-}
diff --git a/src/com/jsyn/data/SpectralWindowFactory.java b/src/com/jsyn/data/SpectralWindowFactory.java
deleted file mode 100644
index 01cced6..0000000
--- a/src/com/jsyn/data/SpectralWindowFactory.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2013 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.data;
-
-import com.jsyn.unitgen.SpectralFFT;
-import com.jsyn.unitgen.SpectralFilter;
-import com.jsyn.unitgen.SpectralIFFT;
-
-/**
- * Create shared windows as needed for use with FFTs and IFFTs.
- *
- * @author Phil Burk (C) 2013 Mobileer Inc
- * @see SpectralWindow
- * @see SpectralFFT
- * @see SpectralIFFT
- * @see SpectralFilter
- */
-public class SpectralWindowFactory {
- private static final int NUM_WINDOWS = 16;
- private static final int MIN_SIZE_LOG_2 = 2;
- private static HammingWindow[] hammingWindows = new HammingWindow[NUM_WINDOWS];
- private static HannWindow[] hannWindows = new HannWindow[NUM_WINDOWS];
-
- /** @return a shared standard HammingWindow */
- public static HammingWindow getHammingWindow(int sizeLog2) {
- int index = sizeLog2 - MIN_SIZE_LOG_2;
- if (hammingWindows[index] == null) {
- hammingWindows[index] = new HammingWindow(1 << sizeLog2);
- }
- return hammingWindows[index];
- }
-
- /** @return a shared HannWindow */
- public static HannWindow getHannWindow(int sizeLog2) {
- int index = sizeLog2 - MIN_SIZE_LOG_2;
- if (hannWindows[index] == null) {
- hannWindows[index] = new HannWindow(1 << sizeLog2);
- }
- return hannWindows[index];
- }
-}
diff --git a/src/com/jsyn/data/Spectrum.java b/src/com/jsyn/data/Spectrum.java
deleted file mode 100644
index 66e4ee4..0000000
--- a/src/com/jsyn/data/Spectrum.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright 2013 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.data;
-
-import com.jsyn.unitgen.SpectralFFT;
-import com.jsyn.unitgen.SpectralIFFT;
-import com.jsyn.unitgen.SpectralProcessor;
-
-/**
- * Complex spectrum with real and imaginary parts. The frequency associated with each bin of the
- * spectrum is:
- *
- * <pre>
- * frequency = binIndex * sampleRate / size
- * </pre>
- *
- * Note that the upper half of the spectrum is above the Nyquist frequency. Those frequencies are
- * mirrored around the Nyquist frequency. Note that this spectral API is experimental and may change
- * at any time.
- *
- * @author Phil Burk (C) 2013 Mobileer Inc
- * @version 016
- * @see SpectralFFT
- * @see SpectralIFFT
- * @see SpectralProcessor
- */
-public class Spectrum {
- private double[] real;
- private double[] imaginary;
- public static final int DEFAULT_SIZE_LOG_2 = 9;
- public static final int DEFAULT_SIZE = 1 << DEFAULT_SIZE_LOG_2;
-
- public Spectrum() {
- this(DEFAULT_SIZE);
- }
-
- public Spectrum(int size) {
- setSize(size);
- }
-
- public double[] getReal() {
- return real;
- }
-
- public double[] getImaginary() {
- return imaginary;
- }
-
- /**
- * If you change the size of the spectrum then the real and imaginary arrays will be
- * reallocated.
- *
- * @param size
- */
- public void setSize(int size) {
- if ((real == null) || (real.length != size)) {
- real = new double[size];
- imaginary = new double[size];
- }
- }
-
- public int size() {
- return real.length;
- }
-
- /**
- * Copy this spectrum to another spectrum of the same length.
- *
- * @param destination
- */
- public void copyTo(Spectrum destination) {
- assert (size() == destination.size());
- System.arraycopy(real, 0, destination.real, 0, real.length);
- System.arraycopy(imaginary, 0, destination.imaginary, 0, imaginary.length);
- }
-
- public void clear() {
- for (int i = 0; i < real.length; i++) {
- real[i] = 0.0;
- imaginary[i] = 0.0;
- }
- }
-}
diff --git a/src/com/jsyn/devices/AudioDeviceFactory.java b/src/com/jsyn/devices/AudioDeviceFactory.java
deleted file mode 100644
index 612c81d..0000000
--- a/src/com/jsyn/devices/AudioDeviceFactory.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright 2010 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.devices;
-
-import com.jsyn.util.JavaTools;
-
-/**
- * Create a device appropriate for the platform.
- *
- * @author Phil Burk (C) 2010 Mobileer Inc
- */
-public class AudioDeviceFactory {
- private static AudioDeviceManager instance;
-
- /**
- * Use a custom device interface. Overrides the selection of a default device manager.
- *
- * @param instance
- */
- public static void setInstance(AudioDeviceManager instance) {
- AudioDeviceFactory.instance = instance;
- }
-
- /**
- * Try to load JPortAudio or JavaSound devices.
- *
- * @return A device supported on this platform.
- */
- public static AudioDeviceManager createAudioDeviceManager() {
- return createAudioDeviceManager(false);
- }
-
- /**
- * Try to load JPortAudio or JavaSound devices.
- *
- * @param preferJavaSound if true then try to create a JavaSound manager before other types.
- * @return A device supported on this platform.
- */
- public static AudioDeviceManager createAudioDeviceManager(boolean preferJavaSound) {
- if (preferJavaSound) {
- tryJavaSound();
- tryJPortAudio();
- } else {
- tryJPortAudio();
- tryJavaSound();
- }
- return instance;
- }
-
- private static void tryJavaSound() {
- if (instance == null) {
- try {
- @SuppressWarnings("unchecked")
- Class<AudioDeviceManager> clazz = JavaTools.loadClass(
- "com.jsyn.devices.javasound.JavaSoundAudioDevice", false);
- if (clazz != null) {
- instance = clazz.newInstance();
- }
- } catch (Throwable e) {
- System.err.println("Could not load JavaSound device. " + e);
- }
- }
- }
-
- private static void tryJPortAudio() {
- if (instance == null) {
- try {
- if (JavaTools.loadClass("com.portaudio.PortAudio", false) != null) {
- instance = (AudioDeviceManager) JavaTools.loadClass(
- "com.jsyn.devices.jportaudio.JPortAudioDevice").newInstance();
- }
-
- } catch (Throwable e) {
- System.err.println("Could not load JPortAudio device. " + e);
- }
- }
- }
-
-}
diff --git a/src/com/jsyn/devices/AudioDeviceInputStream.java b/src/com/jsyn/devices/AudioDeviceInputStream.java
deleted file mode 100644
index a3d1854..0000000
--- a/src/com/jsyn/devices/AudioDeviceInputStream.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2009 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.devices;
-
-import com.jsyn.io.AudioInputStream;
-
-public interface AudioDeviceInputStream extends AudioInputStream {
- /** Start the input device. */
- public void start();
-
- public void stop();
-
- /**
- * @return Estimated latency in seconds.
- */
- public double getLatency();
-}
diff --git a/src/com/jsyn/devices/AudioDeviceManager.java b/src/com/jsyn/devices/AudioDeviceManager.java
deleted file mode 100644
index ac8d47c..0000000
--- a/src/com/jsyn/devices/AudioDeviceManager.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright 2010 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.devices;
-
-/**
- * Interface for an audio system. This may be implemented using JavaSound, or a native device
- * wrapper.
- *
- * @author Phil Burk (C) 2010 Mobileer Inc
- */
-public interface AudioDeviceManager {
- /**
- * Pass this value to the start method to request the default device ID.
- */
- public final static int USE_DEFAULT_DEVICE = -1;
-
- /**
- * @return The number of devices available.
- */
- public int getDeviceCount();
-
- /**
- * Get the name of an audio device.
- *
- * @param deviceID An index between 0 to deviceCount-1.
- * @return A name that can be shown to the user.
- */
- public String getDeviceName(int deviceID);
-
- /**
- * @return A name of the device manager that can be shown to the user.
- */
- public String getName();
-
- /**
- * The user can generally select a default device using a control panel that is part of the
- * operating system.
- *
- * @return The ID for the input device that the user has selected as the default.
- */
- public int getDefaultInputDeviceID();
-
- /**
- * The user can generally select a default device using a control panel that is part of the
- * operating system.
- *
- * @return The ID for the output device that the user has selected as the default.
- */
- public int getDefaultOutputDeviceID();
-
- /**
- * @param deviceID
- * @return The maximum number of channels that the device will support.
- */
- public int getMaxInputChannels(int deviceID);
-
- /**
- * @param deviceID An index between 0 to numDevices-1.
- * @return The maximum number of channels that the device will support.
- */
- public int getMaxOutputChannels(int deviceID);
-
- /**
- * This the lowest latency that the device can support reliably. It should be used for
- * applications that require low latency such as live processing of guitar signals.
- *
- * @param deviceID An index between 0 to numDevices-1.
- * @return Latency in seconds.
- */
- public double getDefaultLowInputLatency(int deviceID);
-
- /**
- * This the highest latency that the device can support. High latency is recommended for
- * applications that are not time critical, such as recording.
- *
- * @param deviceID An index between 0 to numDevices-1.
- * @return Latency in seconds.
- */
- public double getDefaultHighInputLatency(int deviceID);
-
- public double getDefaultLowOutputLatency(int deviceID);
-
- public double getDefaultHighOutputLatency(int deviceID);
-
- /**
- * Set latency in seconds for the audio device. If set to zero then the DefaultLowLatency value
- * for the device will be used. This is just a suggestion that will be used when the
- * AudioDeviceInputStream is started.
- **/
- public int setSuggestedInputLatency(double latency);
-
- public int setSuggestedOutputLatency(double latency);
-
- /**
- * Create a stream that can be used internally by JSyn for outputting audio data. Applications
- * should not call this directly.
- */
- AudioDeviceOutputStream createOutputStream(int deviceID, int frameRate, int numOutputChannels);
-
- /**
- * Create a stream that can be used internally by JSyn for acquiring audio input data.
- * Applications should not call this directly.
- */
- AudioDeviceInputStream createInputStream(int deviceID, int frameRate, int numInputChannels);
-
-}
diff --git a/src/com/jsyn/devices/AudioDeviceOutputStream.java b/src/com/jsyn/devices/AudioDeviceOutputStream.java
deleted file mode 100644
index 5c17efb..0000000
--- a/src/com/jsyn/devices/AudioDeviceOutputStream.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright 2009 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.devices;
-
-import com.jsyn.io.AudioOutputStream;
-
-public interface AudioDeviceOutputStream extends AudioOutputStream {
- public void start();
-
- public void stop();
-
- /**
- * @return Estimated latency in seconds.
- */
- public double getLatency();
-}
diff --git a/src/com/jsyn/devices/javasound/JavaSoundAudioDevice.java b/src/com/jsyn/devices/javasound/JavaSoundAudioDevice.java
deleted file mode 100644
index 656dc1c..0000000
--- a/src/com/jsyn/devices/javasound/JavaSoundAudioDevice.java
+++ /dev/null
@@ -1,431 +0,0 @@
-/*
- * Copyright 2009 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.devices.javasound;
-
-import java.util.ArrayList;
-import java.util.logging.Logger;
-
-import javax.sound.sampled.AudioFormat;
-import javax.sound.sampled.AudioSystem;
-import javax.sound.sampled.DataLine;
-import javax.sound.sampled.Line;
-import javax.sound.sampled.LineUnavailableException;
-import javax.sound.sampled.Mixer;
-import javax.sound.sampled.SourceDataLine;
-import javax.sound.sampled.TargetDataLine;
-
-import com.jsyn.devices.AudioDeviceInputStream;
-import com.jsyn.devices.AudioDeviceManager;
-import com.jsyn.devices.AudioDeviceOutputStream;
-
-/**
- * Use JavaSound to access the audio hardware.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public class JavaSoundAudioDevice implements AudioDeviceManager {
- private static final int BYTES_PER_SAMPLE = 2;
- private static final boolean USE_BIG_ENDIAN = false;
-
- ArrayList<DeviceInfo> deviceRecords;
- private double suggestedOutputLatency = 0.040;
- private double suggestedInputLatency = 0.100;
- private int defaultInputDeviceID = -1;
- private int defaultOutputDeviceID = -1;
-
- static Logger logger = Logger.getLogger(JavaSoundAudioDevice.class.getName());
-
- public JavaSoundAudioDevice() {
- String osName = System.getProperty("os.name");
- if (osName.contains("Windows")) {
- suggestedOutputLatency = 0.08;
- logger.info("JSyn: default output latency set to "
- + ((int) (suggestedOutputLatency * 1000)) + " msec for " + osName);
- }
- deviceRecords = new ArrayList<DeviceInfo>();
- sniffAvailableMixers();
- dumpAvailableMixers();
- }
-
- private void dumpAvailableMixers() {
- for (DeviceInfo deviceInfo : deviceRecords) {
- logger.fine("" + deviceInfo);
- }
- }
-
- /**
- * Build device info and determine default devices.
- */
- private void sniffAvailableMixers() {
- Mixer.Info[] mixers = AudioSystem.getMixerInfo();
- for (int i = 0; i < mixers.length; i++) {
- DeviceInfo deviceInfo = new DeviceInfo();
-
- deviceInfo.name = mixers[i].getName();
- Mixer mixer = AudioSystem.getMixer(mixers[i]);
-
- Line.Info[] lines = mixer.getTargetLineInfo();
- deviceInfo.maxInputs = scanMaxChannels(lines);
- // Remember first device that supports input.
- if ((defaultInputDeviceID < 0) && (deviceInfo.maxInputs > 0)) {
- defaultInputDeviceID = i;
- }
-
- lines = mixer.getSourceLineInfo();
- deviceInfo.maxOutputs = scanMaxChannels(lines);
- // Remember first device that supports output.
- if ((defaultOutputDeviceID < 0) && (deviceInfo.maxOutputs > 0)) {
- defaultOutputDeviceID = i;
- }
-
- deviceRecords.add(deviceInfo);
- }
- }
-
- private int scanMaxChannels(Line.Info[] lines) {
- int maxChannels = 0;
- for (Line.Info line : lines) {
- if (line instanceof DataLine.Info) {
- int numChannels = scanMaxChannels(((DataLine.Info) line));
- if (numChannels > maxChannels) {
- maxChannels = numChannels;
- }
- }
- }
- return maxChannels;
- }
-
- private int scanMaxChannels(DataLine.Info info) {
- int maxChannels = 0;
- for (AudioFormat format : info.getFormats()) {
- int numChannels = format.getChannels();
- if (numChannels > maxChannels) {
- maxChannels = numChannels;
- }
- }
- return maxChannels;
- }
-
- class DeviceInfo {
- String name;
- int maxInputs;
- int maxOutputs;
-
- @Override
- public String toString() {
- return "AudioDevice: " + name + ", max in = " + maxInputs + ", max out = " + maxOutputs;
- }
- }
-
- private class JavaSoundStream {
- AudioFormat format;
- byte[] bytes;
- int frameRate;
- int deviceID;
- int samplesPerFrame;
-
- public JavaSoundStream(int deviceID, int frameRate, int samplesPerFrame) {
- this.deviceID = deviceID;
- this.frameRate = frameRate;
- this.samplesPerFrame = samplesPerFrame;
- format = new AudioFormat(frameRate, 16, samplesPerFrame, true, USE_BIG_ENDIAN);
- }
-
- Line getDataLine(DataLine.Info info) throws LineUnavailableException {
- Line dataLine;
- if (deviceID >= 0) {
- Mixer.Info[] mixers = AudioSystem.getMixerInfo();
- Mixer mixer = AudioSystem.getMixer(mixers[deviceID]);
- dataLine = mixer.getLine(info);
- } else {
- dataLine = AudioSystem.getLine(info);
- }
- return dataLine;
- }
-
- int calculateBufferSize(double suggestedOutputLatency) {
- int numFrames = (int) (suggestedOutputLatency * frameRate);
- int numBytes = numFrames * samplesPerFrame * BYTES_PER_SAMPLE;
- return numBytes;
- }
-
- }
-
- private class JavaSoundOutputStream extends JavaSoundStream implements AudioDeviceOutputStream {
- SourceDataLine line;
-
- public JavaSoundOutputStream(int deviceID, int frameRate, int samplesPerFrame) {
- super(deviceID, frameRate, samplesPerFrame);
- }
-
- @Override
- public void start() {
- DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
- if (!AudioSystem.isLineSupported(info)) {
- // Handle the error.
- logger.severe("JavaSoundOutputStream - not supported." + format);
- } else {
- try {
- line = (SourceDataLine) getDataLine(info);
- int bufferSize = calculateBufferSize(suggestedOutputLatency);
- line.open(format, bufferSize);
- logger.fine("Output buffer size = " + bufferSize + " bytes.");
- line.start();
-
- } catch (Exception e) {
- e.printStackTrace();
- line = null;
- }
- }
- }
-
- /** Grossly inefficient. Call the array version instead. */
- @Override
- public void write(double value) {
- double[] buffer = new double[1];
- buffer[0] = value;
- write(buffer, 0, 1);
- }
-
- @Override
- public void write(double[] buffer) {
- write(buffer, 0, buffer.length);
- }
-
- @Override
- public void write(double[] buffer, int start, int count) {
- // Allocate byte buffer if needed.
- if ((bytes == null) || ((bytes.length * 2) < count)) {
- bytes = new byte[count * 2];
- }
-
- // Convert float samples to LittleEndian bytes.
- int byteIndex = 0;
- for (int i = 0; i < count; i++) {
- // Offset before casting so that we can avoid using floor().
- // Also round by adding 0.5 so that very small signals go to zero.
- double temp = (32767.0 * buffer[i + start]) + 32768.5;
- int sample = ((int) temp) - 32768;
- if (sample > Short.MAX_VALUE) {
- sample = Short.MAX_VALUE;
- } else if (sample < Short.MIN_VALUE) {
- sample = Short.MIN_VALUE;
- }
- bytes[byteIndex++] = (byte) sample; // little end
- bytes[byteIndex++] = (byte) (sample >> 8); // big end
- }
-
- line.write(bytes, 0, byteIndex);
- }
-
- @Override
- public void stop() {
- if (line != null) {
- line.stop();
- line.flush();
- line.close();
- line = null;
- } else {
- new RuntimeException("AudioOutput stop attempted when no line created.")
- .printStackTrace();
- }
- }
-
- @Override
- public double getLatency() {
- if (line == null) {
- return 0.0;
- }
- int numBytes = line.getBufferSize();
- int numFrames = numBytes / (BYTES_PER_SAMPLE * samplesPerFrame);
- return ((double) numFrames) / frameRate;
- }
-
- @Override
- public void close() {
- }
-
- }
-
- private class JavaSoundInputStream extends JavaSoundStream implements AudioDeviceInputStream {
- TargetDataLine line;
-
- public JavaSoundInputStream(int deviceID, int frameRate, int samplesPerFrame) {
- super(deviceID, frameRate, samplesPerFrame);
- }
-
- @Override
- public void start() {
- DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
- if (!AudioSystem.isLineSupported(info)) {
- // Handle the error.
- logger.severe("JavaSoundInputStream - not supported." + format);
- } else {
- try {
- line = (TargetDataLine) getDataLine(info);
- int bufferSize = calculateBufferSize(suggestedInputLatency);
- line.open(format, bufferSize);
- logger.fine("Input buffer size = " + bufferSize + " bytes.");
- line.start();
- } catch (Exception e) {
- e.printStackTrace();
- line = null;
- }
- }
- }
-
- @Override
- public double read() {
- double[] buffer = new double[1];
- read(buffer, 0, 1);
- return buffer[0];
- }
-
- @Override
- public int read(double[] buffer) {
- return read(buffer, 0, buffer.length);
- }
-
- @Override
- public int read(double[] buffer, int start, int count) {
- // Allocate byte buffer if needed.
- if ((bytes == null) || ((bytes.length * 2) < count)) {
- bytes = new byte[count * 2];
- }
- int bytesRead = line.read(bytes, 0, bytes.length);
-
- // Convert BigEndian bytes to float samples
- int bi = 0;
- for (int i = 0; i < count; i++) {
- int sample = bytes[bi++] & 0x00FF; // little end
- sample = sample + (bytes[bi++] << 8); // big end
- buffer[i + start] = sample * (1.0 / 32767.0);
- }
- return bytesRead / 4;
- }
-
- @Override
- public void stop() {
- if (line != null) {
- line.drain();
- line.close();
- } else {
- new RuntimeException("AudioInput stop attempted when no line created.")
- .printStackTrace();
- }
- }
-
- @Override
- public double getLatency() {
- if (line == null) {
- return 0.0;
- }
- int numBytes = line.getBufferSize();
- int numFrames = numBytes / (BYTES_PER_SAMPLE * samplesPerFrame);
- return ((double) numFrames) / frameRate;
- }
-
- @Override
- public int available() {
- return line.available() / BYTES_PER_SAMPLE;
- }
-
- @Override
- public void close() {
- }
-
- }
-
- @Override
- public AudioDeviceOutputStream createOutputStream(int deviceID, int frameRate,
- int samplesPerFrame) {
- return new JavaSoundOutputStream(deviceID, frameRate, samplesPerFrame);
- }
-
- @Override
- public AudioDeviceInputStream createInputStream(int deviceID, int frameRate, int samplesPerFrame) {
- return new JavaSoundInputStream(deviceID, frameRate, samplesPerFrame);
- }
-
- @Override
- public double getDefaultHighInputLatency(int deviceID) {
- return 0.300;
- }
-
- @Override
- public double getDefaultHighOutputLatency(int deviceID) {
- return 0.300;
- }
-
- @Override
- public int getDefaultInputDeviceID() {
- return defaultInputDeviceID;
- }
-
- @Override
- public int getDefaultOutputDeviceID() {
- return defaultOutputDeviceID;
- }
-
- @Override
- public double getDefaultLowInputLatency(int deviceID) {
- return 0.100;
- }
-
- @Override
- public double getDefaultLowOutputLatency(int deviceID) {
- return 0.100;
- }
-
- @Override
- public int getDeviceCount() {
- return deviceRecords.size();
- }
-
- @Override
- public String getDeviceName(int deviceID) {
- return deviceRecords.get(deviceID).name;
- }
-
- @Override
- public int getMaxInputChannels(int deviceID) {
- return deviceRecords.get(deviceID).maxInputs;
- }
-
- @Override
- public int getMaxOutputChannels(int deviceID) {
- return deviceRecords.get(deviceID).maxOutputs;
- }
-
- @Override
- public int setSuggestedOutputLatency(double latency) {
- suggestedOutputLatency = latency;
- return 0;
- }
-
- @Override
- public int setSuggestedInputLatency(double latency) {
- suggestedInputLatency = latency;
- return 0;
- }
-
- @Override
- public String getName() {
- return "JavaSound";
- }
-
-}
diff --git a/src/com/jsyn/devices/javasound/MidiDeviceTools.java b/src/com/jsyn/devices/javasound/MidiDeviceTools.java
deleted file mode 100644
index 413beca..0000000
--- a/src/com/jsyn/devices/javasound/MidiDeviceTools.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright 2009 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.devices.javasound;
-
-import javax.sound.midi.MidiDevice;
-import javax.sound.midi.MidiSystem;
-import javax.sound.midi.MidiUnavailableException;
-import javax.sound.midi.Sequencer;
-import javax.sound.midi.Synthesizer;
-
-public class MidiDeviceTools {
- /** Print the available MIDI Devices. */
- public static void listDevices() {
- // Ask the MidiSystem what is available.
- MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
- // Print info about each device.
- for (MidiDevice.Info info : infos) {
- System.out.println("MIDI Info: " + info.getDescription() + ", " + info.getName() + ", "
- + info.getVendor() + ", " + info.getVersion());
- // Get the device for more information.
- try {
- MidiDevice device = MidiSystem.getMidiDevice(info);
- System.out.println(" Device: " + ", #recv = " + device.getMaxReceivers()
- + ", #xmit = " + device.getMaxTransmitters() + ", open = "
- + device.isOpen() + ", " + device);
- } catch (MidiUnavailableException e) {
- e.printStackTrace();
- }
- }
- }
-
- /** Find a MIDI transmitter that contains text in the name. */
- public static MidiDevice findKeyboard(String text) {
- MidiDevice keyboard = null;
- // Ask the MidiSystem what is available.
- MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
- // Print info about each device.
- for (MidiDevice.Info info : infos) {
- try {
- MidiDevice device = MidiSystem.getMidiDevice(info);
- // Hardware devices are not Synthesizers or Sequencers.
- if (!(device instanceof Synthesizer) && !(device instanceof Sequencer)) {
- // Is this a transmitter?
- // Might be -1 if unlimited.
- if (device.getMaxTransmitters() != 0) {
- if ((text == null)
- || (info.getDescription().toLowerCase()
- .contains(text.toLowerCase()))) {
- keyboard = device;
- System.out.println("Chose: " + info.getDescription());
- break;
- }
- }
- }
- } catch (MidiUnavailableException e) {
- e.printStackTrace();
- }
- }
- return keyboard;
- }
-
- public static MidiDevice findKeyboard() {
- return findKeyboard(null);
- }
-
-}
diff --git a/src/com/jsyn/devices/jportaudio/JPortAudioDevice.java b/src/com/jsyn/devices/jportaudio/JPortAudioDevice.java
deleted file mode 100644
index a8e574a..0000000
--- a/src/com/jsyn/devices/jportaudio/JPortAudioDevice.java
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * Copyright 2009 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.devices.jportaudio;
-
-import com.jsyn.devices.AudioDeviceInputStream;
-import com.jsyn.devices.AudioDeviceManager;
-import com.jsyn.devices.AudioDeviceOutputStream;
-import com.portaudio.BlockingStream;
-import com.portaudio.DeviceInfo;
-import com.portaudio.HostApiInfo;
-import com.portaudio.PortAudio;
-import com.portaudio.StreamParameters;
-
-public class JPortAudioDevice implements AudioDeviceManager {
- private double suggestedOutputLatency = 0.030;
- private double suggestedInputLatency = 0.050;
- private static final int FRAMES_PER_BUFFER = 128;
-
- // static Logger logger = Logger.getLogger( JPortAudioDevice.class.getName() );
-
- public JPortAudioDevice() {
- PortAudio.initialize();
- }
-
- @Override
- public int getDeviceCount() {
- return PortAudio.getDeviceCount();
- }
-
- @Override
- public String getDeviceName(int deviceID) {
- DeviceInfo deviceInfo = PortAudio.getDeviceInfo(deviceID);
- HostApiInfo hostInfo = PortAudio.getHostApiInfo(deviceInfo.hostApi);
- return deviceInfo.name + " - " + hostInfo.name;
- }
-
- @Override
- public int getDefaultInputDeviceID() {
- return PortAudio.getDefaultInputDevice();
- }
-
- @Override
- public int getDefaultOutputDeviceID() {
- return PortAudio.getDefaultOutputDevice();
- }
-
- @Override
- public int getMaxInputChannels(int deviceID) {
- if (deviceID < 0) {
- deviceID = PortAudio.getDefaultInputDevice();
- }
- return PortAudio.getDeviceInfo(deviceID).maxInputChannels;
- }
-
- @Override
- public int getMaxOutputChannels(int deviceID) {
- if (deviceID < 0) {
- deviceID = PortAudio.getDefaultOutputDevice();
- }
- return PortAudio.getDeviceInfo(deviceID).maxOutputChannels;
- }
-
- @Override
- public double getDefaultLowInputLatency(int deviceID) {
- if (deviceID < 0) {
- deviceID = PortAudio.getDefaultInputDevice();
- }
- return PortAudio.getDeviceInfo(deviceID).defaultLowInputLatency;
- }
-
- @Override
- public double getDefaultHighInputLatency(int deviceID) {
- if (deviceID < 0) {
- deviceID = PortAudio.getDefaultInputDevice();
- }
- return PortAudio.getDeviceInfo(deviceID).defaultHighInputLatency;
- }
-
- @Override
- public double getDefaultLowOutputLatency(int deviceID) {
- if (deviceID < 0) {
- deviceID = PortAudio.getDefaultOutputDevice();
- }
- return PortAudio.getDeviceInfo(deviceID).defaultLowOutputLatency;
- }
-
- @Override
- public double getDefaultHighOutputLatency(int deviceID) {
- if (deviceID < 0) {
- deviceID = PortAudio.getDefaultOutputDevice();
- }
- return PortAudio.getDeviceInfo(deviceID).defaultHighOutputLatency;
- }
-
- @Override
- public int setSuggestedOutputLatency(double latency) {
- suggestedOutputLatency = latency;
- return 0;
- }
-
- @Override
- public int setSuggestedInputLatency(double latency) {
- suggestedInputLatency = latency;
- return 0;
- }
-
- @Override
- public AudioDeviceOutputStream createOutputStream(int deviceID, int frameRate,
- int samplesPerFrame) {
- return new JPAOutputStream(deviceID, frameRate, samplesPerFrame);
- }
-
- @Override
- public AudioDeviceInputStream createInputStream(int deviceID, int frameRate, int samplesPerFrame) {
- return new JPAInputStream(deviceID, frameRate, samplesPerFrame);
- }
-
- private class JPAStream {
- BlockingStream blockingStream;
- float[] floatBuffer = null;
- int samplesPerFrame;
-
- public void close() {
- blockingStream.close();
- }
-
- public void start() {
- blockingStream.start();
- }
-
- public void stop() {
- blockingStream.stop();
- }
-
- }
-
- private class JPAOutputStream extends JPAStream implements AudioDeviceOutputStream {
-
- private JPAOutputStream(int deviceID, int frameRate, int samplesPerFrame) {
- this.samplesPerFrame = samplesPerFrame;
- StreamParameters streamParameters = new StreamParameters();
- streamParameters.channelCount = samplesPerFrame;
- if (deviceID < 0) {
- deviceID = PortAudio.getDefaultOutputDevice();
- }
- streamParameters.device = deviceID;
- streamParameters.suggestedLatency = suggestedOutputLatency;
- int flags = 0;
- System.out.println("Audio output on " + getDeviceName(deviceID));
- blockingStream = PortAudio.openStream(null, streamParameters, frameRate,
- FRAMES_PER_BUFFER, flags);
- }
-
- /** Grossly inefficient. Call the array version instead. */
- @Override
- public void write(double value) {
- double[] buffer = new double[1];
- buffer[0] = value;
- write(buffer, 0, 1);
- }
-
- @Override
- public void write(double[] buffer) {
- write(buffer, 0, buffer.length);
- }
-
- @Override
- public void write(double[] buffer, int start, int count) {
- // Allocate float buffer if needed.
- if ((floatBuffer == null) || (floatBuffer.length < count)) {
- floatBuffer = new float[count];
- }
- for (int i = 0; i < count; i++) {
-
- floatBuffer[i] = (float) buffer[i + start];
- }
- blockingStream.write(floatBuffer, count / samplesPerFrame);
- }
-
- @Override
- public double getLatency() {
- return blockingStream.getInfo().outputLatency;
- }
- }
-
- private class JPAInputStream extends JPAStream implements AudioDeviceInputStream {
- private JPAInputStream(int deviceID, int frameRate, int samplesPerFrame) {
- this.samplesPerFrame = samplesPerFrame;
- StreamParameters streamParameters = new StreamParameters();
- streamParameters.channelCount = samplesPerFrame;
- if (deviceID < 0) {
- deviceID = PortAudio.getDefaultInputDevice();
- }
- streamParameters.device = deviceID;
- streamParameters.suggestedLatency = suggestedInputLatency;
- int flags = 0;
- System.out.println("Audio input from " + getDeviceName(deviceID));
- blockingStream = PortAudio.openStream(streamParameters, null, frameRate,
- FRAMES_PER_BUFFER, flags);
- }
-
- @Override
- public double read() {
- double[] buffer = new double[1];
- read(buffer, 0, 1);
- return buffer[0];
- }
-
- @Override
- public int read(double[] buffer) {
- return read(buffer, 0, buffer.length);
- }
-
- @Override
- public int read(double[] buffer, int start, int count) {
- // Allocate float buffer if needed.
- if ((floatBuffer == null) || (floatBuffer.length < count)) {
- floatBuffer = new float[count];
- }
- blockingStream.read(floatBuffer, count / samplesPerFrame);
-
- for (int i = 0; i < count; i++) {
-
- buffer[i + start] = floatBuffer[i];
- }
- return count;
- }
-
- @Override
- public double getLatency() {
- return blockingStream.getInfo().inputLatency;
- }
-
- @Override
- public int available() {
- return blockingStream.getReadAvailable() * samplesPerFrame;
- }
-
- }
-
- @Override
- public String getName() {
- return "JPortAudio";
- }
-}
diff --git a/src/com/jsyn/engine/LoadAnalyzer.java b/src/com/jsyn/engine/LoadAnalyzer.java
deleted file mode 100644
index cbf7ed5..0000000
--- a/src/com/jsyn/engine/LoadAnalyzer.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright 2009 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.engine;
-
-/** Measure CPU load. */
-public class LoadAnalyzer {
- private long stopTime;
- private long previousStopTime;
- private long startTime;
- private double averageTotalTime;
- private double averageOnTime;
-
- protected LoadAnalyzer() {
- stopTime = System.nanoTime();
- }
-
- /**
- * Call this when you stop doing something. Ideally all of the time since start() was spent on
- * doing something without interruption.
- */
- public void stop() {
- previousStopTime = stopTime;
- stopTime = System.nanoTime();
- long onTime = stopTime - startTime;
- long totalTime = stopTime - previousStopTime;
- if (totalTime > 0) {
- // Recursive averaging filter.
- double rate = 0.01;
- averageOnTime = (averageOnTime * (1.0 - rate)) + (onTime * rate);
- averageTotalTime = (averageTotalTime * (1.0 - rate)) + (totalTime * rate);
- }
- }
-
- /** Call this when you start doing something. */
- public void start() {
- startTime = System.nanoTime();
- }
-
- /** Calculate, on average, how much of the time was spent doing something. */
- public double getAverageLoad() {
- if (averageTotalTime > 0.0) {
- return averageOnTime / averageTotalTime;
- } else {
- return 0.0;
- }
- }
-}
diff --git a/src/com/jsyn/engine/MultiTable.java b/src/com/jsyn/engine/MultiTable.java
deleted file mode 100644
index 6606639..0000000
--- a/src/com/jsyn/engine/MultiTable.java
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright 2009 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.engine;
-
-/*
- * Multiple tables of sawtooth data.
- * organized by octaves below the Nyquist Rate.
- * used to generate band-limited Sawtooth, Impulse, Pulse, Square and Triangle BL waveforms
- *
- <pre>
- Analysis of octave requirements for tables.
-
- OctavesIndex Frequency Partials
- 0 N/2 11025 1
- 1 N/4 5512 2
- 2 N/8 2756 4
- 3 N/16 1378 8
- 4 N/32 689 16
- 5 N/64 344 32
- 6 N/128 172 64
- 7 N/256 86 128
- </pre>
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public class MultiTable {
-
- public final static int NUM_TABLES = 8;
- public final static int CYCLE_SIZE = (1 << 10);
-
- private static MultiTable instance = new MultiTable(NUM_TABLES, CYCLE_SIZE);
- private double phaseScalar;
- private float[][] tables; // array of array of tables
-
- /**************************************************************************
- * Initialize sawtooth wavetables. Table[0] should contain a pure sine wave. Succeeding tables
- * should have increasing numbers of partials.
- */
- public MultiTable(int numTables, int cycleSize) {
- int tableSize = cycleSize + 1;
-
- // Allocate array of arrays.
- tables = new float[numTables][tableSize];
-
- float[] sineTable = tables[0];
-
- phaseScalar = (float) (cycleSize * 0.5);
-
- /* Fill initial sine table with values for -PI to PI. */
- for (int j = 0; j < tableSize; j++) {
- sineTable[j] = (float) Math.sin(((((double) j) / (double) cycleSize) * Math.PI * 2.0)
- - Math.PI);
- }
-
- /*
- * Build each table from scratch and scale partials by raised cosine* to eliminate Gibbs
- * effect.
- */
- for (int i = 1; i < numTables; i++) {
- int numPartials;
- double kGibbs;
- float[] table = tables[i];
-
- /* Add together partials for this table. */
- numPartials = 1 << i;
- kGibbs = Math.PI / (2 * numPartials);
- for (int k = 0; k < numPartials; k++) {
- double ampl, cGibbs;
- int sineIndex = 0;
- int partial = k + 1;
- cGibbs = Math.cos(k * kGibbs);
- /* Calculate amplitude for Nth partial */
- ampl = cGibbs * cGibbs / partial;
-
- for (int j = 0; j < tableSize; j++) {
- table[j] += (float) ampl * sineTable[sineIndex];
- sineIndex += partial;
- /* Wrap index at end of table.. */
- if (sineIndex >= cycleSize) {
- sineIndex -= cycleSize;
- }
- }
- }
- }
-
- /* Normalize after */
- for (int i = 1; i < numTables; i++) {
- normalizeArray(tables[i]);
- }
- }
-
- /**************************************************************************/
- public static float normalizeArray(float[] fdata) {
- float max, val, gain;
- int i;
-
- // determine maximum value.
- max = 0.0f;
- for (i = 0; i < fdata.length; i++) {
- val = Math.abs(fdata[i]);
- if (val > max)
- max = val;
- }
- if (max < 0.0000001f)
- max = 0.0000001f;
- // scale array
- gain = 1.0f / max;
- for (i = 0; i < fdata.length; i++)
- fdata[i] *= gain;
- return gain;
- }
-
- /*****************************************************************************
- * When the phaseInc maps to the highest level table, then we start interpolating between the
- * highest table and the raw sawtooth value (phase). When phaseInc points to highest table:
- * flevel = NUM_TABLES - 1 = -1 - log2(pInc); log2(pInc) = - NUM_TABLES pInc = 2**(-NUM_TABLES)
- */
- private final static double LOWEST_PHASE_INC_INV = (1 << NUM_TABLES);
-
- /**************************************************************************/
- /* Phase ranges from -1.0 to +1.0 */
- public double calculateSawtooth(double currentPhase, double positivePhaseIncrement,
- double flevel) {
- float[] tableBase;
- double val;
- double hiSam; /* Use when verticalFraction is 1.0 */
- double loSam; /* Use when verticalFraction is 0.0 */
- double sam1, sam2;
-
- /* Use Phase to determine sampleIndex into table. */
- double findex = ((phaseScalar * currentPhase) + phaseScalar);
- // findex is > 0 so we do not need to call floor().
- int sampleIndex = (int) findex;
- double horizontalFraction = findex - sampleIndex;
- int tableIndex = (int) flevel;
-
- if (tableIndex > (NUM_TABLES - 2)) {
- /*
- * Just use top table and mix with arithmetic sawtooth if below lowest frequency.
- * Generate new fraction for interpolating between 0.0 and lowest table frequency.
- */
- double fraction = positivePhaseIncrement * LOWEST_PHASE_INC_INV;
- tableBase = tables[(NUM_TABLES - 1)];
-
- /* Get adjacent samples. Assume guard point present. */
- sam1 = tableBase[sampleIndex];
- sam2 = tableBase[sampleIndex + 1];
- /* Interpolate between adjacent samples. */
- loSam = sam1 + (horizontalFraction * (sam2 - sam1));
-
- /* Use arithmetic version for low frequencies. */
- /* fraction is 0.0 at 0 Hz */
- val = currentPhase + (fraction * (loSam - currentPhase));
- } else {
-
- double verticalFraction = flevel - tableIndex;
-
- if (tableIndex < 0) {
- if (tableIndex < -1) // above Nyquist!
- {
- val = 0.0;
- } else {
- /*
- * At top of supported range, interpolate between 0.0 and first partial.
- */
- tableBase = tables[0]; /* Sine wave table. */
-
- /* Get adjacent samples. Assume guard point present. */
- sam1 = tableBase[sampleIndex];
- sam2 = tableBase[sampleIndex + 1];
-
- /* Interpolate between adjacent samples. */
- hiSam = sam1 + (horizontalFraction * (sam2 - sam1));
- /* loSam = 0.0 */
- // verticalFraction is 0.0 at Nyquist
- val = verticalFraction * hiSam;
- }
- } else {
- /*
- * Interpolate between adjacent levels to prevent harmonics from popping.
- */
- tableBase = tables[tableIndex + 1];
-
- /* Get adjacent samples. Assume guard point present. */
- sam1 = tableBase[sampleIndex];
- sam2 = tableBase[sampleIndex + 1];
-
- /* Interpolate between adjacent samples. */
- hiSam = sam1 + (horizontalFraction * (sam2 - sam1));
-
- /* Get adjacent samples. Assume guard point present. */
- tableBase = tables[tableIndex];
- sam1 = tableBase[sampleIndex];
- sam2 = tableBase[sampleIndex + 1];
-
- /* Interpolate between adjacent samples. */
- loSam = sam1 + (horizontalFraction * (sam2 - sam1));
-
- val = loSam + (verticalFraction * (hiSam - loSam));
- }
- }
- return val;
- }
-
- public double convertPhaseIncrementToLevel(double positivePhaseIncrement) {
- if (positivePhaseIncrement < 1.0e-30) {
- positivePhaseIncrement = 1.0e-30;
- }
- return -1.0 - (Math.log(positivePhaseIncrement) / Math.log(2.0));
- }
-
- public static MultiTable getInstance() {
- return instance;
- }
-
-}
diff --git a/src/com/jsyn/engine/SynthesisEngine.java b/src/com/jsyn/engine/SynthesisEngine.java
deleted file mode 100644
index b49e78e..0000000
--- a/src/com/jsyn/engine/SynthesisEngine.java
+++ /dev/null
@@ -1,698 +0,0 @@
-/*
- * Copyright 2009 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.engine;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.logging.Logger;
-
-import com.jsyn.JSyn;
-import com.jsyn.Synthesizer;
-import com.jsyn.devices.AudioDeviceFactory;
-import com.jsyn.devices.AudioDeviceInputStream;
-import com.jsyn.devices.AudioDeviceManager;
-import com.jsyn.devices.AudioDeviceOutputStream;
-import com.jsyn.unitgen.UnitGenerator;
-import com.softsynth.shared.time.ScheduledCommand;
-import com.softsynth.shared.time.ScheduledQueue;
-import com.softsynth.shared.time.TimeStamp;
-
-//TODO Resolve problem with HearDAHDSR where "Rate" port.set is not reflected in knob. Engine not running.
-//TODO new tutorial and docs on website
-//TODO AutoStop on DAHDSR
-//TODO Test/example SequentialData queueOn and queueOff
-
-//TODO Abstract device interface. File device!
-//TODO Measure thread switching sync, performance for multi-core synthesis. Use 4 core pro.
-//TODO Optimize SineOscillatorPhaseModulated
-//TODO More circuits.
-//TODO DC blocker
-//TODO Swing scope probe UIs, auto ranging
-
-/**
- * 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
- */
-public class SynthesisEngine implements Synthesizer {
- private final static int BLOCKS_PER_BUFFER = 8;
- private final static int FRAMES_PER_BUFFER = Synthesizer.FRAMES_PER_BLOCK * BLOCKS_PER_BUFFER;
- // I have measured JavaSound taking 1200 msec to close devices.
- private static final int MAX_THREAD_STOP_TIME = 2000;
-
- public static final int DEFAULT_FRAME_RATE = 44100;
-
- private final AudioDeviceManager audioDeviceManager;
- private EngineThread engineThread;
- private final ScheduledQueue<ScheduledCommand> commandQueue = new ScheduledQueue<ScheduledCommand>();
-
- private InterleavingBuffer inputBuffer;
- private InterleavingBuffer outputBuffer;
- private double inverseNyquist;
- private long frameCount;
- private boolean pullDataEnabled = true;
- private boolean useRealTime = true;
- private boolean started;
- private int frameRate = DEFAULT_FRAME_RATE;
- private double framePeriod = 1.0 / frameRate;
-
- // List of all units added to the synth.
- private final ArrayList<UnitGenerator> allUnitList = new ArrayList<UnitGenerator>();
- // List of running units.
- private final ArrayList<UnitGenerator> runningUnitList = new ArrayList<UnitGenerator>();
- // List of units stopping because of autoStop.
- private final ArrayList<UnitGenerator> stoppingUnitList = new ArrayList<UnitGenerator>();
-
- private LoadAnalyzer loadAnalyzer;
- // private int numOutputChannels;
- // private int numInputChannels;
- private final CopyOnWriteArrayList<Runnable> audioTasks = new CopyOnWriteArrayList<Runnable>();
- private double mOutputLatency;
- private double mInputLatency;
- /** 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. */
- public static final double DB90 = (1.0 / (1 << 15));
-
- static Logger logger = Logger.getLogger(SynthesisEngine.class.getName());
-
- public SynthesisEngine(AudioDeviceManager audioDeviceManager) {
- this.audioDeviceManager = audioDeviceManager;
- }
-
- public SynthesisEngine() {
- this(AudioDeviceFactory.createAudioDeviceManager());
- }
-
- @Override
- public String getVersion() {
- return JSyn.VERSION;
- }
-
- @Override
- public int getVersionCode() {
- return JSyn.VERSION_CODE;
- }
-
- @Override
- public String toString() {
- return "JSyn " + JSyn.VERSION_TEXT;
- }
-
- public boolean isPullDataEnabled() {
- return pullDataEnabled;
- }
-
- /**
- * 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) {
- this.pullDataEnabled = pullDataEnabled;
- }
-
- private void setupAudioBuffers(int numInputChannels, int numOutputChannels) {
- inputBuffer = new InterleavingBuffer(FRAMES_PER_BUFFER, Synthesizer.FRAMES_PER_BLOCK,
- numInputChannels);
- outputBuffer = new InterleavingBuffer(FRAMES_PER_BUFFER, Synthesizer.FRAMES_PER_BLOCK,
- numOutputChannels);
- }
-
- public void terminate() {
- }
-
- class InterleavingBuffer {
- private final double[] interleavedBuffer;
- ChannelBlockBuffer[] blockBuffers;
-
- InterleavingBuffer(int framesPerBuffer, int framesPerBlock, int samplesPerFrame) {
- interleavedBuffer = new double[framesPerBuffer * samplesPerFrame];
- // Allocate buffers for each channel of synthesis output.
- blockBuffers = new ChannelBlockBuffer[samplesPerFrame];
- for (int i = 0; i < blockBuffers.length; i++) {
- blockBuffers[i] = new ChannelBlockBuffer(framesPerBlock);
- }
- }
-
- int deinterleave(int inIndex) {
- for (int jf = 0; jf < Synthesizer.FRAMES_PER_BLOCK; jf++) {
- for (int iob = 0; iob < blockBuffers.length; iob++) {
- ChannelBlockBuffer buffer = blockBuffers[iob];
- buffer.values[jf] = interleavedBuffer[inIndex++];
- }
- }
- return inIndex;
- }
-
- int interleave(int outIndex) {
- for (int jf = 0; jf < Synthesizer.FRAMES_PER_BLOCK; jf++) {
- for (int iob = 0; iob < blockBuffers.length; iob++) {
- ChannelBlockBuffer buffer = blockBuffers[iob];
- interleavedBuffer[outIndex++] = buffer.values[jf];
- }
- }
- return outIndex;
- }
-
- public double[] getChannelBuffer(int i) {
- return blockBuffers[i].values;
- }
-
- public void clear() {
- for (int i = 0; i < blockBuffers.length; i++) {
- blockBuffers[i].clear();
- }
- }
- }
-
- class ChannelBlockBuffer {
- private final double[] values;
-
- ChannelBlockBuffer(int framesPerBlock) {
- values = new double[framesPerBlock];
- }
-
- void clear() {
- for (int i = 0; i < values.length; i++) {
- values[i] = 0.0f;
- }
- }
- }
-
- @Override
- public void start() {
- // TODO Use constants.
- start(DEFAULT_FRAME_RATE, -1, 0, -1, 2);
- }
-
- @Override
- public void start(int frameRate) {
- // TODO Use constants.
- start(frameRate, -1, 0, -1, 2);
- }
-
- @Override
- public synchronized void start(int frameRate, int inputDeviceID, int numInputChannels,
- int outputDeviceID, int numOutputChannels) {
- if (started) {
- logger.info("JSyn already started.");
- return;
- }
-
- this.frameRate = frameRate;
- this.framePeriod = 1.0 / frameRate;
-
- setupAudioBuffers(numInputChannels, numOutputChannels);
-
- logger.info("Pure Java JSyn from www.softsynth.com, rate = " + frameRate + ", "
- + (useRealTime ? "RT" : "NON-RealTime") + ", " + JSyn.VERSION_TEXT);
-
- inverseNyquist = 2.0 / frameRate;
-
- if (useRealTime) {
- engineThread = new EngineThread(inputDeviceID, numInputChannels,
- outputDeviceID, numOutputChannels);
- logger.fine("Synth thread old priority = " + engineThread.getPriority());
- int engineThreadPriority = engineThread.getPriority() + 2 > Thread.MAX_PRIORITY ?
- Thread.MAX_PRIORITY : engineThread.getPriority() + 2;
- engineThread.setPriority(engineThreadPriority);
- logger.fine("Synth thread new priority = " + engineThread.getPriority());
- engineThread.start();
- }
-
- started = true;
- }
-
- @Override
- public boolean isRunning() {
- Thread thread = engineThread;
- return (thread != null) && thread.isAlive();
- }
-
- @Override
- public synchronized void stop() {
- if (!started) {
- logger.info("JSyn already stopped.");
- return;
- }
-
- if (useRealTime) {
- // Stop audio synthesis and all units.
- if (engineThread != null) {
- try {
- // Interrupt now, otherwise audio thread will wait for audio I/O.
- engineThread.requestStop();
- engineThread.join(MAX_THREAD_STOP_TIME);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- synchronized (runningUnitList) {
- runningUnitList.clear();
- }
- started = false;
- }
-
- private class EngineThread extends Thread
- {
- private AudioDeviceOutputStream audioOutputStream;
- private AudioDeviceInputStream audioInputStream;
- private volatile boolean go = true;
-
- EngineThread(int inputDeviceID, int numInputChannels,
- int outputDeviceID, int numOutputChannels) {
- if (numInputChannels > 0) {
- audioInputStream = audioDeviceManager.createInputStream(inputDeviceID, frameRate,
- numInputChannels);
- }
- if (numOutputChannels > 0) {
- audioOutputStream = audioDeviceManager.createOutputStream(outputDeviceID,
- frameRate, numOutputChannels);
- }
- }
-
- public void requestStop() {
- go = false;
- interrupt();
- }
-
- @Override
- public void run() {
- logger.fine("JSyn synthesis thread starting.");
- try {
- if (audioInputStream != null) {
- logger.finer("JSyn synthesis thread trying to start audio INPUT!");
- audioInputStream.start();
- mInputLatency = audioInputStream.getLatency();
- String msg = String.format("Input Latency in = %5.1f msec",
- 1000 * mInputLatency);
- logger.fine(msg);
- }
- if (audioOutputStream != null) {
- logger.finer("JSyn synthesis thread trying to start audio OUTPUT!");
- audioOutputStream.start();
- mOutputLatency = audioOutputStream.getLatency();
- String msg = String.format("Output Latency = %5.1f msec",
- 1000 * mOutputLatency);
- logger.fine(msg);
- // Buy some time while we fill the buffer.
- audioOutputStream.write(outputBuffer.interleavedBuffer);
- }
- loadAnalyzer = new LoadAnalyzer();
- while (go) {
- boolean throttled = false;
- if (audioInputStream != null) {
- // This call will block when the input is empty.
- audioInputStream.read(inputBuffer.interleavedBuffer);
- throttled = true;
- }
-
- loadAnalyzer.start();
- runAudioTasks();
- generateNextBuffer();
- loadAnalyzer.stop();
-
- if (audioOutputStream != null) {
- // This call will block when the output is full.
- audioOutputStream.write(outputBuffer.interleavedBuffer);
- throttled = true;
- }
- if (!throttled && isRealTime()) {
- Thread.sleep(2); // avoid spinning and eating up CPU
- }
- }
-
- } catch (Throwable e) {
- e.printStackTrace();
- go = false;
-
- } finally {
- logger.info("JSyn synthesis thread in finally code.");
- // Stop audio system.
- if (audioInputStream != null) {
- audioInputStream.stop();
- }
- if (audioOutputStream != null) {
- audioOutputStream.stop();
- }
- }
- logger.fine("JSyn synthesis thread exiting.");
- }
- }
-
- private void runAudioTasks() {
- for (Runnable task : audioTasks) {
- task.run();
- }
- }
-
- // TODO We need to implement a sharedSleeper like we use in JSyn1.
- public void generateNextBuffer() {
- int outIndex = 0;
- int inIndex = 0;
- for (int i = 0; i < BLOCKS_PER_BUFFER; i++) {
- if (inputBuffer != null) {
- inIndex = inputBuffer.deinterleave(inIndex);
- }
-
- TimeStamp timeStamp = createTimeStamp();
- // Try putting this up here so incoming time-stamped events will get
- // scheduled later.
- processScheduledCommands(timeStamp);
- clearBlockBuffers();
- synthesizeBuffer();
-
- if (outputBuffer != null) {
- outIndex = outputBuffer.interleave(outIndex);
- }
- frameCount += Synthesizer.FRAMES_PER_BLOCK;
- }
- }
-
- @Override
- public double getCurrentTime() {
- return frameCount * framePeriod;
- }
-
- @Override
- public TimeStamp createTimeStamp() {
- return new TimeStamp(getCurrentTime());
- }
-
- private void processScheduledCommands(TimeStamp timeStamp) {
- List<ScheduledCommand> timeList = commandQueue.removeNextList(timeStamp);
-
- while (timeList != null) {
- while (!timeList.isEmpty()) {
- ScheduledCommand command = timeList.remove(0);
- logger.fine("processing " + command + ", at time " + timeStamp.getTime());
- command.run();
- }
- // Get next list of commands at the given time.
- timeList = commandQueue.removeNextList(timeStamp);
- }
- }
-
- @Override
- public void scheduleCommand(TimeStamp timeStamp, ScheduledCommand command) {
- if ((Thread.currentThread() == engineThread) && (timeStamp.getTime() <= getCurrentTime())) {
- command.run();
- } else {
- logger.fine("scheduling " + command + ", at time " + timeStamp.getTime());
- commandQueue.add(timeStamp, command);
- }
- }
-
- @Override
- public void scheduleCommand(double time, ScheduledCommand command) {
- TimeStamp timeStamp = new TimeStamp(time);
- scheduleCommand(timeStamp, command);
- }
-
- @Override
- public void queueCommand(ScheduledCommand command) {
- TimeStamp timeStamp = createTimeStamp();
- scheduleCommand(timeStamp, command);
- }
-
- @Override
- public void clearCommandQueue() {
- commandQueue.clear();
- }
-
- private void clearBlockBuffers() {
- outputBuffer.clear();
- }
-
- private void synthesizeBuffer() {
- synchronized (runningUnitList) {
- ListIterator<UnitGenerator> iterator = runningUnitList.listIterator();
- while (iterator.hasNext()) {
- UnitGenerator unit = iterator.next();
- if (pullDataEnabled) {
- unit.pullData(getFrameCount(), 0, Synthesizer.FRAMES_PER_BLOCK);
- } else {
- unit.generate(0, Synthesizer.FRAMES_PER_BLOCK);
- }
- }
- // Remove any units that got auto stopped.
- for (UnitGenerator ugen : stoppingUnitList) {
- runningUnitList.remove(ugen);
- ugen.flattenOutputs();
- }
- }
- stoppingUnitList.clear();
- }
-
- public double[] getInputBuffer(int i) {
- try {
- return inputBuffer.getChannelBuffer(i);
- } catch (ArrayIndexOutOfBoundsException e) {
- throw new RuntimeException("Audio Input not configured in start() method.");
- }
- }
-
- public double[] getOutputBuffer(int i) {
- try {
- return outputBuffer.getChannelBuffer(i);
- } catch (ArrayIndexOutOfBoundsException e) {
- throw new RuntimeException("Audio Output not configured in start() method.");
- }
- }
-
- private void internalStopUnit(UnitGenerator unit) {
- synchronized (runningUnitList) {
- runningUnitList.remove(unit);
- }
- unit.flattenOutputs();
- }
-
- public void autoStopUnit(UnitGenerator unitGenerator) {
- synchronized (stoppingUnitList) {
- stoppingUnitList.add(unitGenerator);
- }
- }
-
- @Override
- public void startUnit(UnitGenerator unit, double time) {
- startUnit(unit, new TimeStamp(time));
- }
-
- @Override
- public void stopUnit(UnitGenerator unit, double time) {
- stopUnit(unit, new TimeStamp(time));
- }
-
- @Override
- public void startUnit(final UnitGenerator unit, TimeStamp timeStamp) {
- // Don't start if it is a component in a circuit because it will be
- // executed by the circuit.
- if (unit.getCircuit() == null) {
- scheduleCommand(timeStamp, new ScheduledCommand() {
- @Override
- public void run() {
- internalStartUnit(unit);
- }
- });
- }
- }
-
- @Override
- public void stopUnit(final UnitGenerator unit, TimeStamp timeStamp) {
- scheduleCommand(timeStamp, new ScheduledCommand() {
- @Override
- public void run() {
- internalStopUnit(unit);
- }
- });
- }
-
- @Override
- public void startUnit(UnitGenerator unit) {
- startUnit(unit, createTimeStamp());
- }
-
- @Override
- public void stopUnit(UnitGenerator unit) {
- stopUnit(unit, createTimeStamp());
- }
-
- private void internalStartUnit(UnitGenerator unit) {
- // logger.info( "internalStartUnit " + unit + " with circuit " +
- // unit.getCircuit() );
- if (unit.getCircuit() == null) {
- synchronized (runningUnitList) {
- if (!runningUnitList.contains(unit)) {
- runningUnitList.add(unit);
- }
- }
- }
- // else
- // {
- // logger.info(
- // "internalStartUnit detected race condition !!!! from old JSyn" + unit
- // + " with circuit " + unit.getCircuit() );
- // }
- }
-
- public double getInverseNyquist() {
- return inverseNyquist;
- }
-
- public double convertTimeToExponentialScaler(double duration) {
- // Calculate scaler so that scaler^frames = target/source
- double numFrames = duration * getFrameRate();
- return Math.pow(DB90, (1.0 / numFrames));
- }
-
- @Override
- public long getFrameCount() {
- return frameCount;
- }
-
- /**
- * @return the frameRate
- */
- @Override
- public int getFrameRate() {
- return frameRate;
- }
-
- /**
- * @return the inverse of the frameRate for efficiency
- */
- @Override
- public double getFramePeriod() {
- return framePeriod;
- }
-
- /** Convert a short value to a double in the range -1.0 to almost 1.0. */
- public static double convertShortToDouble(short sdata) {
- return (sdata * (1.0 / Short.MAX_VALUE));
- }
-
- /**
- * Convert a double value in the range -1.0 to almost 1.0 to a short. Double value is clipped
- * before converting.
- */
- public static short convertDoubleToShort(double d) {
- final double maxValue = ((double) (Short.MAX_VALUE - 1)) / Short.MAX_VALUE;
- if (d > maxValue) {
- d = maxValue;
- } else if (d < -1.0) {
- d = -1.0;
- }
- return (short) (d * Short.MAX_VALUE);
- }
-
- @Override
- public void addAudioTask(Runnable blockTask) {
- audioTasks.add(blockTask);
- }
-
- @Override
- public void removeAudioTask(Runnable blockTask) {
- audioTasks.remove(blockTask);
- }
-
- @Override
- public double getUsage() {
- // use temp so we don't have to synchronize
- LoadAnalyzer temp = loadAnalyzer;
- if (temp != null) {
- return temp.getAverageLoad();
- } else {
- return 0.0;
- }
- }
-
- @Override
- public AudioDeviceManager getAudioDeviceManager() {
- return audioDeviceManager;
- }
-
- @Override
- public void setRealTime(boolean realTime) {
- useRealTime = realTime;
- }
-
- @Override
- public boolean isRealTime() {
- return useRealTime;
- }
-
- public double getOutputLatency() {
- return mOutputLatency;
- }
-
- public double getInputLatency() {
- return mInputLatency;
- }
-
- @Override
- public void add(UnitGenerator ugen) {
- ugen.setSynthesisEngine(this);
- allUnitList.add(ugen);
- }
-
- @Override
- public void remove(UnitGenerator ugen) {
- allUnitList.remove(ugen);
- }
-
- @Override
- public void sleepUntil(double time) throws InterruptedException {
- double timeToSleep = time - getCurrentTime();
- while (timeToSleep > 0.0) {
- if (useRealTime) {
- long msecToSleep = (long) (1000 * timeToSleep);
- if (msecToSleep <= 0) {
- msecToSleep = 1;
- }
- Thread.sleep(msecToSleep);
- } else {
-
- generateNextBuffer();
- }
- timeToSleep = time - getCurrentTime();
- }
- }
-
- @Override
- public void sleepFor(double duration) throws InterruptedException {
- sleepUntil(getCurrentTime() + duration);
- }
-
- public void printConnections() {
- if (pullDataEnabled) {
- ListIterator<UnitGenerator> iterator = runningUnitList.listIterator();
- while (iterator.hasNext()) {
- UnitGenerator unit = iterator.next();
- unit.printConnections();
- }
- }
-
- }
-
-}
diff --git a/src/com/jsyn/exceptions/ChannelMismatchException.java b/src/com/jsyn/exceptions/ChannelMismatchException.java
deleted file mode 100644
index a1554cd..0000000
--- a/src/com/jsyn/exceptions/ChannelMismatchException.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2010 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.exceptions;
-
-/**
- * This will get thrown if, for example, stereo data is queued to a mono player.
- *
- * @author Phil Burk (C) 2010 Mobileer Inc
- */
-public class ChannelMismatchException extends RuntimeException {
-
- public ChannelMismatchException(String message) {
- super(message);
- }
-
- /**
- *
- */
- private static final long serialVersionUID = -5345224363387498119L;
-
-}
diff --git a/src/com/jsyn/instruments/DrumWoodFM.java b/src/com/jsyn/instruments/DrumWoodFM.java
deleted file mode 100644
index ba6cd1b..0000000
--- a/src/com/jsyn/instruments/DrumWoodFM.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright 2011 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.instruments;
-
-import com.jsyn.ports.UnitInputPort;
-import com.jsyn.ports.UnitOutputPort;
-import com.jsyn.unitgen.Add;
-import com.jsyn.unitgen.Circuit;
-import com.jsyn.unitgen.EnvelopeAttackDecay;
-import com.jsyn.unitgen.Multiply;
-import com.jsyn.unitgen.PassThrough;
-import com.jsyn.unitgen.SineOscillator;
-import com.jsyn.unitgen.SineOscillatorPhaseModulated;
-import com.jsyn.unitgen.UnitVoice;
-import com.jsyn.util.VoiceDescription;
-import com.softsynth.shared.time.TimeStamp;
-
-/**
- * Drum instruments using 2 Operator FM.
- *
- * @author Phil Burk (C) 2011 Mobileer Inc
- */
-public class DrumWoodFM extends Circuit implements UnitVoice {
- private static final int NUM_PRESETS = 3;
- // Declare units and ports.
- EnvelopeAttackDecay ampEnv;
- SineOscillatorPhaseModulated carrierOsc;
- EnvelopeAttackDecay modEnv;
- SineOscillator modOsc;
- PassThrough freqDistributor;
- Add modSummer;
- Multiply frequencyMultiplier;
-
- public UnitInputPort mcratio;
- public UnitInputPort index;
- public UnitInputPort modRange;
- public UnitInputPort frequency;
-
- public DrumWoodFM() {
- // Create unit generators.
- add(carrierOsc = new SineOscillatorPhaseModulated());
- add(freqDistributor = new PassThrough());
- add(modSummer = new Add());
- add(ampEnv = new EnvelopeAttackDecay());
- add(modEnv = new EnvelopeAttackDecay());
- add(modOsc = new SineOscillator());
- add(frequencyMultiplier = new Multiply());
-
- addPort(mcratio = frequencyMultiplier.inputB, "MCRatio");
- addPort(index = modSummer.inputA, "Index");
- addPort(modRange = modEnv.amplitude, "ModRange");
- addPort(frequency = freqDistributor.input, "Frequency");
-
- ampEnv.export(this, "Amp");
- modEnv.export(this, "Mod");
-
- freqDistributor.output.connect(carrierOsc.frequency);
- freqDistributor.output.connect(frequencyMultiplier.inputA);
-
- carrierOsc.output.connect(ampEnv.amplitude);
- modEnv.output.connect(modSummer.inputB);
- modSummer.output.connect(modOsc.amplitude);
- modOsc.output.connect(carrierOsc.modulation);
- frequencyMultiplier.output.connect(modOsc.frequency);
-
- // Make the circuit turn off when the envelope finishes to reduce CPU load.
- ampEnv.setupAutoDisable(this);
-
- usePreset(0);
- }
-
- @Override
- public void noteOff(TimeStamp timeStamp) {
- }
-
- @Override
- public void noteOn(double freq, double ampl, TimeStamp timeStamp) {
- carrierOsc.amplitude.set(ampl, timeStamp);
- ampEnv.input.trigger(timeStamp);
- modEnv.input.trigger(timeStamp);
- }
-
- @Override
- public UnitOutputPort getOutput() {
- return ampEnv.output;
- }
-
- @Override
- public void usePreset(int presetIndex) {
- mcratio.setup(0.001, 0.6875, 20.0);
- ampEnv.attack.setup(0.001, 0.005, 8.0);
- modEnv.attack.setup(0.001, 0.005, 8.0);
-
- int n = presetIndex % NUM_PRESETS;
- switch (n) {
- case 0:
- ampEnv.decay.setup(0.001, 0.293, 8.0);
- modEnv.decay.setup(0.001, 0.07, 8.0);
- frequency.setup(0.0, 349.0, 3000.0);
- index.setup(0.001, 0.05, 10.0);
- modRange.setup(0.001, 0.4, 10.0);
- break;
- case 1:
- default:
- ampEnv.decay.setup(0.001, 0.12, 8.0);
- modEnv.decay.setup(0.001, 0.06, 8.0);
- frequency.setup(0.0, 1400.0, 3000.0);
- index.setup(0.001, 0.16, 10.0);
- modRange.setup(0.001, 0.17, 10.0);
- break;
- }
- }
-
- static class MyVoiceDescription extends VoiceDescription {
- static String[] presetNames = {
- "WoodBlockFM", "ClaveFM"
- };
- static String[] tags = {
- "electronic", "drum"
- };
-
- public MyVoiceDescription() {
- super("DrumWoodFM", presetNames);
- }
-
- @Override
- public UnitVoice createUnitVoice() {
- return new DrumWoodFM();
- }
-
- @Override
- public String[] getTags(int presetIndex) {
- return tags;
- }
-
- @Override
- public String getVoiceClassName() {
- return DrumWoodFM.class.getName();
- }
- }
-
- public static VoiceDescription getVoiceDescription() {
- return new MyVoiceDescription();
- }
-}
diff --git a/src/com/jsyn/instruments/DualOscillatorSynthVoice.java b/src/com/jsyn/instruments/DualOscillatorSynthVoice.java
deleted file mode 100644
index c81041f..0000000
--- a/src/com/jsyn/instruments/DualOscillatorSynthVoice.java
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- * Copyright 2010 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.instruments;
-
-import com.jsyn.ports.UnitInputPort;
-import com.jsyn.ports.UnitOutputPort;
-import com.jsyn.unitgen.Add;
-import com.jsyn.unitgen.Circuit;
-import com.jsyn.unitgen.EnvelopeDAHDSR;
-import com.jsyn.unitgen.FilterFourPoles;
-import com.jsyn.unitgen.MorphingOscillatorBL;
-import com.jsyn.unitgen.Multiply;
-import com.jsyn.unitgen.UnitVoice;
-import com.jsyn.util.VoiceDescription;
-import com.softsynth.math.AudioMath;
-import com.softsynth.shared.time.TimeStamp;
-
-/**
- * Synthesizer voice with two morphing oscillators and a four-pole resonant filter.
- * Modulate the amplitude and filter using DAHDSR envelopes.
- */
-public class DualOscillatorSynthVoice extends Circuit implements UnitVoice {
- private Multiply frequencyMultiplier;
- private Multiply amplitudeMultiplier;
- private Multiply detuneScaler1;
- private Multiply detuneScaler2;
- private Multiply amplitudeBoost;
- private MorphingOscillatorBL osc1;
- private MorphingOscillatorBL osc2;
- private FilterFourPoles filter;
- private EnvelopeDAHDSR ampEnv;
- private EnvelopeDAHDSR filterEnv;
- private Add cutoffAdder;
-
- private static MyVoiceDescription voiceDescription;
-
- public UnitInputPort amplitude;
- public UnitInputPort frequency;
- /**
- * This scales the frequency value. You can use this to modulate a group of instruments using a
- * shared LFO and they will stay in tune. Set to 1.0 for no modulation.
- */
- public UnitInputPort frequencyScaler;
- public UnitInputPort oscShape1;
- public UnitInputPort oscShape2;
-// public UnitInputPort oscDetune1;
-// public UnitInputPort oscDetune2;
- public UnitInputPort cutoff;
- public UnitInputPort filterEnvDepth;
- public UnitInputPort Q;
-
- public DualOscillatorSynthVoice() {
- add(frequencyMultiplier = new Multiply());
- add(amplitudeMultiplier = new Multiply());
- add(amplitudeBoost = new Multiply());
- add(detuneScaler1 = new Multiply());
- add(detuneScaler2 = new Multiply());
- // Add tone generators.
- add(osc1 = new MorphingOscillatorBL());
- add(osc2 = new MorphingOscillatorBL());
-
- // Use an envelope to control the amplitude.
- add(ampEnv = new EnvelopeDAHDSR());
-
- // Use an envelope to control the filter cutoff.
- add(filterEnv = new EnvelopeDAHDSR());
- add(filter = new FilterFourPoles());
- add(cutoffAdder = new Add());
-
- filterEnv.output.connect(cutoffAdder.inputA);
- cutoffAdder.output.connect(filter.frequency);
- frequencyMultiplier.output.connect(detuneScaler1.inputA);
- frequencyMultiplier.output.connect(detuneScaler2.inputA);
- detuneScaler1.output.connect(osc1.frequency);
- detuneScaler2.output.connect(osc2.frequency);
- osc1.output.connect(amplitudeMultiplier.inputA); // mix oscillators
- osc2.output.connect(amplitudeMultiplier.inputA);
- amplitudeMultiplier.output.connect(filter.input);
- filter.output.connect(amplitudeBoost.inputA);
- amplitudeBoost.output.connect(ampEnv.amplitude);
-
- addPort(amplitude = amplitudeMultiplier.inputB, PORT_NAME_AMPLITUDE);
- addPort(frequency = frequencyMultiplier.inputA, PORT_NAME_FREQUENCY);
- addPort(oscShape1 = osc1.shape, "OscShape1");
- addPort(oscShape2 = osc2.shape, "OscShape2");
-// addPort(oscDetune1 = osc1.shape, "OscDetune1");
-// addPort(oscDetune2 = osc2.shape, "OscDetune2");
- addPort(cutoff = cutoffAdder.inputB, PORT_NAME_CUTOFF);
- addPortAlias(cutoff, PORT_NAME_TIMBRE);
- addPort(Q = filter.Q);
- addPort(frequencyScaler = frequencyMultiplier.inputB, PORT_NAME_FREQUENCY_SCALER);
- addPort(filterEnvDepth = filterEnv.amplitude, "FilterEnvDepth");
-
- filterEnv.export(this, "Filter");
- ampEnv.export(this, "Amp");
-
- frequency.setup(osc1.frequency);
- frequencyScaler.setup(0.2, 1.0, 4.0);
- cutoff.setup(filter.frequency);
- // Allow negative filter sweeps
- filterEnvDepth.setup(-4000.0, 2000.0, 4000.0);
-
- // set amplitudes slightly different so that they never entirely cancel
- osc1.amplitude.set(0.5);
- osc2.amplitude.set(0.4);
- // Make the circuit turn off when the envelope finishes to reduce CPU load.
- ampEnv.setupAutoDisable(this);
- // Add named port for mapping pressure.
- amplitudeBoost.inputB.setup(1.0, 1.0, 4.0);
- addPortAlias(amplitudeBoost.inputB, PORT_NAME_PRESSURE);
-
- usePreset(0);
- }
-
- /**
- * The first oscillator will be tuned UP by semitoneOffset/2.
- * The second oscillator will be tuned DOWN by semitoneOffset/2.
- * @param semitoneOffset
- */
- private void setDetunePitch(double semitoneOffset) {
- double halfOffset = semitoneOffset * 0.5;
- setDetunePitch1(halfOffset);
- setDetunePitch2(-halfOffset);
- }
-
- /**
- * Set the detuning for osc1 in semitones.
- * @param semitoneOffset
- */
- private void setDetunePitch1(double semitoneOffset) {
- double scale = AudioMath.semitonesToFrequencyScaler(semitoneOffset);
- detuneScaler1.inputB.set(scale);
- }
-
- /**
- * Set the detuning for osc2 in semitones.
- * @param semitoneOffset
- */
- private void setDetunePitch2(double semitoneOffset) {
- double scale = AudioMath.semitonesToFrequencyScaler(semitoneOffset);
- detuneScaler2.inputB.set(scale);
- }
-
- @Override
- public void noteOff(TimeStamp timeStamp) {
- ampEnv.input.off(timeStamp);
- filterEnv.input.off(timeStamp);
- }
-
- @Override
- public void noteOn(double freq, double ampl, TimeStamp timeStamp) {
- frequency.set(freq, timeStamp);
- amplitude.set(ampl, timeStamp);
- ampEnv.input.on(timeStamp);
- filterEnv.input.on(timeStamp);
- }
-
- @Override
- public UnitOutputPort getOutput() {
- return ampEnv.output;
- }
-
- // Reset to basic voice.
- public void reset() {
- osc1.shape.set(0.0);
- osc2.shape.set(0.0);
- ampEnv.attack.set(0.005);
- ampEnv.decay.set(0.2);
- ampEnv.sustain.set(0.5);
- ampEnv.release.set(1.0);
- filterEnv.attack.set(0.01);
- filterEnv.decay.set(0.6);
- filterEnv.sustain.set(0.4);
- filterEnv.release.set(1.0);
- cutoff.set(500.0);
- filterEnvDepth.set(3000.0);
- filter.reset();
- filter.Q.set(3.9);
- setDetunePitch(0.02);
- }
-
- @Override
- public void usePreset(int presetIndex) {
- reset(); // start from known configuration
- int n = presetIndex % presetNames.length;
- switch (n) {
- case 0:
- break;
- case 1:
- ampEnv.attack.set(0.1);
- ampEnv.decay.set(0.9);
- ampEnv.sustain.set(0.1);
- ampEnv.release.set(0.1);
- cutoff.set(500.0);
- filterEnvDepth.set(500.0);
- filter.Q.set(3.0);
- break;
- case 2:
- ampEnv.attack.set(0.1);
- ampEnv.decay.set(0.3);
- ampEnv.release.set(0.5);
- cutoff.set(2000.0);
- filterEnvDepth.set(500.0);
- filter.Q.set(2.0);
- break;
- case 3:
- osc1.shape.set(-0.9);
- osc2.shape.set(-0.8);
- ampEnv.attack.set(0.3);
- ampEnv.decay.set(0.8);
- ampEnv.release.set(0.2);
- filterEnv.sustain.set(0.7);
- cutoff.set(500.0);
- filterEnvDepth.set(500.0);
- filter.Q.set(3.0);
- break;
- case 4:
- osc1.shape.set(1.0);
- osc2.shape.set(0.0);
- break;
- case 5:
- osc1.shape.set(1.0);
- setDetunePitch1(0.0);
- osc2.shape.set(0.9);
- setDetunePitch1(7.0);
- break;
- case 6:
- osc1.shape.set(0.6);
- osc2.shape.set(-0.2);
- setDetunePitch1(0.01);
- ampEnv.attack.set(0.005);
- ampEnv.decay.set(0.09);
- ampEnv.sustain.set(0.0);
- ampEnv.release.set(1.0);
- filterEnv.attack.set(0.005);
- filterEnv.decay.set(0.1);
- filterEnv.sustain.set(0.4);
- filterEnv.release.set(1.0);
- cutoff.set(2000.0);
- filterEnvDepth.set(5000.0);
- filter.Q.set(7.02);
- break;
- default:
- break;
- }
- }
-
- private static final String[] presetNames = {
- "FastSaw", "SlowSaw", "BrightSaw",
- "SoftSine", "SquareSaw", "SquareFifth",
- "Blip"
- };
-
- static class MyVoiceDescription extends VoiceDescription {
- String[] tags = {
- "electronic", "filter", "analog", "subtractive"
- };
-
- public MyVoiceDescription() {
- super(DualOscillatorSynthVoice.class.getName(), presetNames);
- }
-
- @Override
- public UnitVoice createUnitVoice() {
- return new DualOscillatorSynthVoice();
- }
-
- @Override
- public String[] getTags(int presetIndex) {
- return tags;
- }
-
- @Override
- public String getVoiceClassName() {
- return DualOscillatorSynthVoice.class.getName();
- }
- }
-
- public static VoiceDescription getVoiceDescription() {
- if (voiceDescription == null) {
- voiceDescription = new MyVoiceDescription();
- }
- return voiceDescription;
- }
-
-
-}
diff --git a/src/com/jsyn/instruments/JSynInstrumentLibrary.java b/src/com/jsyn/instruments/JSynInstrumentLibrary.java
deleted file mode 100644
index 9f111c3..0000000
--- a/src/com/jsyn/instruments/JSynInstrumentLibrary.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2011 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.instruments;
-
-import com.jsyn.swing.InstrumentBrowser;
-import com.jsyn.util.InstrumentLibrary;
-import com.jsyn.util.VoiceDescription;
-
-/**
- * Stock instruments provided with the JSyn distribution.
- *
- * @author Phil Burk (C) 2011 Mobileer Inc
- * @see InstrumentBrowser
- */
-
-public class JSynInstrumentLibrary implements InstrumentLibrary {
- static VoiceDescription[] descriptions = {
- WaveShapingVoice.getVoiceDescription(),
- SubtractiveSynthVoice.getVoiceDescription(),
- DualOscillatorSynthVoice.getVoiceDescription(),
- NoiseHit.getVoiceDescription(),
- DrumWoodFM.getVoiceDescription()
- };
-
- @Override
- public VoiceDescription[] getVoiceDescriptions() {
- return descriptions;
- }
-
- @Override
- public String getName() {
- return "JSynInstruments";
- }
-}
diff --git a/src/com/jsyn/instruments/NoiseHit.java b/src/com/jsyn/instruments/NoiseHit.java
deleted file mode 100644
index b8714fc..0000000
--- a/src/com/jsyn/instruments/NoiseHit.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright 2009 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.instruments;
-
-import com.jsyn.ports.UnitOutputPort;
-import com.jsyn.unitgen.Circuit;
-import com.jsyn.unitgen.EnvelopeAttackDecay;
-import com.jsyn.unitgen.PinkNoise;
-import com.jsyn.unitgen.UnitVoice;
-import com.jsyn.util.VoiceDescription;
-import com.softsynth.shared.time.TimeStamp;
-
-/**
- * Cheap synthetic cymbal sound.
- */
-public class NoiseHit extends Circuit implements UnitVoice {
- EnvelopeAttackDecay ampEnv;
- PinkNoise noise;
- private static final int NUM_PRESETS = 3;
-
- public NoiseHit() {
- // Create unit generators.
- add(noise = new PinkNoise());
- add(ampEnv = new EnvelopeAttackDecay());
- noise.output.connect(ampEnv.amplitude);
-
- ampEnv.export(this, "Amp");
-
- // Make the circuit turn off when the envelope finishes to reduce CPU load.
- ampEnv.setupAutoDisable(this);
-
- usePreset(0);
- }
-
- @Override
- public void noteOff(TimeStamp timeStamp) {
- }
-
- @Override
- public void noteOn(double freq, double ampl, TimeStamp timeStamp) {
- noise.amplitude.set(ampl, timeStamp);
- ampEnv.input.trigger();
- }
-
- @Override
- public UnitOutputPort getOutput() {
- return ampEnv.output;
- }
-
- @Override
- public void usePreset(int presetIndex) {
- int n = presetIndex % NUM_PRESETS;
- switch (n) {
- case 0:
- ampEnv.attack.set(0.001);
- ampEnv.decay.set(0.1);
- break;
- case 1:
- ampEnv.attack.set(0.03);
- ampEnv.decay.set(1.4);
- break;
- default:
- ampEnv.attack.set(0.9);
- ampEnv.decay.set(0.3);
- break;
- }
- }
-
- static class MyVoiceDescription extends VoiceDescription {
- static String[] presetNames = {
- "ShortNoiseHit", "LongNoiseHit", "SlowNoiseHit"
- };
- static String[] tags = {
- "electronic", "noise"
- };
-
- public MyVoiceDescription() {
- super("NoiseHit", presetNames);
- }
-
- @Override
- public UnitVoice createUnitVoice() {
- return new NoiseHit();
- }
-
- @Override
- public String[] getTags(int presetIndex) {
- return tags;
- }
-
- @Override
- public String getVoiceClassName() {
- return NoiseHit.class.getName();
- }
- }
-
- public static VoiceDescription getVoiceDescription() {
- return new MyVoiceDescription();
- }
-}
diff --git a/src/com/jsyn/instruments/SubtractiveSynthVoice.java b/src/com/jsyn/instruments/SubtractiveSynthVoice.java
deleted file mode 100644
index 5cfc4b9..0000000
--- a/src/com/jsyn/instruments/SubtractiveSynthVoice.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright 2010 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.instruments;
-
-import com.jsyn.ports.UnitInputPort;
-import com.jsyn.ports.UnitOutputPort;
-import com.jsyn.unitgen.Add;
-import com.jsyn.unitgen.Circuit;
-import com.jsyn.unitgen.EnvelopeDAHDSR;
-import com.jsyn.unitgen.FilterLowPass;
-import com.jsyn.unitgen.Multiply;
-import com.jsyn.unitgen.SawtoothOscillatorBL;
-import com.jsyn.unitgen.UnitOscillator;
-import com.jsyn.unitgen.UnitVoice;
-import com.jsyn.util.VoiceDescription;
-import com.softsynth.shared.time.TimeStamp;
-
-/**
- * Typical synthesizer voice with one oscillator and a biquad resonant filter. Modulate the amplitude and
- * filter using DAHDSR envelopes.
- *
- * @author Phil Burk (C) 2010 Mobileer Inc
- */
-public class SubtractiveSynthVoice extends Circuit implements UnitVoice {
- private UnitOscillator osc;
- private FilterLowPass filter;
- private EnvelopeDAHDSR ampEnv;
- private EnvelopeDAHDSR filterEnv;
- private Add cutoffAdder;
- private Multiply frequencyScaler;
-
- public UnitInputPort amplitude;
- public UnitInputPort frequency;
- /**
- * This scales the frequency value. You can use this to modulate a group of instruments using a
- * shared LFO and they will stay in tune.
- */
- public UnitInputPort pitchModulation;
- public UnitInputPort cutoff;
- public UnitInputPort cutoffRange;
- public UnitInputPort Q;
-
- public SubtractiveSynthVoice() {
- add(frequencyScaler = new Multiply());
- // Add a tone generator.
- add(osc = new SawtoothOscillatorBL());
-
- // Use an envelope to control the amplitude.
- add(ampEnv = new EnvelopeDAHDSR());
-
- // Use an envelope to control the filter cutoff.
- add(filterEnv = new EnvelopeDAHDSR());
- add(filter = new FilterLowPass());
- add(cutoffAdder = new Add());
-
- filterEnv.output.connect(cutoffAdder.inputA);
- cutoffAdder.output.connect(filter.frequency);
- frequencyScaler.output.connect(osc.frequency);
- osc.output.connect(filter.input);
- filter.output.connect(ampEnv.amplitude);
-
- addPort(amplitude = osc.amplitude, "Amplitude");
- addPort(frequency = frequencyScaler.inputA, "Frequency");
- addPort(pitchModulation = frequencyScaler.inputB, "PitchMod");
- addPort(cutoff = cutoffAdder.inputB, "Cutoff");
- addPort(cutoffRange = filterEnv.amplitude, "CutoffRange");
- addPort(Q = filter.Q);
-
- ampEnv.export(this, "Amp");
- filterEnv.export(this, "Filter");
-
- frequency.setup(osc.frequency);
- pitchModulation.setup(0.2, 1.0, 4.0);
- cutoff.setup(filter.frequency);
- cutoffRange.setup(filter.frequency);
-
- // Make the circuit turn off when the envelope finishes to reduce CPU load.
- ampEnv.setupAutoDisable(this);
-
- usePreset(0);
- }
-
- @Override
- public void noteOff(TimeStamp timeStamp) {
- ampEnv.input.off(timeStamp);
- filterEnv.input.off(timeStamp);
- }
-
- @Override
- public void noteOn(double freq, double ampl, TimeStamp timeStamp) {
- frequency.set(freq, timeStamp);
- amplitude.set(ampl, timeStamp);
-
- ampEnv.input.on(timeStamp);
- filterEnv.input.on(timeStamp);
- }
-
- @Override
- public UnitOutputPort getOutput() {
- return ampEnv.output;
- }
-
- @Override
- public void usePreset(int presetIndex) {
- int n = presetIndex % presetNames.length;
- switch (n) {
- case 0:
- ampEnv.attack.set(0.01);
- ampEnv.decay.set(0.2);
- ampEnv.release.set(1.0);
- cutoff.set(500.0);
- cutoffRange.set(500.0);
- filter.Q.set(1.0);
- break;
- case 1:
- ampEnv.attack.set(0.5);
- ampEnv.decay.set(0.3);
- ampEnv.release.set(0.2);
- cutoff.set(500.0);
- cutoffRange.set(500.0);
- filter.Q.set(3.0);
- break;
- case 2:
- default:
- ampEnv.attack.set(0.1);
- ampEnv.decay.set(0.3);
- ampEnv.release.set(0.5);
- cutoff.set(2000.0);
- cutoffRange.set(500.0);
- filter.Q.set(2.0);
- break;
- }
- }
-
- static String[] presetNames = {
- "FastSaw", "SlowSaw", "BrightSaw"
- };
-
- static class MyVoiceDescription extends VoiceDescription {
- String[] tags = {
- "electronic", "filter", "clean"
- };
-
- public MyVoiceDescription() {
- super("SubtractiveSynth", presetNames);
- }
-
- @Override
- public UnitVoice createUnitVoice() {
- return new SubtractiveSynthVoice();
- }
-
- @Override
- public String[] getTags(int presetIndex) {
- return tags;
- }
-
- @Override
- public String getVoiceClassName() {
- return SubtractiveSynthVoice.class.getName();
- }
- }
-
- public static VoiceDescription getVoiceDescription() {
- return new MyVoiceDescription();
- }
-
-}
diff --git a/src/com/jsyn/instruments/WaveShapingVoice.java b/src/com/jsyn/instruments/WaveShapingVoice.java
deleted file mode 100644
index 5044f21..0000000
--- a/src/com/jsyn/instruments/WaveShapingVoice.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright 2011 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.instruments;
-
-import com.jsyn.data.DoubleTable;
-import com.jsyn.ports.UnitFunctionPort;
-import com.jsyn.ports.UnitInputPort;
-import com.jsyn.ports.UnitOutputPort;
-import com.jsyn.unitgen.Circuit;
-import com.jsyn.unitgen.EnvelopeDAHDSR;
-import com.jsyn.unitgen.FunctionEvaluator;
-import com.jsyn.unitgen.Multiply;
-import com.jsyn.unitgen.SineOscillator;
-import com.jsyn.unitgen.UnitOscillator;
-import com.jsyn.unitgen.UnitVoice;
-import com.jsyn.util.VoiceDescription;
-import com.softsynth.math.ChebyshevPolynomial;
-import com.softsynth.math.PolynomialTableData;
-import com.softsynth.shared.time.TimeStamp;
-
-/**
- * Waveshaping oscillator with envelopes.
- *
- * @author Phil Burk (C) 2011 Mobileer Inc
- */
-public class WaveShapingVoice extends Circuit implements UnitVoice {
- private static final long serialVersionUID = -2704222221111608377L;
- private static final int NUM_PRESETS = 3;
- private UnitOscillator osc;
- private FunctionEvaluator waveShaper;
- private EnvelopeDAHDSR ampEnv;
- private EnvelopeDAHDSR rangeEnv;
- private Multiply frequencyScaler;
-
- public UnitInputPort range;
- public UnitInputPort frequency;
- public UnitInputPort amplitude;
- public UnitFunctionPort function;
- public UnitInputPort pitchModulation;
-
- // default Chebyshev polynomial table to share.
- private static DoubleTable chebyshevTable;
- private final static int CHEBYSHEV_ORDER = 11;
-
- static {
- // Make table with Chebyshev polynomial to share among voices
- PolynomialTableData chebData = new PolynomialTableData(
- ChebyshevPolynomial.T(CHEBYSHEV_ORDER), 1024);
- chebyshevTable = new DoubleTable(chebData.getData());
- }
-
- public WaveShapingVoice() {
- add(frequencyScaler = new Multiply());
- add(osc = new SineOscillator());
- add(waveShaper = new FunctionEvaluator());
- add(rangeEnv = new EnvelopeDAHDSR());
- add(ampEnv = new EnvelopeDAHDSR());
-
- addPort(amplitude = ampEnv.amplitude);
- addPort(range = osc.amplitude, "Range");
- addPort(function = waveShaper.function);
- addPort(frequency = frequencyScaler.inputA, "Frequency");
- addPort(pitchModulation = frequencyScaler.inputB, "PitchMod");
-
- ampEnv.export(this, "Amp");
- rangeEnv.export(this, "Range");
-
- function.set(chebyshevTable);
-
- // Connect units.
- osc.output.connect(rangeEnv.amplitude);
- rangeEnv.output.connect(waveShaper.input);
- ampEnv.output.connect(waveShaper.amplitude);
- frequencyScaler.output.connect(osc.frequency);
-
- // Set reasonable defaults for the ports.
- pitchModulation.setup(0.1, 1.0, 10.0);
- range.setup(0.1, 0.8, 1.0);
- frequency.setup(osc.frequency);
- amplitude.setup(0.0, 0.5, 1.0);
-
- // Make the circuit turn off when the envelope finishes to reduce CPU load.
- ampEnv.setupAutoDisable(this);
-
- usePreset(2);
- }
-
- @Override
- public UnitOutputPort getOutput() {
- return waveShaper.output;
- }
-
- @Override
- public void noteOn(double freq, double amp, TimeStamp timeStamp) {
- frequency.set(freq, timeStamp);
- amplitude.set(amp, timeStamp);
- ampEnv.input.on(timeStamp);
- rangeEnv.input.on(timeStamp);
- }
-
- @Override
- public void noteOff(TimeStamp timeStamp) {
- ampEnv.input.off(timeStamp);
- rangeEnv.input.off(timeStamp);
- }
-
- @Override
- public void usePreset(int presetIndex) {
- int n = presetIndex % NUM_PRESETS;
- switch (n) {
- case 0:
- ampEnv.attack.set(0.01);
- ampEnv.decay.set(0.2);
- ampEnv.release.set(1.0);
- rangeEnv.attack.set(0.01);
- rangeEnv.decay.set(0.2);
- rangeEnv.sustain.set(0.4);
- rangeEnv.release.set(1.0);
- break;
- case 1:
- ampEnv.attack.set(0.5);
- ampEnv.decay.set(0.3);
- ampEnv.release.set(0.2);
- rangeEnv.attack.set(0.03);
- rangeEnv.decay.set(0.2);
- rangeEnv.sustain.set(0.5);
- rangeEnv.release.set(1.0);
- break;
- default:
- ampEnv.attack.set(0.1);
- ampEnv.decay.set(0.3);
- ampEnv.release.set(0.5);
- rangeEnv.attack.set(0.01);
- rangeEnv.decay.set(0.2);
- rangeEnv.sustain.set(0.9);
- rangeEnv.release.set(1.0);
- break;
- }
- }
-
- static class MyVoiceDescription extends VoiceDescription {
- static String[] presetNames = {
- "FastChebyshev", "SlowChebyshev", "BrightChebyshev"
- };
- static String[] tags = {
- "electronic", "waveshaping", "clean"
- };
-
- public MyVoiceDescription() {
- super("Waveshaping", presetNames);
- }
-
- @Override
- public UnitVoice createUnitVoice() {
- return new WaveShapingVoice();
- }
-
- @Override
- public String[] getTags(int presetIndex) {
- return tags;
- }
-
- @Override
- public String getVoiceClassName() {
- return WaveShapingVoice.class.getName();
- }
- }
-
- public static VoiceDescription getVoiceDescription() {
- return new MyVoiceDescription();
- }
-
-}
diff --git a/src/com/jsyn/io/AudioFifo.java b/src/com/jsyn/io/AudioFifo.java
deleted file mode 100644
index 0c563e4..0000000
--- a/src/com/jsyn/io/AudioFifo.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright 2010 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.io;
-
-import java.util.concurrent.locks.Condition;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-
-/**
- * FIFO that implements AudioInputStream, AudioOutputStream interfaces. This can be used to send
- * audio data between different threads. The reads or writes may or may not wait based on flags.
- *
- * @author Phil Burk (C) 2010 Mobileer Inc
- */
-public class AudioFifo implements AudioInputStream, AudioOutputStream {
- // These indices run double the FIFO size so that we can tell empty from full.
- private volatile int readIndex;
- private volatile int writeIndex;
- private volatile double[] buffer;
- // Used to mask the index into range when accessing the buffer array.
- private int accessMask;
- // Used to mask the index so it wraps around.
- private int sizeMask;
- private boolean writeWaitEnabled = true;
- private boolean readWaitEnabled = true;
- final Lock lock = new ReentrantLock();
- final Condition notFull = lock.newCondition();
- final Condition notEmpty = lock.newCondition();
-
- /**
- * @param size Number of doubles in the FIFO. Must be a power of 2. Eg. 1024.
- */
- public void allocate(int size) {
- if (!isPowerOfTwo(size)) {
- throw new IllegalArgumentException("Size must be a power of two.");
- }
- buffer = new double[size];
- accessMask = size - 1;
- sizeMask = (size * 2) - 1;
- }
-
- public int size() {
- return buffer.length;
- }
-
- public static boolean isPowerOfTwo(int size) {
- return ((size & (size - 1)) == 0);
- }
-
- /** How many samples are available for reading without blocking? */
- @Override
- public int available() {
- return (writeIndex - readIndex) & sizeMask;
- }
-
- @Override
- public void close() {
- // TODO Maybe we should tell any thread that is waiting that the FIFO is closed.
- }
-
- @Override
- public double read() {
- double value = Double.NaN;
- if (readWaitEnabled) {
- lock.lock();
- try {
- while (available() < 1) {
- try {
- notEmpty.await();
- } catch (InterruptedException e) {
- return Double.NaN;
- }
- }
- value = readOneInternal();
- } finally {
- lock.unlock();
- }
-
- } else {
- if (readIndex != writeIndex) {
- value = readOneInternal();
- }
- }
-
- if (writeWaitEnabled) {
- lock.lock();
- notFull.signal();
- lock.unlock();
- }
-
- return value;
- }
-
- private double readOneInternal() {
- double value = buffer[readIndex & accessMask];
- readIndex = (readIndex + 1) & sizeMask;
- return value;
- }
-
- @Override
- public void write(double value) {
- if (writeWaitEnabled) {
- lock.lock();
- try {
- while (available() == buffer.length)
- {
- try {
- notFull.await();
- } catch (InterruptedException e) {
- return; // Silently fail
- }
- }
- writeOneInternal(value);
- } finally {
- lock.unlock();
- }
-
- } else {
- if (available() != buffer.length) {
- writeOneInternal(value);
- }
- }
-
- if (readWaitEnabled) {
- lock.lock();
- notEmpty.signal();
- lock.unlock();
- }
- }
-
- private void writeOneInternal(double value) {
- buffer[writeIndex & accessMask] = value;
- writeIndex = (writeIndex + 1) & sizeMask;
- }
-
- @Override
- public int read(double[] buffer) {
- return read(buffer, 0, buffer.length);
- }
-
- @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();
- }
- }
- }
- return count;
- }
-
- @Override
- public void write(double[] buffer) {
- write(buffer, 0, buffer.length);
- }
-
- @Override
- public void write(double[] buffer, int start, int count) {
- for (int i = 0; i < count; i++) {
- write(buffer[i + start]);
- }
- }
-
- /** If true then a subsequent write call will wait if there is no room to write. */
- public void setWriteWaitEnabled(boolean enabled) {
- writeWaitEnabled = enabled;
-
- }
-
- /** If true then a subsequent read call will wait if there is no data to read. */
- public void setReadWaitEnabled(boolean enabled) {
- readWaitEnabled = enabled;
-
- }
-
- public boolean isWriteWaitEnabled() {
- return writeWaitEnabled;
- }
-
- public boolean isReadWaitEnabled() {
- return readWaitEnabled;
- }
-}
diff --git a/src/com/jsyn/io/AudioInputStream.java b/src/com/jsyn/io/AudioInputStream.java
deleted file mode 100644
index f233ff1..0000000
--- a/src/com/jsyn/io/AudioInputStream.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2009 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.io;
-
-public interface AudioInputStream {
- public double read();
-
- /**
- * Try to fill the entire buffer.
- *
- * @param buffer
- * @return number of samples read
- */
- public int read(double[] buffer);
-
- /**
- * Read from the stream. Block until some data is available.
- *
- * @param buffer
- * @param start index of first sample in buffer
- * @param count number of samples to read, for example count=8 for 4 stereo frames
- * @return number of samples read
- */
- public int read(double[] buffer, int start, int count);
-
- public void close();
-
- /**
- * @return number of samples currently available to read without blocking
- */
- public int available();
-}
diff --git a/src/com/jsyn/io/AudioOutputStream.java b/src/com/jsyn/io/AudioOutputStream.java
deleted file mode 100644
index dada577..0000000
--- a/src/com/jsyn/io/AudioOutputStream.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright 2009 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.io;
-
-import java.io.IOException;
-
-public interface AudioOutputStream {
- public void write(double value) throws IOException;
-
- public void write(double[] buffer) throws IOException;
-
- public void write(double[] buffer, int start, int count) throws IOException;
-
- public void close() throws IOException;
-}
diff --git a/src/com/jsyn/midi/MessageParser.java b/src/com/jsyn/midi/MessageParser.java
deleted file mode 100644
index d0f5d4d..0000000
--- a/src/com/jsyn/midi/MessageParser.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright 2010 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.midi;
-
-/**
- * Parse the message and call the appropriate method to handle it.
- *
- * @author Phil Burk (C) 2010 Mobileer Inc
- */
-public class MessageParser {
- private int[] parameterIndices = new int[MidiConstants.MAX_CHANNELS];
- private int[] parameterValues = new int[MidiConstants.MAX_CHANNELS];
- private int BIT_NON_RPM = 1 << 14;
- private int MASK_14BIT = (1 << 14) - 1;
-
- public void parse(byte[] message) {
- int status = message[0];
- int command = status & 0xF0;
- int channel = status & 0x0F;
-
- switch (command) {
- case MidiConstants.NOTE_ON:
- int velocity = message[2];
- if (velocity == 0) {
- noteOff(channel, message[1], velocity);
- } else {
- noteOn(channel, message[1], velocity);
- }
- break;
-
- case MidiConstants.NOTE_OFF:
- noteOff(channel, message[1], message[2]);
- break;
-
- case MidiConstants.POLYPHONIC_AFTERTOUCH:
- polyphonicAftertouch(channel, message[1], message[2]);
- break;
-
- case MidiConstants.CHANNEL_PRESSURE:
- channelPressure(channel, message[1]);
- break;
-
- case MidiConstants.CONTROL_CHANGE:
- rawControlChange(channel, message[1], message[2]);
- break;
-
- case MidiConstants.PROGRAM_CHANGE:
- programChange(channel, message[1]);
- break;
-
- case MidiConstants.PITCH_BEND:
- int bend = (message[2] << 7) + message[1];
- pitchBend(channel, bend);
- break;
- }
-
- }
-
- public void rawControlChange(int channel, int index, int value) {
- int paramIndex;
- int paramValue;
- switch(index) {
- case MidiConstants.CONTROLLER_DATA_ENTRY:
- parameterValues[channel] = value << 7;
- fireParameterChange(channel);
- break;
- case MidiConstants.CONTROLLER_DATA_ENTRY_LSB:
- paramValue = parameterValues[channel] & ~0x7F;
- paramValue |= value;
- parameterValues[channel] = paramValue;
- fireParameterChange(channel);
- break;
- case MidiConstants.CONTROLLER_NRPN_LSB:
- paramIndex = parameterIndices[channel] & ~0x7F;
- paramIndex |= value | BIT_NON_RPM;
- parameterIndices[channel] = paramIndex;
- break;
- case MidiConstants.CONTROLLER_NRPN_MSB:
- parameterIndices[channel] = (value << 7) | BIT_NON_RPM;;
- break;
- case MidiConstants.CONTROLLER_RPN_LSB:
- paramIndex = parameterIndices[channel] & ~0x7F;
- paramIndex |= value;
- parameterIndices[channel] = paramIndex;
- break;
- case MidiConstants.CONTROLLER_RPN_MSB:
- parameterIndices[channel] = value << 7;
- break;
- default:
- controlChange(channel, index, value);
- break;
-
- }
- }
-
- private void fireParameterChange(int channel) {
- int paramIndex;
- paramIndex = parameterIndices[channel];
- if ((paramIndex & BIT_NON_RPM) == 0) {
- registeredParameter(channel, paramIndex, parameterValues[channel]);
- } else {
- nonRegisteredParameter(channel, paramIndex & MASK_14BIT, parameterValues[channel]);
- }
- }
-
- public void nonRegisteredParameter(int channel, int index14, int value14) {
- }
-
- public void registeredParameter(int channel, int index14, int value14) {
- }
-
- public void pitchBend(int channel, int bend) {
- }
-
- public void programChange(int channel, int program) {
- }
-
- public void polyphonicAftertouch(int channel, int pitch, int pressure) {
- }
-
- public void channelPressure(int channel, int pressure) {
- }
-
- public void controlChange(int channel, int index, int value) {
- }
-
- public void noteOn(int channel, int pitch, int velocity) {
- }
-
- // If a NOTE_ON with zero velocity is received then noteOff will be called.
- public void noteOff(int channel, int pitch, int velocity) {
- }
-}
diff --git a/src/com/jsyn/midi/MidiConstants.java b/src/com/jsyn/midi/MidiConstants.java
deleted file mode 100644
index 8c92119..0000000
--- a/src/com/jsyn/midi/MidiConstants.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright 2010 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.midi;
-
-/**
- * Constants that define the MIDI standard.
- *
- * @author Phil Burk (C) 2010 Mobileer Inc
- */
-public class MidiConstants {
-
- public static final int MAX_CHANNELS = 16;
- // Basic commands.
- public static final int NOTE_OFF = 0x80;
- public static final int NOTE_ON = 0x90;
- public static final int POLYPHONIC_AFTERTOUCH = 0xA0;
- public static final int CONTROL_CHANGE = 0xB0;
- public static final int PROGRAM_CHANGE = 0xC0;
- public static final int CHANNEL_AFTERTOUCH = 0xD0;
- public static final int CHANNEL_PRESSURE = CHANNEL_AFTERTOUCH;
- public static final int PITCH_BEND = 0xE0;
- public static final int SYSTEM_COMMON = 0xF0;
-
- public static final int PITCH_BEND_CENTER = 0x2000;
-
- public static final int CONTROLLER_BANK_SELECT = 0;
- public static final int CONTROLLER_MOD_WHEEL = 1;
- public static final int CONTROLLER_BREATH = 2;
- public static final int CONTROLLER_DATA_ENTRY = 6;
- public static final int CONTROLLER_VOLUME = 7;
- public static final int CONTROLLER_PAN = 10;
-
- public static final int CONTROLLER_LSB_OFFSET = 32;
- public static final int CONTROLLER_DATA_ENTRY_LSB = CONTROLLER_DATA_ENTRY + CONTROLLER_LSB_OFFSET;
-
- public static final int CONTROLLER_TIMBRE = 74; // Often used by MPE for Y axis control.
-
- public static final int CONTROLLER_DATA_INCREMENT = 96;
- public static final int CONTROLLER_DATA_DECREMENT = 97;
- public static final int CONTROLLER_NRPN_LSB = 98;
- public static final int CONTROLLER_NRPN_MSB = 99;
- public static final int CONTROLLER_RPN_LSB = 100;
- public static final int CONTROLLER_RPN_MSB = 101;
-
- public static final int RPN_BEND_RANGE = 0;
- public static final int RPN_FINE_TUNING = 1;
-
- public static final String PITCH_NAMES[] = {
- "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"
- };
-
- /**
- * Calculate frequency in Hertz based on MIDI pitch. Middle C is 60.0. You can use fractional
- * pitches so 60.5 would give you a pitch half way between C and C#.
- */
- static final double CONCERT_A_FREQUENCY = 440.0;
- static final double CONCERT_A_PITCH = 69.0;
-
- public static double convertPitchToFrequency(double pitch) {
- return CONCERT_A_FREQUENCY * Math.pow(2.0, ((pitch - CONCERT_A_PITCH) / 12.0));
- }
-
- /**
- * Calculate MIDI pitch based on frequency in Hertz. Middle C is 60.0.
- */
- public static double convertFrequencyToPitch(double frequency) {
- return CONCERT_A_PITCH + (12 * Math.log(frequency / CONCERT_A_FREQUENCY) / Math.log(2.0));
- }
-
-}
diff --git a/src/com/jsyn/midi/MidiSynthesizer.java b/src/com/jsyn/midi/MidiSynthesizer.java
deleted file mode 100644
index 30204b0..0000000
--- a/src/com/jsyn/midi/MidiSynthesizer.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright 2016 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.midi;
-
-import com.jsyn.instruments.DualOscillatorSynthVoice;
-import com.jsyn.util.MultiChannelSynthesizer;
-
-/**
- * Map MIDI messages into calls to a MultiChannelSynthesizer.
- * Handles CONTROLLER_MOD_WHEEL, TIMBRE, VOLUME and PAN.
- * Handles Bend Range RPN.
- *
- * <pre><code>
- voiceDescription = DualOscillatorSynthVoice.getVoiceDescription();
- multiSynth = new MultiChannelSynthesizer();
- final int startChannel = 0;
- multiSynth.setup(synth, startChannel, NUM_CHANNELS, VOICES_PER_CHANNEL, voiceDescription);
- midiSynthesizer = new MidiSynthesizer(multiSynth);
- // pass MIDI bytes
- midiSynthesizer.onReceive(bytes, 0, bytes.length);
- </code></pre>
- *
- * See the example UseMidiKeyboard.java
- *
- * @author Phil Burk (C) 2016 Mobileer Inc
- */
-public class MidiSynthesizer extends MessageParser {
-
- private MultiChannelSynthesizer multiSynth;
-
- public MidiSynthesizer(MultiChannelSynthesizer multiSynth) {
- this.multiSynth = multiSynth;
- }
-
- @Override
- public void controlChange(int channel, int index, int value) {
- //System.out.println("controlChange(" + channel + ", " + index + ", " + value + ")");
- double normalized = value * (1.0 / 127.0);
- switch (index) {
- case MidiConstants.CONTROLLER_MOD_WHEEL:
- double vibratoDepth = 0.1 * normalized;
- System.out.println( "vibratoDepth = " + vibratoDepth );
- multiSynth.setVibratoDepth(channel, vibratoDepth);
- break;
- case MidiConstants.CONTROLLER_TIMBRE:
- multiSynth.setTimbre(channel, normalized);
- break;
- case MidiConstants.CONTROLLER_VOLUME:
- multiSynth.setVolume(channel, normalized);
- break;
- case MidiConstants.CONTROLLER_PAN:
- // convert to -1 to +1 range
- multiSynth.setPan(channel, (normalized * 2.0) - 1.0);
- break;
- }
- }
-
- @Override
- public void registeredParameter(int channel, int index14, int value14) {
- switch(index14) {
- case MidiConstants.RPN_BEND_RANGE:
- int semitones = value14 >> 7;
- int cents = value14 & 0x7F;
- double bendRange = semitones + (cents * 0.01);
- multiSynth.setBendRange(channel, bendRange);
- break;
- default:
- break;
- }
- }
-
- @Override
- public void programChange(int channel, int program) {
- multiSynth.programChange(channel, program);
- }
-
- @Override
- public void channelPressure(int channel, int value) {
- double normalized = value * (1.0 / 127.0);
- multiSynth.setPressure(channel, normalized);
- }
-
- @Override
- public void noteOff(int channel, int noteNumber, int velocity) {
- multiSynth.noteOff(channel, noteNumber, velocity);
- }
-
- @Override
- public void noteOn(int channel, int noteNumber, int velocity) {
- multiSynth.noteOn(channel, noteNumber, velocity);
- }
-
- @Override
- public void pitchBend(int channel, int bend) {
- double offset = (bend - MidiConstants.PITCH_BEND_CENTER)
- * (1.0 / (MidiConstants.PITCH_BEND_CENTER));
- multiSynth.setPitchBend(channel, offset);
- }
-
- public void onReceive(byte[] bytes, int i, int length) {
- parse(bytes); // TODO
- }
-
-}
diff --git a/src/com/jsyn/package.html b/src/com/jsyn/package.html
deleted file mode 100644
index cd73832..0000000
--- a/src/com/jsyn/package.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<title>JSyn Package</title>
-</head>
-<body>
-JSyn is a music and audio synthesis API for Java. The basic sequence of operations is:
-<ul>
-<li>Use the JSyn class to create a synthesizer.</li>
-<li>Create unit generators and add them to the synthesizer.</li>
-<li>Connect unit generators so that audio signals can flow between them.</li>
-<li>Start an output generator. It will pull data from the connected units.</li>
-<li>Set port values and queue sample and envelope data to change the sound.</li>
-</ul>
-</body>
-</html> \ No newline at end of file
diff --git a/src/com/jsyn/ports/ConnectableInput.java b/src/com/jsyn/ports/ConnectableInput.java
deleted file mode 100644
index 3dae876..0000000
--- a/src/com/jsyn/ports/ConnectableInput.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2011 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.ports;
-
-/**
- * This interface lets you pass either an input port, or a single part of an input port.
- *
- * @author Phil Burk (C) 2011 Mobileer Inc
- */
-public interface ConnectableInput {
- public void connect(ConnectableOutput other);
-
- public void disconnect(ConnectableOutput other);
-
- /**
- * This is used internally by PortBlockPart to make a connection between specific parts of a
- * port.
- *
- * @return
- */
- public PortBlockPart getPortBlockPart();
-
- public void pullData(long frameCount, int start, int limit);
-}
diff --git a/src/com/jsyn/ports/ConnectableOutput.java b/src/com/jsyn/ports/ConnectableOutput.java
deleted file mode 100644
index f42a799..0000000
--- a/src/com/jsyn/ports/ConnectableOutput.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright 2009 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.ports;
-
-public interface ConnectableOutput {
- public void connect(ConnectableInput other);
-
- public void disconnect(ConnectableInput other);
-}
diff --git a/src/com/jsyn/ports/GettablePort.java b/src/com/jsyn/ports/GettablePort.java
deleted file mode 100644
index aabf5ca..0000000
--- a/src/com/jsyn/ports/GettablePort.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright 2009 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.ports;
-
-public interface GettablePort {
- String getName();
-
- int getNumParts();
-
- double getValue(int partNum);
-
- Object getUnitGenerator();
-}
diff --git a/src/com/jsyn/ports/InputMixingBlockPart.java b/src/com/jsyn/ports/InputMixingBlockPart.java
deleted file mode 100644
index 5b54b99..0000000
--- a/src/com/jsyn/ports/InputMixingBlockPart.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright 2009 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.ports;
-
-import java.io.PrintStream;
-
-import com.jsyn.Synthesizer;
-import com.jsyn.unitgen.UnitGenerator;
-
-/**
- * A UnitInputPort has an array of these, one for each part.
- *
- * @author Phil Burk 2009 Mobileer Inc
- */
-
-public class InputMixingBlockPart extends PortBlockPart {
- private double[] mixer = new double[Synthesizer.FRAMES_PER_BLOCK];
- private double current;
- private UnitInputPort unitInputPort;
-
- InputMixingBlockPart(UnitInputPort unitInputPort, double defaultValue) {
- super(unitInputPort, defaultValue);
- this.unitInputPort = unitInputPort;
- }
-
- @Override
- public double getValue() {
- return current;
- }
-
- @Override
- protected void setValue(double value) {
- current = value;
- super.setValue(value);
- }
-
- @Override
- public double[] getValues() {
- double[] result;
- int numConnections = getConnectionCount();
- // System.out.println("numConnection = " + numConnections + " for " +
- // this );
- if (numConnections == 0) {
- // No connection so just use our own data.
- result = super.getValues();
- } else {
- // Mix all of the connected ports.
- double[] inputs;
- int jCon = 0;
- PortBlockPart otherPart;
- // Choose value to initialize the mixer array.
- if (unitInputPort.isValueAdded()) {
- inputs = super.getValues(); // prime mixer with the set() values
- jCon = 0;
- } else {
- otherPart = getConnection(jCon);
- inputs = otherPart.getValues(); // prime mixer with first connected
- jCon = 1;
- }
- for (int i = 0; i < mixer.length; i++) {
- mixer[i] = inputs[i];
- }
- // Now mix in the remaining inputs.
- for (; jCon < numConnections; jCon++) {
- otherPart = getConnection(jCon);
- inputs = otherPart.getValues();
- for (int i = 0; i < mixer.length; i++) {
- mixer[i] += inputs[i];
- }
- }
- result = mixer;
- }
- current = result[0];
- return result;
- }
-
- private void printIndentation(PrintStream out, int level) {
- for (int i = 0; i < level; i++) {
- out.print(" ");
- }
- }
-
- private String portToString(UnitBlockPort port) {
- UnitGenerator ugen = port.getUnitGenerator();
- return ugen.getClass().getSimpleName() + "." + port.getName();
- }
-
- public void printConnections(PrintStream out, int level) {
- for (int i = 0; i < getConnectionCount(); i++) {
- PortBlockPart part = getConnection(i);
-
- printIndentation(out, level);
- out.println(portToString(getPort()) + " <--- " + portToString(part.getPort()));
-
- part.getPort().getUnitGenerator().printConnections(out, level + 1);
- }
- }
-}
diff --git a/src/com/jsyn/ports/PortBlockPart.java b/src/com/jsyn/ports/PortBlockPart.java
deleted file mode 100644
index ad75211..0000000
--- a/src/com/jsyn/ports/PortBlockPart.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright 2009 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.ports;
-
-import java.util.ArrayList;
-
-import com.jsyn.Synthesizer;
-import com.jsyn.engine.SynthesisEngine;
-import com.softsynth.shared.time.ScheduledCommand;
-import com.softsynth.shared.time.TimeStamp;
-
-/**
- * Part of a multi-part port, for example, the left side of a stereo port.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public class PortBlockPart implements ConnectableOutput, ConnectableInput {
- private double[] values = new double[Synthesizer.FRAMES_PER_BLOCK];
- private ArrayList<PortBlockPart> connections = new ArrayList<PortBlockPart>();
- private UnitBlockPort unitBlockPort;
-
- protected PortBlockPart(UnitBlockPort unitBlockPort, double defaultValue) {
- this.unitBlockPort = unitBlockPort;
- setValue(defaultValue);
- }
-
- public double[] getValues() {
- return values;
- }
-
- public double getValue() {
- return values[0];
- }
-
- public double get() {
- return values[0];
- }
-
- protected void setValue(double value) {
- for (int i = 0; i < values.length; i++) {
- values[i] = value;
- }
- }
-
- protected boolean isConnected() {
- return (connections.size() > 0);
- }
-
- private void addConnection(PortBlockPart otherPart) {
- // System.out.println("addConnection from " + this + " to " + otherPart
- // );
- if (connections.contains(otherPart)) {
- System.out.println("addConnection already had connection from " + this + " to "
- + otherPart);
- } else {
- connections.add(otherPart);
- }
- }
-
- private void removeConnection(PortBlockPart otherPart) {
- // System.out.println("removeConnection from " + this + " to " +
- // otherPart );
- connections.remove(otherPart);
- }
-
- private void connectNow(PortBlockPart otherPart) {
- addConnection(otherPart);
- otherPart.addConnection(this);
- }
-
- private void disconnectNow(PortBlockPart otherPart) {
- removeConnection(otherPart);
- otherPart.removeConnection(this);
- }
-
- private void disconnectAllNow() {
- for (PortBlockPart part : connections) {
- part.removeConnection(this);
- }
- connections.clear();
- }
-
- public PortBlockPart getConnection(int i) {
- return connections.get(i);
- }
-
- public int getConnectionCount() {
- return connections.size();
- }
-
- /** Set all values to the last value. */
- protected void flatten() {
- double lastValue = values[values.length - 1];
- for (int i = 0; i < values.length - 1; i++) {
- values[i] = lastValue;
- }
- }
-
- protected UnitBlockPort getPort() {
- return unitBlockPort;
- }
-
- private void checkConnection(PortBlockPart destination) {
- SynthesisEngine sourceSynth = unitBlockPort.getSynthesisEngine();
- SynthesisEngine destSynth = destination.unitBlockPort.getSynthesisEngine();
- if ((sourceSynth != destSynth) && (sourceSynth != null) && (destSynth != null)) {
- throw new RuntimeException("Connection between units on different synths.");
- }
- }
-
- protected void connect(final PortBlockPart destination) {
- checkConnection(destination);
- unitBlockPort.queueCommand(new ScheduledCommand() {
- @Override
- public void run() {
- connectNow(destination);
- }
- });
- }
-
- protected void connect(final PortBlockPart destination, TimeStamp timeStamp) {
- unitBlockPort.scheduleCommand(timeStamp, new ScheduledCommand() {
- @Override
- public void run() {
- connectNow(destination);
- }
- });
- }
-
- protected void disconnect(final PortBlockPart destination) {
- unitBlockPort.queueCommand(new ScheduledCommand() {
- @Override
- public void run() {
- disconnectNow(destination);
- }
- });
- }
-
- protected void disconnect(final PortBlockPart destination, TimeStamp timeStamp) {
- unitBlockPort.scheduleCommand(timeStamp, new ScheduledCommand() {
- @Override
- public void run() {
- disconnectNow(destination);
- }
- });
- }
-
- protected void disconnectAll() {
- unitBlockPort.queueCommand(new ScheduledCommand() {
- @Override
- public void run() {
- disconnectAllNow();
- }
- });
- }
-
- @Override
- public void connect(ConnectableInput other) {
- connect(other.getPortBlockPart());
- }
-
- @Override
- public void connect(ConnectableOutput other) {
- other.connect(this);
- }
-
- @Override
- public void disconnect(ConnectableOutput other) {
- other.disconnect(this);
- }
-
- @Override
- public void disconnect(ConnectableInput other) {
- disconnect(other.getPortBlockPart());
- }
-
- /** To implement ConnectableInput */
- @Override
- public PortBlockPart getPortBlockPart() {
- return this;
- }
-
- @Override
- public void pullData(long frameCount, int start, int limit) {
- for (int i = 0; i < getConnectionCount(); i++) {
- PortBlockPart part = getConnection(i);
- part.getPort().getUnitGenerator().pullData(frameCount, start, limit);
- }
- }
-
-}
diff --git a/src/com/jsyn/ports/QueueDataCommand.java b/src/com/jsyn/ports/QueueDataCommand.java
deleted file mode 100644
index c23fbcd..0000000
--- a/src/com/jsyn/ports/QueueDataCommand.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright 2009 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.ports;
-
-import com.jsyn.data.SequentialData;
-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.
- * QueueDataCommand command = envelopePlayer.dataQueue.createQueueDataCommand( envelope, 0,
- * envelope.getNumFrames() );
- * // Create an object to be called when the queued data is done.
- * TestQueueCallback callback = new TestQueueCallback();
- * command.setCallback( callback );
- * command.setNumLoops( 2 );
- * envelopePlayer.rate.set( 0.2 );
- * synth.queueCommand( command );
- * </code>
- * </pre>
- *
- * The callback will be passed QueueDataEvents.
- *
- * <pre>
- * <code>
- * class TestQueueCallback implements UnitDataQueueCallback
- * {
- * public void started( QueueDataEvent event )
- * {
- * 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.");
- * }
- * }
- * </code>
- * </pre>
- *
- * @author Phil Burk 2009 Mobileer Inc
- */
-public abstract class QueueDataCommand extends QueueDataEvent implements ScheduledCommand {
-
- protected SequentialDataCrossfade crossfadeData;
- protected SequentialData currentData;
-
- private static final long serialVersionUID = -1185274459972359536L;
- private UnitDataQueueCallback callback;
-
- public QueueDataCommand(UnitDataQueuePort port, SequentialData sequentialData, int startFrame,
- int numFrames) {
- super(port);
-
- 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();
- this.startFrame = startFrame;
- this.numFrames = numFrames;
- }
-
- @Override
- public abstract void run();
-
- /**
- * 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) {
- this.skipIfOthers = skipIfOthers;
- }
-
- /**
- * If true then the queue will be cleared and this item will be started immediately. It is
- * 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) {
- this.immediate = immediate;
- }
-
- public UnitDataQueueCallback getCallback() {
- return callback;
- }
-
- public void setCallback(UnitDataQueueCallback callback) {
- this.callback = callback;
- }
-
- public SequentialDataCrossfade getCrossfadeData() {
- return crossfadeData;
- }
-
- public void setCrossfadeData(SequentialDataCrossfade crossfadeData) {
- this.crossfadeData = crossfadeData;
- }
-
- public SequentialData getCurrentData() {
- return currentData;
- }
-
- public void setCurrentData(SequentialData currentData) {
- this.currentData = currentData;
- }
-
- /**
- * Stop the unit that contains this port after this command has finished.
- *
- * @param autoStop
- */
- public void setAutoStop(boolean autoStop) {
- this.autoStop = autoStop;
- }
-
- /**
- * 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) {
- this.numLoops = numLoops;
- }
-
- /**
- * 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) {
- this.crossFadeIn = size;
- }
-
-}
diff --git a/src/com/jsyn/ports/QueueDataEvent.java b/src/com/jsyn/ports/QueueDataEvent.java
deleted file mode 100644
index 2b93fab..0000000
--- a/src/com/jsyn/ports/QueueDataEvent.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright 2009 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.ports;
-
-import java.util.EventObject;
-
-import com.jsyn.data.SequentialData;
-
-/**
- * An event that is passed to a UnitDataQueueCallback when the element in the queue is played..
- *
- * @author Phil Burk 2009 Mobileer Inc
- */
-public class QueueDataEvent extends EventObject {
- private static final long serialVersionUID = 176846633064538053L;
- protected SequentialData sequentialData;
- protected int startFrame;
- protected int numFrames;
- protected int numLoops;
- protected int loopsLeft;
- protected int crossFadeIn;
- protected boolean skipIfOthers;
- protected boolean autoStop;
- protected boolean immediate;
-
- public QueueDataEvent(Object arg0) {
- super(arg0);
- }
-
- public boolean isSkipIfOthers() {
- return skipIfOthers;
- }
-
- public boolean isImmediate() {
- return immediate;
- }
-
- public SequentialData getSequentialData() {
- return sequentialData;
- }
-
- public int getCrossFadeIn() {
- return crossFadeIn;
- }
-
- public int getStartFrame() {
- return startFrame;
- }
-
- public int getNumFrames() {
- return numFrames;
- }
-
- public int getNumLoops() {
- return numLoops;
- }
-
- public int getLoopsLeft() {
- return loopsLeft;
- }
-
- public boolean isAutoStop() {
- return autoStop;
- }
-
-}
diff --git a/src/com/jsyn/ports/SequentialDataCrossfade.java b/src/com/jsyn/ports/SequentialDataCrossfade.java
deleted file mode 100644
index 25e1fd9..0000000
--- a/src/com/jsyn/ports/SequentialDataCrossfade.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright 2009 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.ports;
-
-import com.jsyn.data.SequentialData;
-import com.jsyn.data.SequentialDataCommon;
-
-/**
- * A SequentialData object that will crossfade between two other SequentialData objects. The
- * crossfade is linear. This could, for example, be used to create a smooth transition between two
- * samples, or between two arbitrary regions in one sample. As an example, consider a sample that
- * has a length of 200000 frames. You could specify a sample loop that started arbitrarily at frame
- * 50000 and with a size of 30000 frames. Unless you got lucky with the zero crossings, it is likely
- * that you will hear a pop when this sample loops. To prevent the pop you could crossfade the
- * beginning of the loop with the region immediately after the end of the loop. To crossfade with
- * 5000 samples after the loop:
- *
- * <pre>
- * SequentialDataCrossfade xfade = new SequentialDataCrossfade(sample, (50000 + 30000), 5000, sample,
- * 50000, 30000);
- * </pre>
- *
- * After the crossfade you will hear the rest of the target at full volume. There are two regions
- * that determine what is returned from readDouble()
- * <ol>
- * <li>Crossfade region with size crossFadeFrames. It fades smoothly from source to target.</li>
- * <li>Steady region that is simply the target values with size (numFrames-crossFadeFrames).</li>
- * </ol>
- *
- * <pre>
- * "Crossfade Region" "Steady Region"
- * |-- source fading out --|
- * |-- target fading in --|-- remainder of target at original volume --|
- * </pre>
- *
- * @author Phil Burk
- */
-class SequentialDataCrossfade extends SequentialDataCommon {
- private SequentialData source;
- private int sourceStartIndex;
-
- private SequentialData target;
- private int targetStartIndex;
-
- private int crossFadeFrames;
- private double frameScaler;
-
- /**
- * @param source SequentialData that will be at full volume at the beginning of the crossfade
- * region.
- * @param sourceStartFrame Frame in source to begin the crossfade.
- * @param crossFadeFrames Number of frames in the crossfaded region.
- * @param target SequentialData that will be at full volume at the end of the crossfade region.
- * @param targetStartFrame Frame in target to begin the crossfade.
- * @param numFrames total number of frames in this data object.
- */
- public void setup(SequentialData source, int sourceStartFrame, int crossFadeFrames,
- SequentialData target, int targetStartFrame, int numFrames) {
-
- assert ((sourceStartFrame + crossFadeFrames) <= source.getNumFrames());
- assert ((targetStartFrame + numFrames) <= target.getNumFrames());
-
- // System.out.println( "WARNING! sourceStartFrame = " + sourceStartFrame
- // + ", crossFadeFrames = " + crossFadeFrames + ", maxFrame = "
- // + source.getNumFrames() + ", source = " + source );
- // System.out.println( " targetStartFrame = " + targetStartFrame
- // + ", numFrames = " + numFrames + ", maxFrame = "
- // + target.getNumFrames() + ", target = " + target );
-
- // There is a danger that we might nest SequentialDataCrossfades deeply
- // as source. If past crossfade region then pull out the target.
- if (source instanceof SequentialDataCrossfade) {
- SequentialDataCrossfade crossfade = (SequentialDataCrossfade) source;
- // If we are starting past the crossfade region then just use the
- // target.
- if (sourceStartFrame >= crossfade.crossFadeFrames) {
- source = crossfade.target;
- sourceStartFrame += crossfade.targetStartIndex / source.getChannelsPerFrame();
- }
- }
-
- if (target instanceof SequentialDataCrossfade) {
- SequentialDataCrossfade crossfade = (SequentialDataCrossfade) target;
- target = crossfade.target;
- targetStartFrame += crossfade.targetStartIndex / target.getChannelsPerFrame();
- }
-
- this.source = source;
- this.target = target;
- this.sourceStartIndex = sourceStartFrame * source.getChannelsPerFrame();
- this.crossFadeFrames = crossFadeFrames;
- this.targetStartIndex = targetStartFrame * target.getChannelsPerFrame();
-
- frameScaler = (crossFadeFrames == 0) ? 1.0 : (1.0 / crossFadeFrames);
- this.numFrames = numFrames;
- }
-
- @Override
- public void writeDouble(int index, double value) {
- }
-
- @Override
- public double readDouble(int index) {
- int frame = index / source.getChannelsPerFrame();
- if (frame < crossFadeFrames) {
- double factor = frame * frameScaler;
- double value = (1.0 - factor) * source.readDouble(index + sourceStartIndex);
- value += (factor * target.readDouble(index + targetStartIndex));
- return value;
- } else {
- return target.readDouble(index + targetStartIndex);
- }
- }
-
- @Override
- public double getRateScaler(int index, double synthesisRate) {
- return target.getRateScaler(index, synthesisRate);
- }
-
- @Override
- public int getChannelsPerFrame() {
- return target.getChannelsPerFrame();
- }
-
-}
diff --git a/src/com/jsyn/ports/SettablePort.java b/src/com/jsyn/ports/SettablePort.java
deleted file mode 100644
index e0db05c..0000000
--- a/src/com/jsyn/ports/SettablePort.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright 2009 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.ports;
-
-import com.softsynth.shared.time.TimeStamp;
-
-/**
- * Port whose parts can be set.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public interface SettablePort extends GettablePort {
- void set(int partNum, double value, TimeStamp timeStamp);
-}
diff --git a/src/com/jsyn/ports/UnitBlockPort.java b/src/com/jsyn/ports/UnitBlockPort.java
deleted file mode 100644
index d7fc82f..0000000
--- a/src/com/jsyn/ports/UnitBlockPort.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright 2009 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.ports;
-
-/**
- * A port that contains multiple parts with blocks of data.
- *
- * @author Phil Burk 2009 Mobileer Inc
- */
-public class UnitBlockPort extends UnitPort {
- PortBlockPart[] parts;
-
- public UnitBlockPort(int numParts, String name, double defaultValue) {
- super(name);
- makeParts(numParts, defaultValue);
- }
-
- public UnitBlockPort(String name) {
- this(1, name, 0.0);
- }
-
- protected void makeParts(int numParts, double defaultValue) {
- parts = new PortBlockPart[numParts];
- for (int i = 0; i < numParts; i++) {
- parts[i] = new PortBlockPart(this, defaultValue);
- }
- }
-
- @Override
- public int getNumParts() {
- return parts.length;
- }
-
- /**
- * Convenience call to get(0).
- *
- * @return value of 0th part as set
- */
- public double get() {
- return get(0);
- }
-
- public double getValue() {
- return getValue(0);
- }
-
- /**
- * This is used inside UnitGenerators to get the current values for a port. It works regardless
- * of whether the port is connected or not.
- *
- * @return
- */
- public double[] getValues() {
- return parts[0].getValues();
- }
-
- /** Only for use in the audio thread when implementing UnitGenerators. */
- public double[] getValues(int partNum) {
- return parts[partNum].getValues();
- }
-
- /** Get the immediate current value of the port. */
- public double getValue(int partNum) {
- return parts[partNum].getValue();
- }
-
- public double get(int partNum) {
- return parts[partNum].get();
- }
-
- /** Only for use in the audio thread when implementing UnitGenerators. */
- protected void setValueInternal(int partNum, double value) {
- parts[partNum].setValue(value);
- }
-
- /** Only for use in the audio thread when implementing UnitGenerators. */
- public void setValueInternal(double value) {
- setValueInternal(0, value);
- }
-
- public boolean isConnected() {
- return isConnected(0);
- }
-
- public boolean isConnected(int partNum) {
- return parts[partNum].isConnected();
- }
-
- public void disconnectAll(int partNum) {
- parts[partNum].disconnectAll();
- }
-
- public void disconnectAll() {
- disconnectAll(0);
- }
-}
diff --git a/src/com/jsyn/ports/UnitDataQueueCallback.java b/src/com/jsyn/ports/UnitDataQueueCallback.java
deleted file mode 100644
index dca4adc..0000000
--- a/src/com/jsyn/ports/UnitDataQueueCallback.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2011 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.ports;
-
-/**
- * This is called when a block of data that is queued to a UnitDataQueuePort starts, loops, or
- * finishes.
- *
- * @author Phil Burk (C) 2011 Mobileer Inc
- */
-public interface UnitDataQueueCallback {
- public void started(QueueDataEvent event);
-
- public void looped(QueueDataEvent event);
-
- public void finished(QueueDataEvent event);
-}
diff --git a/src/com/jsyn/ports/UnitDataQueuePort.java b/src/com/jsyn/ports/UnitDataQueuePort.java
deleted file mode 100644
index 5487589..0000000
--- a/src/com/jsyn/ports/UnitDataQueuePort.java
+++ /dev/null
@@ -1,466 +0,0 @@
-/*
- * Copyright 2009 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.ports;
-
-import java.util.LinkedList;
-
-import com.jsyn.data.SequentialData;
-import com.jsyn.exceptions.ChannelMismatchException;
-import com.softsynth.shared.time.ScheduledCommand;
-import com.softsynth.shared.time.TimeStamp;
-
-/**
- * Queue for SequentialData, samples or envelopes
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public class UnitDataQueuePort extends UnitPort {
- private final LinkedList<QueuedBlock> blocks = new LinkedList<QueuedBlock>();
- private QueueDataCommand currentBlock;
- private int frameIndex;
- private int numChannels = 1;
- private double normalizedRate;
- private long framesMoved;
- private boolean autoStopPending;
- private boolean targetValid;
- private QueueDataCommand finishingBlock;
- private QueueDataCommand loopingBlock;
- public static final int LOOP_IF_LAST = -1;
-
- public UnitDataQueuePort(String name) {
- super(name);
- }
-
- /** Hold a reference to part of a sample. */
- @SuppressWarnings("serial")
- private class QueuedBlock extends QueueDataCommand {
-
- public QueuedBlock(SequentialData queueableData, int startFrame, int numFrames) {
- super(UnitDataQueuePort.this, queueableData, startFrame, numFrames);
- }
-
- @Override
- public void run() {
- synchronized (blocks) {
- // Remove last block if it can be skipped.
- if (blocks.size() > 0) {
- QueueDataEvent lastBlock = blocks.getLast();
- if (lastBlock.isSkipIfOthers()) {
- blocks.removeLast();
- }
- }
-
- // If we are crossfading then figure out where to crossfade
- // from.
- if (getCrossFadeIn() > 0) {
- if (isImmediate()) {
- // Queue will be cleared so fade in from current.
- if (currentBlock != null) {
- setupCrossFade(currentBlock, frameIndex, this);
- }
- // else nothing is playing so don't crossfade.
- } else {
- QueueDataCommand endBlock = getEndBlock();
- if (endBlock != null) {
- setupCrossFade(endBlock,
- endBlock.getStartFrame() + endBlock.getNumFrames(), this);
- }
- }
- }
-
- if (isImmediate()) {
- clearQueue();
- }
-
- blocks.add(this);
- }
- }
- }
-
- // FIXME - determine crossfade on any transition between blocks or when looping back.
-
- protected void setupCrossFade(QueueDataCommand sourceCommand, int sourceStartIndex,
- QueueDataCommand targetCommand) {
- int crossFrames = targetCommand.getCrossFadeIn();
- SequentialData sourceData = sourceCommand.getCurrentData();
- SequentialData targetData = targetCommand.getCurrentData();
- int remainingSource = sourceData.getNumFrames() - sourceStartIndex;
- // clip to end of source
- if (crossFrames > remainingSource)
- crossFrames = remainingSource;
- if (crossFrames > 0) {
- // The SequentialDataCrossfade should continue to the end of the target
- // so that we can crossfade from it to the target.
- int remainingTarget = targetData.getNumFrames() - targetCommand.getStartFrame();
- targetCommand.crossfadeData.setup(sourceData, sourceStartIndex, crossFrames,
- targetData, targetCommand.getStartFrame(), remainingTarget);
- targetCommand.currentData = targetCommand.crossfadeData;
- targetCommand.startFrame = 0;
- }
- }
-
- public QueueDataCommand createQueueDataCommand(SequentialData queueableData) {
- return createQueueDataCommand(queueableData, 0, queueableData.getNumFrames());
- }
-
- public QueueDataCommand createQueueDataCommand(SequentialData queueableData, int startFrame,
- int numFrames) {
- if (queueableData.getChannelsPerFrame() != UnitDataQueuePort.this.numChannels) {
- throw new ChannelMismatchException("Tried to queue "
- + queueableData.getChannelsPerFrame() + " channel data to a " + numChannels
- + " channel port.");
- }
- return new QueuedBlock(queueableData, startFrame, numFrames);
- }
-
- public QueueDataCommand getEndBlock() {
- if (blocks.size() > 0) {
- return blocks.getLast();
- } else if (currentBlock != null) {
- return currentBlock;
- } else {
- return null;
- }
- }
-
- public void setCurrentBlock(QueueDataCommand currentBlock) {
- this.currentBlock = currentBlock;
- }
-
- public void firePendingCallbacks() {
- if (loopingBlock != null) {
- if (loopingBlock.getCallback() != null) {
- loopingBlock.getCallback().looped(currentBlock);
- }
- loopingBlock = null;
- }
- if (finishingBlock != null) {
- if (finishingBlock.getCallback() != null) {
- finishingBlock.getCallback().finished(currentBlock); // FIXME - Should this pass
- // finishingBlock?!
- }
- finishingBlock = null;
- }
- }
-
- public boolean hasMore() {
- return (currentBlock != null) || (blocks.size() > 0);
- }
-
- private void checkBlock() {
- if (currentBlock == null) {
- synchronized (blocks) {
- setCurrentBlock(blocks.remove());
- frameIndex = currentBlock.getStartFrame();
- currentBlock.loopsLeft = currentBlock.getNumLoops();
- if (currentBlock.getCallback() != null) {
- currentBlock.getCallback().started(currentBlock);
- }
- }
- }
- }
-
- private void advanceFrameIndex() {
- frameIndex += 1;
- framesMoved += 1;
- // Are we done with this block?
- if (frameIndex >= (currentBlock.getStartFrame() + currentBlock.getNumFrames())) {
- // Should we loop on this block based on a counter?
- if (currentBlock.loopsLeft > 0) {
- currentBlock.loopsLeft -= 1;
- loopToStart();
- }
- // Should we loop forever on this block?
- else if ((blocks.size() == 0) && (currentBlock.loopsLeft < 0)) {
- loopToStart();
- }
- // We are done.
- else {
- if (currentBlock.isAutoStop()) {
- autoStopPending = true;
- }
- finishingBlock = currentBlock;
- setCurrentBlock(null);
- // System.out.println("advanceFrameIndex: currentBlock set null");
- }
- }
- }
-
- private void loopToStart() {
- if (currentBlock.getCrossFadeIn() > 0) {
- setupCrossFade(currentBlock, frameIndex, currentBlock);
- }
- frameIndex = currentBlock.getStartFrame();
- loopingBlock = currentBlock;
- }
-
- public double getNormalizedRate() {
- return normalizedRate;
- }
-
- public double readCurrentChannelDouble(int channelIndex) {
- return currentBlock.currentData.readDouble((frameIndex * numChannels) + channelIndex);
- }
-
- public void writeCurrentChannelDouble(int channelIndex, double value) {
- currentBlock.currentData.writeDouble((frameIndex * numChannels) + channelIndex, value);
- }
-
- public void beginFrame(double synthesisPeriod) {
- checkBlock();
- normalizedRate = currentBlock.currentData.getRateScaler(frameIndex, synthesisPeriod);
- }
-
- public void endFrame() {
- advanceFrameIndex();
- targetValid = true;
- }
-
- public double readNextMonoDouble(double synthesisPeriod) {
- beginFrame(synthesisPeriod);
- double value = currentBlock.currentData.readDouble(frameIndex);
- endFrame();
- return value;
- }
-
- /** Write directly to the port queue. This is only called by unit tests! */
- protected void addQueuedBlock(QueueDataEvent block) {
- blocks.add((QueuedBlock) block);
- }
-
- /** Clear the queue. Internal use only. */
- protected void clearQueue() {
- synchronized (blocks) {
- blocks.clear();
- setCurrentBlock(null);
- targetValid = false;
- autoStopPending = false;
- }
- }
-
- class ClearQueueCommand implements ScheduledCommand {
- @Override
- public void run() {
- clearQueue();
- }
- }
-
- /** Queue the data to the port at a future time. */
- public void queue(SequentialData queueableData, int startFrame, int numFrames,
- TimeStamp timeStamp) {
- QueueDataCommand command = createQueueDataCommand(queueableData, startFrame, numFrames);
- scheduleCommand(timeStamp, command);
- }
-
- /**
- * Queue the data to the port at a future time. Command will clear the queue before executing.
- */
- public void queueImmediate(SequentialData queueableData, int startFrame, int numFrames,
- TimeStamp timeStamp) {
- QueueDataCommand command = createQueueDataCommand(queueableData, startFrame, numFrames);
- command.setImmediate(true);
- scheduleCommand(timeStamp, command);
- }
-
- /** Queue the data to the port at a future time. */
- public void queueLoop(SequentialData queueableData, int startFrame, int numFrames,
- TimeStamp timeStamp) {
- queueLoop(queueableData, startFrame, numFrames, LOOP_IF_LAST, timeStamp);
- }
-
- /**
- * Queue the data to the port at a future time with a specified number of loops.
- */
- public void queueLoop(SequentialData queueableData, int startFrame, int numFrames,
- int numLoops, TimeStamp timeStamp) {
- QueueDataCommand command = createQueueDataCommand(queueableData, startFrame, numFrames);
- command.setNumLoops(numLoops);
- scheduleCommand(timeStamp, command);
- }
-
- /** Queue the entire data object for looping. */
- public void queueLoop(SequentialData queueableData) {
- queueLoop(queueableData, 0, queueableData.getNumFrames());
- }
-
- /** Queue the data to the port for immediate use. */
- public void queueLoop(SequentialData queueableData, int startFrame, int numFrames) {
- queueLoop(queueableData, startFrame, numFrames, LOOP_IF_LAST);
- }
-
- /**
- * Queue the data to the port for immediate use with a specified number of loops.
- */
- public void queueLoop(SequentialData queueableData, int startFrame, int numFrames, int numLoops) {
- QueueDataCommand command = createQueueDataCommand(queueableData, startFrame, numFrames);
- command.setNumLoops(numLoops);
- queueCommand(command);
- }
-
- /**
- * Queue the data to the port at a future time. Request that the unit stop when this block is
- * finished.
- */
- public void queueStop(SequentialData queueableData, int startFrame, int numFrames,
- TimeStamp timeStamp) {
- QueueDataCommand command = createQueueDataCommand(queueableData, startFrame, numFrames);
- command.setAutoStop(true);
- scheduleCommand(timeStamp, command);
- }
-
- /** Queue the data to the port through the command queue ASAP. */
- public void queue(SequentialData queueableData, int startFrame, int numFrames) {
- QueueDataCommand command = createQueueDataCommand(queueableData, startFrame, numFrames);
- queueCommand(command);
- }
-
- /**
- * Queue entire amount of data with no options.
- *
- * @param queueableData
- */
- public void queue(SequentialData queueableData) {
- queue(queueableData, 0, queueableData.getNumFrames());
- }
-
- /** Schedule queueOn now! */
- public void queueOn(SequentialData queueableData) {
- queueOn(queueableData, getSynthesisEngine().createTimeStamp());
- }
-
- /** Schedule queueOff now! */
- public void queueOff(SequentialData queueableData) {
- queueOff(queueableData, false);
- }
-
- /** Schedule queueOff now! */
- public void queueOff(SequentialData queueableData, boolean ifStop) {
- queueOff(queueableData, ifStop, getSynthesisEngine().createTimeStamp());
- }
-
- /**
- * Convenience method that will queue the attack portion of a channelData and the sustain loop
- * if it exists. This could be used to implement a NoteOn method.
- */
- public void queueOn(SequentialData queueableData, TimeStamp timeStamp) {
-
- if (queueableData.getSustainBegin() < 0) {
- // no sustain loop, handle release
- if (queueableData.getReleaseBegin() < 0) {
- // No loops
- queueImmediate(queueableData, 0, queueableData.getNumFrames(), timeStamp);
- } else {
- queueImmediate(queueableData, 0, queueableData.getReleaseEnd(), timeStamp);
- int size = queueableData.getReleaseEnd() - queueableData.getReleaseBegin();
- queueLoop(queueableData, queueableData.getReleaseBegin(), size, timeStamp);
- }
- } else {
- // yes sustain loop
- if (queueableData.getSustainEnd() > 0) {
- int frontSize = queueableData.getSustainBegin();
- int loopSize = queueableData.getSustainEnd() - queueableData.getSustainBegin();
- // Is there an initial portion before the sustain loop?
- if (frontSize > 0) {
- queueImmediate(queueableData, 0, frontSize, timeStamp);
- }
- loopSize = queueableData.getSustainEnd() - queueableData.getSustainBegin();
- if (loopSize > 0) {
- queueLoop(queueableData, queueableData.getSustainBegin(), loopSize, timeStamp);
- }
- }
-
- }
- }
-
- /**
- * Convenience method that will queue the decay portion of a SequentialData object, or the gap
- * and release loop portions if they exist. This could be used to implement a NoteOff method.
- *
- * @param ifStop Will setAutostop(true) if release portion queued without a release loop. This will
- * stop execution of the unit.
- */
- public void queueOff(SequentialData queueableData, boolean ifStop, TimeStamp timeStamp) {
- if (queueableData.getSustainBegin() >= 0) /* Sustain loop? */
- {
- int relSize = queueableData.getReleaseEnd() - queueableData.getReleaseBegin();
- if (queueableData.getReleaseBegin() < 0) { /* Sustain loop, no release loop. */
- int susEnd = queueableData.getSustainEnd();
- int size = queueableData.getNumFrames() - susEnd;
- // System.out.println("queueOff: size = " + size );
- if (size <= 0) {
- // always queue something so that we can stop the loop
- // 20001117
- size = 1;
- susEnd = queueableData.getNumFrames() - 1;
- }
- if (ifStop) {
- queueStop(queueableData, susEnd, size, timeStamp);
- } else {
- queue(queueableData, susEnd, size, timeStamp);
- }
- } else if (queueableData.getReleaseBegin() > queueableData.getSustainEnd()) {
- // Queue gap between sustain and release loop.
- queue(queueableData, queueableData.getSustainEnd(), queueableData.getReleaseEnd()
- - queueableData.getSustainEnd(), timeStamp);
- if (relSize > 0)
- queueLoop(queueableData, queueableData.getReleaseBegin(), relSize, timeStamp);
- } else if (relSize > 0) {
- // No gap between sustain and release.
- queueLoop(queueableData, queueableData.getReleaseBegin(), relSize, timeStamp);
- }
- }
- /* If no sustain loop, then nothing to do. */
- }
-
- public void clear(TimeStamp timeStamp) {
- ScheduledCommand command = new ClearQueueCommand();
- scheduleCommand(timeStamp, command);
- }
-
- public void clear() {
- ScheduledCommand command = new ClearQueueCommand();
- queueCommand(command);
- }
-
- public void writeNextDouble(double value) {
- checkBlock();
- currentBlock.currentData.writeDouble(frameIndex, value);
- advanceFrameIndex();
- }
-
- public long getFrameCount() {
- return framesMoved;
- }
-
- public boolean testAndClearAutoStop() {
- boolean temp = autoStopPending;
- autoStopPending = false;
- return temp;
- }
-
- public boolean isTargetValid() {
- return targetValid;
- }
-
- public void setNumChannels(int numChannels) {
- this.numChannels = numChannels;
- }
-
- public int getNumChannels() {
- return numChannels;
- }
-}
diff --git a/src/com/jsyn/ports/UnitFunctionPort.java b/src/com/jsyn/ports/UnitFunctionPort.java
deleted file mode 100644
index e45241a..0000000
--- a/src/com/jsyn/ports/UnitFunctionPort.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2009 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.ports;
-
-import com.jsyn.data.Function;
-
-/**
- * Port for holding a Function object.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public class UnitFunctionPort extends UnitPort {
- private static NullFunction nullFunction = new NullFunction();
- private Function function = nullFunction;
-
- private static class NullFunction implements Function {
- @Override
- public double evaluate(double input) {
- return 0.0;
- }
- }
-
- public UnitFunctionPort(String name) {
- super(name);
- }
-
- public void set(Function function) {
- this.function = function;
- }
-
- public Function get() {
- return function;
- }
-}
diff --git a/src/com/jsyn/ports/UnitGatePort.java b/src/com/jsyn/ports/UnitGatePort.java
deleted file mode 100644
index 700aef8..0000000
--- a/src/com/jsyn/ports/UnitGatePort.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright 2009 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.ports;
-
-import com.jsyn.unitgen.UnitGenerator;
-import com.softsynth.shared.time.ScheduledCommand;
-import com.softsynth.shared.time.TimeStamp;
-
-public class UnitGatePort extends UnitInputPort {
- private boolean autoDisableEnabled = false;
- private boolean triggered = false;
- private boolean off = true;
- private UnitGenerator gatedUnit;
- public static final double THRESHOLD = 0.01;
-
- public UnitGatePort(String name) {
- super(name);
- }
-
- public void on() {
- setOn(true);
- }
-
- public void off() {
- setOn(false);
- }
-
- public void off(TimeStamp timeStamp) {
- setOn(false, timeStamp);
- }
-
- public void on(TimeStamp timeStamp) {
- setOn(true, timeStamp);
- }
-
- private void setOn(final boolean on) {
- queueCommand(new ScheduledCommand() {
- @Override
- public void run() {
- setOnInternal(on);
- }
- });
- }
-
- private void setOn(final boolean on, TimeStamp timeStamp) {
- scheduleCommand(timeStamp, new ScheduledCommand() {
- @Override
- public void run() {
- setOnInternal(on);
- }
- });
- }
-
- private void setOnInternal(boolean on) {
- if (on) {
- triggerInternal();
- }
- setValueInternal(on ? 1.0 : 0.0);
- }
-
- private void triggerInternal() {
- getGatedUnit().setEnabled(true);
- triggered = true;
- }
-
- public void trigger() {
- queueCommand(new ScheduledCommand() {
- @Override
- public void run() {
- triggerInternal();
- }
- });
- }
-
- public void trigger(TimeStamp timeStamp) {
- scheduleCommand(timeStamp, new ScheduledCommand() {
- @Override
- public void run() {
- triggerInternal();
- }
- });
- }
-
- /**
- * This is called by UnitGenerators. It sets the off value that can be tested using isOff().
- *
- * @param i
- * @return true if triggered by a positive edge.
- */
- public boolean checkGate(int i) {
- double[] inputs = getValues();
- boolean result = triggered;
- triggered = false;
- if (off) {
- if (inputs[i] >= THRESHOLD) {
- result = true;
- off = false;
- }
- } else {
- if (inputs[i] < THRESHOLD) {
- off = true;
- }
- }
- return result;
- }
-
- public boolean isOff() {
- return off;
- }
-
- public boolean isAutoDisableEnabled() {
- return autoDisableEnabled;
- }
-
- /**
- * Request the containing UnitGenerator be disabled when checkAutoDisabled() is called. This can
- * be used to reduce CPU load.
- *
- * @param autoDisableEnabled
- */
- public void setAutoDisableEnabled(boolean autoDisableEnabled) {
- this.autoDisableEnabled = autoDisableEnabled;
- }
-
- /**
- * Called by UnitGenerator when an envelope reaches the end of its contour.
- */
- public void checkAutoDisable() {
- if (autoDisableEnabled) {
- getGatedUnit().setEnabled(false);
- }
- }
-
- private UnitGenerator getGatedUnit() {
- return (gatedUnit == null) ? getUnitGenerator() : gatedUnit;
- }
-
- public void setupAutoDisable(UnitGenerator unit) {
- gatedUnit = unit;
- setAutoDisableEnabled(true);
- // Start off disabled so we don't immediately swamp the CPU.
- gatedUnit.setEnabled(false);
- }
-}
diff --git a/src/com/jsyn/ports/UnitInputPort.java b/src/com/jsyn/ports/UnitInputPort.java
deleted file mode 100644
index 3eda1f6..0000000
--- a/src/com/jsyn/ports/UnitInputPort.java
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Copyright 2009 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.ports;
-
-import java.io.PrintStream;
-
-import com.softsynth.shared.time.ScheduledCommand;
-import com.softsynth.shared.time.TimeStamp;
-
-/**
- * A port that is used to pass values into a UnitGenerator.
- *
- * @author Phil Burk 2009 Mobileer Inc
- */
-public class UnitInputPort extends UnitBlockPort implements ConnectableInput, SettablePort {
- private double minimum = 0.0;
- private double maximum = 1.0;
- private double defaultValue = 0.0;
- private double[] setValues;
- private boolean valueAdded = false;
-
- /**
- * @param numParts typically 1, use 2 for stereo ports
- * @param name name that may be used in GUIs
- * @param defaultValue
- */
- public UnitInputPort(int numParts, String name, double defaultValue) {
- super(numParts, name, defaultValue);
- setDefault(defaultValue);
- setValues = new double[numParts];
- for (int i = 0; i < numParts; i++) {
- setValues[i] = defaultValue;
- }
- }
-
- public UnitInputPort(String name, double defaultValue) {
- this(1, name, defaultValue);
- }
-
- public UnitInputPort(String name) {
- this(1, name, 0.0);
- }
-
- public UnitInputPort(int numParts, String name) {
- this(numParts, name, 0.0);
- }
-
- @Override
- protected void makeParts(int numParts, double defaultValue) {
- parts = new InputMixingBlockPart[numParts];
- for (int i = 0; i < numParts; i++) {
- parts[i] = new InputMixingBlockPart(this, defaultValue);
- }
- }
-
- /**
- * This is used internally by the SynthesisEngine to execute units based on their connections.
- *
- * @param frameCount
- * @param start
- * @param limit
- */
- @Override
- public void pullData(long frameCount, int start, int limit) {
- for (PortBlockPart part : parts) {
- ((InputMixingBlockPart) part).pullData(frameCount, start, limit);
- }
- }
-
- @Override
- protected void setValueInternal(int partNum, double value) {
- super.setValueInternal(partNum, value);
- setValues[partNum] = value;
- }
-
- public void set(double value) {
- set(0, value);
- }
-
- public void set(final int partNum, final double value) {
- // Trigger exception now if out of range.
- setValues[partNum] = value;
- queueCommand(new ScheduledCommand() {
- @Override
- public void run() {
- setValueInternal(partNum, value);
- }
- });
- }
-
- public void set(double value, TimeStamp time) {
- set(0, value, time);
- }
-
- public void set(double value, double time) {
- set(0, value, time);
- }
-
- public void set(int partNum, double value, double time) {
- set(partNum, value, new TimeStamp(time));
- }
-
- @Override
- public void set(final int partNum, final double value, TimeStamp timeStamp) {
- // Trigger exception now if out of range.
- getValue(partNum);
- scheduleCommand(timeStamp, new ScheduledCommand() {
- @Override
- public void run() {
- setValueInternal(partNum, value);
- }
- });
- }
-
- /**
- * Value of a port based on the set() calls. Not affected by connected ports.
- *
- * @param partNum
- * @return value as set
- */
- @Override
- public double get(int partNum) {
- return setValues[partNum];
- }
-
- public double getMaximum() {
- return maximum;
- }
-
- /**
- * The minimum and maximum are only used when setting up knobs or other control systems. The
- * internal values are not clipped to this range.
- *
- * @param maximum
- */
- public void setMaximum(double maximum) {
- this.maximum = maximum;
- }
-
- public double getMinimum() {
- return minimum;
- }
-
- public void setMinimum(double minimum) {
- this.minimum = minimum;
- }
-
- public double getDefault() {
- return defaultValue;
- }
-
- public void setDefault(double defaultValue) {
- this.defaultValue = defaultValue;
- }
-
- /**
- * Convenience function for setting limits on a port. These limits are recommended values when
- * setting up a GUI. It is possible to set a port to a value outside these limits.
- *
- * @param minimum
- * @param value default value, will be clipped to min/max
- * @param maximum
- */
- public void setup(double minimum, double value, double maximum) {
- setMinimum(minimum);
- setMaximum(maximum);
- setDefault(value);
- set(value);
- }
-
- // Grab min, max, default from another port.
- public void setup(UnitInputPort other) {
- setup(other.getMinimum(), other.getDefault(), other.getMaximum());
- }
-
- public boolean isValueAdded() {
- return valueAdded;
- }
-
- /**
- * If set false then the set() value will be ignored when other ports are connected to this port.
- * The sum of the connected port values will be used instead.
- *
- * If set true then the set() value will be added to the sum of the connected port values.
- * This is useful when you want to modulate the set value.
- *
- * The default is false.
- *
- * @param valueAdded
- */
- public void setValueAdded(boolean valueAdded) {
- this.valueAdded = valueAdded;
- }
-
- public void connect(int thisPartNum, UnitOutputPort otherPort, int otherPartNum,
- TimeStamp timeStamp) {
- otherPort.connect(otherPartNum, this, thisPartNum, timeStamp);
- }
-
- /** Connect an input to an output port. */
- public void connect(int thisPartNum, UnitOutputPort otherPort, int otherPartNum) {
- // Typically connections are made from output to input because it is
- // more intuitive.
- otherPort.connect(otherPartNum, this, thisPartNum);
- }
-
- public void connect(UnitOutputPort otherPort) {
- connect(0, otherPort, 0);
- }
-
- @Override
- public void connect(ConnectableOutput other) {
- other.connect(this);
- }
-
- public void disconnect(int thisPartNum, UnitOutputPort otherPort, int otherPartNum) {
- otherPort.disconnect(otherPartNum, this, thisPartNum);
- }
-
- @Override
- public PortBlockPart getPortBlockPart() {
- return parts[0];
- }
-
- public ConnectableInput getConnectablePart(int i) {
- return parts[i];
- }
-
- @Override
- public void disconnect(ConnectableOutput other) {
- other.disconnect(this);
- }
-
- public void printConnections(PrintStream out, int level) {
- for (PortBlockPart part : parts) {
- ((InputMixingBlockPart) part).printConnections(out, level);
- }
- }
-
-}
diff --git a/src/com/jsyn/ports/UnitOutputPort.java b/src/com/jsyn/ports/UnitOutputPort.java
deleted file mode 100644
index 6fcd758..0000000
--- a/src/com/jsyn/ports/UnitOutputPort.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright 2009 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.ports;
-
-import com.jsyn.unitgen.UnitSink;
-import com.softsynth.shared.time.TimeStamp;
-
-/**
- * Units write to their output port blocks. Other multiple connected input ports read from them.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-
-public class UnitOutputPort extends UnitBlockPort implements ConnectableOutput, GettablePort {
- public UnitOutputPort() {
- this("Output");
- }
-
- public UnitOutputPort(String name) {
- this(1, name, 0.0);
- }
-
- public UnitOutputPort(int numParts, String name) {
- this(numParts, name, 0.0);
- }
-
- public UnitOutputPort(int numParts, String name, double defaultValue) {
- super(numParts, name, defaultValue);
- }
-
- public void flatten() {
- for (PortBlockPart part : parts) {
- part.flatten();
- }
- }
-
- public void connect(int thisPartNum, UnitInputPort otherPort, int otherPartNum) {
- PortBlockPart source = parts[thisPartNum];
- PortBlockPart destination = otherPort.parts[otherPartNum];
- source.connect(destination);
- }
-
- public void connect(int thisPartNum, UnitInputPort otherPort, int otherPartNum,
- TimeStamp timeStamp) {
- PortBlockPart source = parts[thisPartNum];
- PortBlockPart destination = otherPort.parts[otherPartNum];
- source.connect(destination, timeStamp);
- }
-
- public void connect(UnitInputPort input) {
- connect(0, input, 0);
- }
-
- @Override
- public void connect(ConnectableInput input) {
- parts[0].connect(input);
- }
-
- public void connect(UnitSink sink) {
- connect(0, sink.getInput(), 0);
- }
-
- public void disconnect(int thisPartNum, UnitInputPort otherPort, int otherPartNum) {
- PortBlockPart source = parts[thisPartNum];
- PortBlockPart destination = otherPort.parts[otherPartNum];
- source.disconnect(destination);
- }
-
- public void disconnect(int thisPartNum, UnitInputPort otherPort, int otherPartNum,
- TimeStamp timeStamp) {
- PortBlockPart source = parts[thisPartNum];
- PortBlockPart destination = otherPort.parts[otherPartNum];
- source.disconnect(destination, timeStamp);
- }
-
- public void disconnect(UnitInputPort otherPort) {
- disconnect(0, otherPort, 0);
- }
-
- @Override
- public void disconnect(ConnectableInput input) {
- parts[0].disconnect(input);
- }
-
- public ConnectableOutput getConnectablePart(int i) {
- return parts[i];
- }
-
-}
diff --git a/src/com/jsyn/ports/UnitPort.java b/src/com/jsyn/ports/UnitPort.java
deleted file mode 100644
index a652e68..0000000
--- a/src/com/jsyn/ports/UnitPort.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright 2009 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.ports;
-
-import com.jsyn.engine.SynthesisEngine;
-import com.jsyn.unitgen.UnitGenerator;
-import com.softsynth.shared.time.ScheduledCommand;
-import com.softsynth.shared.time.TimeStamp;
-
-/**
- * Basic audio port for JSyn unit generators.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public class UnitPort {
- private String name;
- private UnitGenerator unit;
-
- public UnitPort(String name) {
- this.name = name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String getName() {
- return name;
- }
-
- public void setUnitGenerator(UnitGenerator unit) {
- // If a port is in a circuit then we want to just use the lower level
- // unit that instantiated the circuit.
- if (this.unit == null) {
- this.unit = unit;
- }
- }
-
- public UnitGenerator getUnitGenerator() {
- return unit;
- }
-
- SynthesisEngine getSynthesisEngine() {
- if (unit == null) {
- return null;
- }
- return unit.getSynthesisEngine();
- }
-
- public int getNumParts() {
- return 1;
- }
-
- public void scheduleCommand(TimeStamp timeStamp, ScheduledCommand scheduledCommand) {
- if (getSynthesisEngine() == null) {
- scheduledCommand.run();
- } else {
- getSynthesisEngine().scheduleCommand(timeStamp, scheduledCommand);
- }
- }
-
- public void queueCommand(ScheduledCommand scheduledCommand) {
- if (getSynthesisEngine() == null) {
- scheduledCommand.run();
- } else {
- getSynthesisEngine().scheduleCommand(getSynthesisEngine().createTimeStamp(),
- scheduledCommand);
- }
- }
-
-}
diff --git a/src/com/jsyn/ports/UnitSpectralInputPort.java b/src/com/jsyn/ports/UnitSpectralInputPort.java
deleted file mode 100644
index bdf0ff5..0000000
--- a/src/com/jsyn/ports/UnitSpectralInputPort.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright 2009 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.ports;
-
-import com.jsyn.data.Spectrum;
-
-public class UnitSpectralInputPort extends UnitPort implements ConnectableInput {
- private UnitSpectralOutputPort other;
-
- private Spectrum spectrum;
-
- public UnitSpectralInputPort() {
- this("Output");
- }
-
- public UnitSpectralInputPort(String name) {
- super(name);
- }
-
- public void setSpectrum(Spectrum spectrum) {
- this.spectrum = spectrum;
- }
-
- public Spectrum getSpectrum() {
- if (other == null) {
- return spectrum;
- } else {
- return other.getSpectrum();
- }
- }
-
- @Override
- public void connect(ConnectableOutput other) {
- if (other instanceof UnitSpectralOutputPort) {
- this.other = (UnitSpectralOutputPort) other;
- } else {
- throw new RuntimeException(
- "Can only connect UnitSpectralOutputPort to UnitSpectralInputPort!");
- }
- }
-
- @Override
- public void disconnect(ConnectableOutput other) {
- if (this.other == other) {
- this.other = null;
- }
- }
-
- @Override
- public PortBlockPart getPortBlockPart() {
- return null;
- }
-
- @Override
- public void pullData(long frameCount, int start, int limit) {
- if (other != null) {
- other.getUnitGenerator().pullData(frameCount, start, limit);
- }
- }
-
- public boolean isAvailable() {
- if (other != null) {
- return other.isAvailable();
- } else {
- return (spectrum != null);
- }
- }
-
-}
diff --git a/src/com/jsyn/ports/UnitSpectralOutputPort.java b/src/com/jsyn/ports/UnitSpectralOutputPort.java
deleted file mode 100644
index 51633ce..0000000
--- a/src/com/jsyn/ports/UnitSpectralOutputPort.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright 2009 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.ports;
-
-import com.jsyn.data.Spectrum;
-
-public class UnitSpectralOutputPort extends UnitPort implements ConnectableOutput {
- private Spectrum spectrum;
- private boolean available;
-
- public UnitSpectralOutputPort() {
- this("Output");
- }
-
- public UnitSpectralOutputPort(int size) {
- this("Output", size);
- }
-
- public UnitSpectralOutputPort(String name) {
- super(name);
- spectrum = new Spectrum();
- }
-
- public UnitSpectralOutputPort(String name, int size) {
- super(name);
- spectrum = new Spectrum(size);
- }
-
- public void setSize(int size) {
- spectrum.setSize(size);
- }
-
- public Spectrum getSpectrum() {
- return spectrum;
- }
-
- public void advance() {
- available = true;
- }
-
- @Override
- public void connect(ConnectableInput other) {
- other.connect(this);
- }
-
- @Override
- public void disconnect(ConnectableInput other) {
- other.disconnect(this);
- }
-
- public boolean isAvailable() {
- return available;
- }
-
-}
diff --git a/src/com/jsyn/ports/UnitVariablePort.java b/src/com/jsyn/ports/UnitVariablePort.java
deleted file mode 100644
index 60b64fd..0000000
--- a/src/com/jsyn/ports/UnitVariablePort.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright 2009 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.ports;
-
-import com.softsynth.shared.time.ScheduledCommand;
-import com.softsynth.shared.time.TimeStamp;
-
-public class UnitVariablePort extends UnitPort implements SettablePort {
- private double value;
-
- public UnitVariablePort(String name, double defaultValue) {
- super(name);
- value = defaultValue;
- }
-
- public UnitVariablePort(String name) {
- super(name);
- }
-
- public void setValue(double value) {
- this.value = value;
- }
-
- public void set(double value) {
- this.value = value;
- }
-
- public double get() {
- return value;
- }
-
- public double getValue() {
- return value;
- }
-
- @Override
- public double getValue(int partNum) {
- return value;
- }
-
- @Override
- public void set(int partNum, final double value, TimeStamp timeStamp) {
- scheduleCommand(timeStamp, new ScheduledCommand() {
- @Override
- public void run() {
- set(value);
- }
- });
- }
-}
diff --git a/src/com/jsyn/ports/package.html b/src/com/jsyn/ports/package.html
deleted file mode 100644
index 3547618..0000000
--- a/src/com/jsyn/ports/package.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<title>JSyn Ports</title>
-</head>
-<body>
-<p>Ports are used to pass audio data in and out of UnitGenerators.
-They can also be used to connect UnitGenerators together so that signals can flow between them.
-The UnitDataQueuePort contains a FIFO that will accept envelope and sample data.
-</p>
-</body>
-</html> \ No newline at end of file
diff --git a/src/com/jsyn/scope/AudioScope.java b/src/com/jsyn/scope/AudioScope.java
deleted file mode 100644
index 7b2a98c..0000000
--- a/src/com/jsyn/scope/AudioScope.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright 2010 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.scope;
-
-import com.jsyn.Synthesizer;
-import com.jsyn.ports.UnitOutputPort;
-import com.jsyn.scope.swing.AudioScopeView;
-
-// TODO Auto and Manual triggers.
-// TODO Auto scaling of vertical.
-// TODO Fixed size Y scale knobs.
-// TODO Pan back and forth around trigger.
-// TODO Continuous capture
-/**
- * Digital oscilloscope for JSyn.
- *
- * @author Phil Burk (C) 2010 Mobileer Inc
- */
-public class AudioScope {
- public enum TriggerMode {
- AUTO, NORMAL // , MANUAL
- }
-
- public enum ViewMode {
- WAVEFORM, SPECTRUM
- }
-
- private AudioScopeView audioScopeView = null;
- private AudioScopeModel audioScopeModel;
-
- public AudioScope(Synthesizer synth) {
- audioScopeModel = new AudioScopeModel(synth);
- }
-
- public AudioScopeProbe addProbe(UnitOutputPort output) {
- return addProbe(output, 0);
- }
-
- public AudioScopeProbe addProbe(UnitOutputPort output, int partIndex) {
- return audioScopeModel.addProbe(output, partIndex);
- }
-
- public void start() {
- audioScopeModel.start();
- }
-
- public void stop() {
- audioScopeModel.stop();
- }
-
- public AudioScopeModel getModel() {
- return audioScopeModel;
- }
-
- public AudioScopeView getView() {
- if (audioScopeView == null) {
- audioScopeView = new AudioScopeView();
- audioScopeView.setModel(audioScopeModel);
- }
- return audioScopeView;
- }
-
- public void setTriggerMode(TriggerMode triggerMode) {
- audioScopeModel.setTriggerMode(triggerMode);
- }
-
- public void setTriggerSource(AudioScopeProbe probe) {
- audioScopeModel.setTriggerSource(probe);
- }
-
- public void setTriggerLevel(double level) {
- getModel().getTriggerModel().getLevelModel().setDoubleValue(level);
- }
-
- public double getTriggerLevel() {
- return getModel().getTriggerModel().getLevelModel().getDoubleValue();
- }
-
- /**
- * Not yet implemented.
- * @param viewMode
- */
- public void setViewMode(ViewMode viewMode) {
- // TODO Auto-generated method stub
- }
-
-}
diff --git a/src/com/jsyn/scope/AudioScopeModel.java b/src/com/jsyn/scope/AudioScopeModel.java
deleted file mode 100644
index 85c4413..0000000
--- a/src/com/jsyn/scope/AudioScopeModel.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright 2009 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.scope;
-
-import java.util.ArrayList;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
-
-import com.jsyn.Synthesizer;
-import com.jsyn.ports.UnitOutputPort;
-import com.jsyn.scope.AudioScope.TriggerMode;
-
-public class AudioScopeModel implements Runnable {
- private static final int PRE_TRIGGER_SIZE = 32;
- private Synthesizer synthesisEngine;
- private ArrayList<AudioScopeProbe> probes = new ArrayList<AudioScopeProbe>();
- private CopyOnWriteArrayList<ChangeListener> changeListeners = new CopyOnWriteArrayList<ChangeListener>();
- private MultiChannelScopeProbeUnit probeUnit;
- private double timeToArm;
- private double period = 0.2;
- private TriggerModel triggerModel;
-
- public AudioScopeModel(Synthesizer synth) {
- this.synthesisEngine = synth;
- triggerModel = new TriggerModel();
- }
-
- public AudioScopeProbe addProbe(UnitOutputPort output, int partIndex) {
- AudioScopeProbe probe = new AudioScopeProbe(this, output, partIndex);
- DefaultWaveTraceModel waveTraceModel = new DefaultWaveTraceModel(this, probes.size());
- probe.setWaveTraceModel(waveTraceModel);
- probes.add(probe);
- if (triggerModel.getSource() == null) {
- triggerModel.setSource(probe);
- }
- return probe;
- }
-
- public void start() {
- stop();
- probeUnit = new MultiChannelScopeProbeUnit(probes.size(), triggerModel);
- synthesisEngine.add(probeUnit);
- for (int i = 0; i < probes.size(); i++) {
- AudioScopeProbe probe = probes.get(i);
- probe.getSource().connect(probe.getPartIndex(), probeUnit.input, i);
- }
- // Connect trigger signal to input of probe.
- triggerModel.getSource().getSource()
- .connect(triggerModel.getSource().getPartIndex(), probeUnit.trigger, 0);
- probeUnit.start();
-
- // Get synthesizer time in seconds.
- timeToArm = synthesisEngine.getCurrentTime();
- probeUnit.arm(timeToArm, this);
- }
-
- public void stop() {
- if (probeUnit != null) {
- for (int i = 0; i < probes.size(); i++) {
- probeUnit.input.disconnectAll(i);
- }
- probeUnit.trigger.disconnectAll();
- probeUnit.stop();
- synthesisEngine.remove(probeUnit);
- probeUnit = null;
- }
- }
-
- public AudioScopeProbe[] getProbes() {
- return probes.toArray(new AudioScopeProbe[0]);
- }
-
- public Synthesizer getSynthesizer() {
- return synthesisEngine;
- }
-
- @Override
- public void run() {
- fireChangeListeners();
- timeToArm = synthesisEngine.getCurrentTime();
- timeToArm += period;
- probeUnit.arm(timeToArm, this);
- }
-
- private void fireChangeListeners() {
- ChangeEvent changeEvent = new ChangeEvent(this);
- for (ChangeListener listener : changeListeners) {
- listener.stateChanged(changeEvent);
- }
- // debug();
- }
-
- public void addChangeListener(ChangeListener changeListener) {
- changeListeners.add(changeListener);
- }
-
- public void removeChangeListener(ChangeListener changeListener) {
- changeListeners.remove(changeListener);
- }
-
- public void setTriggerMode(TriggerMode triggerMode) {
- triggerModel.getModeModel().setSelectedItem(triggerMode);
- }
-
- public void setTriggerSource(AudioScopeProbe probe) {
- triggerModel.setSource(probe);
- }
-
- public double getSample(int bufferIndex, int i) {
- return probeUnit.getSample(bufferIndex, i);
- }
-
- public int getFramesPerBuffer() {
- return probeUnit.getFramesPerBuffer();
- }
-
- public int getFramesCaptured() {
- return probeUnit.getFramesCaptured();
- }
-
- public int getVisibleSize() {
- int size = 0;
- if (probeUnit != null) {
- size = probeUnit.getPostTriggerSize() + PRE_TRIGGER_SIZE;
- if (size > getFramesCaptured()) {
- size = getFramesCaptured();
- }
- }
- return size;
- }
-
- public int getStartIndex() {
- // TODO Add pan support here.
- return getFramesCaptured() - getVisibleSize();
- }
-
- public TriggerModel getTriggerModel() {
- return triggerModel;
- }
-
-}
diff --git a/src/com/jsyn/scope/AudioScopeProbe.java b/src/com/jsyn/scope/AudioScopeProbe.java
deleted file mode 100644
index f1aad65..0000000
--- a/src/com/jsyn/scope/AudioScopeProbe.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright 2010 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.scope;
-
-import java.awt.Color;
-
-import javax.swing.JToggleButton.ToggleButtonModel;
-
-import com.jsyn.ports.UnitOutputPort;
-import com.jsyn.swing.ExponentialRangeModel;
-
-/**
- * Collect data from the source and make it available to the scope.
- *
- * @author Phil Burk (C) 2010 Mobileer Inc
- */
-public class AudioScopeProbe {
- // private UnitOutputPort output;
- private WaveTraceModel waveTraceModel;
- private AudioScopeModel audioScopeModel;
- private UnitOutputPort source;
- private int partIndex;
- private Color color;
- private ExponentialRangeModel verticalScaleModel;
- private ToggleButtonModel autoScaleButtonModel;
- private double MIN_RANGE = 0.01;
- private double MAX_RANGE = 100.0;
-
- public AudioScopeProbe(AudioScopeModel audioScopeModel, UnitOutputPort source, int partIndex) {
- this.audioScopeModel = audioScopeModel;
- this.source = source;
- this.partIndex = partIndex;
-
- verticalScaleModel = new ExponentialRangeModel("VScale", 1000, MIN_RANGE, MAX_RANGE,
- MIN_RANGE);
- autoScaleButtonModel = new ToggleButtonModel();
- autoScaleButtonModel.setSelected(true);
- }
-
- public WaveTraceModel getWaveTraceModel() {
- return waveTraceModel;
- }
-
- public void setWaveTraceModel(WaveTraceModel waveTraceModel) {
- this.waveTraceModel = waveTraceModel;
- }
-
- public UnitOutputPort getSource() {
- return source;
- }
-
- public int getPartIndex() {
- return partIndex;
- }
-
- public Color getColor() {
- return color;
- }
-
- public void setColor(Color color) {
- this.color = color;
- }
-
- public void setAutoScaleEnabled(boolean enabled) {
- autoScaleButtonModel.setSelected(enabled);
- }
-
- public void setVerticalScale(double max) {
- verticalScaleModel.setDoubleValue(max);
- }
-
- public ExponentialRangeModel getVerticalScaleModel() {
- return verticalScaleModel;
- }
-
- public ToggleButtonModel getAutoScaleButtonModel() {
- return autoScaleButtonModel;
- }
-
-}
diff --git a/src/com/jsyn/scope/DefaultWaveTraceModel.java b/src/com/jsyn/scope/DefaultWaveTraceModel.java
deleted file mode 100644
index a123c0b..0000000
--- a/src/com/jsyn/scope/DefaultWaveTraceModel.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2009 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.scope;
-
-public class DefaultWaveTraceModel implements WaveTraceModel {
- private AudioScopeModel audioScopeModel;
- private int bufferIndex;
-
- public DefaultWaveTraceModel(AudioScopeModel audioScopeModel, int bufferIndex) {
- this.audioScopeModel = audioScopeModel;
- this.bufferIndex = bufferIndex;
- }
-
- @Override
- public double getSample(int i) {
- return audioScopeModel.getSample(bufferIndex, i);
- }
-
- @Override
- public int getSize() {
- return audioScopeModel.getFramesCaptured();
- }
-
- @Override
- public int getStartIndex() {
- return audioScopeModel.getStartIndex();
- }
-
- @Override
- public int getVisibleSize() {
- return audioScopeModel.getVisibleSize();
- }
-
-}
diff --git a/src/com/jsyn/scope/MultiChannelScopeProbeUnit.java b/src/com/jsyn/scope/MultiChannelScopeProbeUnit.java
deleted file mode 100644
index 5be19f0..0000000
--- a/src/com/jsyn/scope/MultiChannelScopeProbeUnit.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright 2009 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.scope;
-
-import com.jsyn.ports.UnitInputPort;
-import com.jsyn.scope.AudioScope.TriggerMode;
-import com.jsyn.unitgen.UnitGenerator;
-import com.softsynth.shared.time.ScheduledCommand;
-
-/**
- * Multi-channel scope probe with an independent trigger input.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public class MultiChannelScopeProbeUnit extends UnitGenerator {
- // Signal that is captured.
- public UnitInputPort input;
- // Signal that triggers the probe.
- public UnitInputPort trigger;
-
- // I am using ints instead of an enum for performance reasons.
- private static final int STATE_IDLE = 0;
- private static final int STATE_ARMED = 1;
- private static final int STATE_READY = 2;
- private static final int STATE_TRIGGERED = 3;
- private int state = STATE_IDLE;
-
- private int numChannels;
- private double[][] inputValues;
- private static final int FRAMES_PER_BUFFER = 4096; // must be power of two
- private static final int FRAMES_PER_BUFFER_MASK = FRAMES_PER_BUFFER - 1;
- private Runnable callback;
-
- private TriggerModel triggerModel;
- private int autoCountdown;
- private int countdown;
- private int postTriggerSize = 512;
- SignalBuffer captureBuffer;
- SignalBuffer displayBuffer;
-
- // Use double buffers. One for capture, one for display.
- class SignalBuffer {
- float[][] buffers;
- private int writeCursor;
- private int triggerIndex;
- private int framesCaptured;
-
- SignalBuffer(int numChannels) {
- buffers = new float[numChannels][];
- for (int j = 0; j < numChannels; j++) {
- buffers[j] = new float[FRAMES_PER_BUFFER];
- }
- }
-
- void reset() {
- writeCursor = 0;
- triggerIndex = 0;
- framesCaptured = 0;
- }
-
- public void saveChannelValue(int j, float value) {
- buffers[j][writeCursor] = value;
- }
-
- public void markTrigger() {
- triggerIndex = writeCursor;
- }
-
- public void bumpCursor() {
- writeCursor = (writeCursor + 1) & FRAMES_PER_BUFFER_MASK;
- if (writeCursor >= FRAMES_PER_BUFFER) {
- writeCursor = 0;
- }
- if (framesCaptured < FRAMES_PER_BUFFER) {
- framesCaptured += 1;
- }
- }
-
- private int convertInternalToExternalIndex(int internalIndex) {
- if (framesCaptured < FRAMES_PER_BUFFER) {
- return internalIndex;
- } else {
- return (internalIndex - writeCursor) & (FRAMES_PER_BUFFER_MASK);
- }
- }
-
- private int convertExternalToInternalIndex(int externalIndex) {
- if (framesCaptured < FRAMES_PER_BUFFER) {
- return externalIndex;
- } else {
- return (externalIndex + writeCursor) & (FRAMES_PER_BUFFER_MASK);
- }
- }
-
- public int getTriggerIndex() {
- return convertInternalToExternalIndex(triggerIndex);
- }
-
- public int getFramesCaptured() {
- return framesCaptured;
- }
-
- public float getSample(int bufferIndex, int sampleIndex) {
- int index = convertExternalToInternalIndex(sampleIndex);
- return buffers[bufferIndex][index];
- }
- }
-
- public MultiChannelScopeProbeUnit(int numChannels, TriggerModel triggerModel) {
- this.numChannels = numChannels;
- captureBuffer = new SignalBuffer(numChannels);
- displayBuffer = new SignalBuffer(numChannels);
- this.triggerModel = triggerModel;
- addPort(trigger = new UnitInputPort(numChannels, "Trigger"));
- addPort(input = new UnitInputPort(numChannels, "Input"));
- inputValues = new double[numChannels][];
- }
-
- private synchronized void switchBuffers() {
- SignalBuffer temp = captureBuffer;
- captureBuffer = displayBuffer;
- displayBuffer = temp;
- }
-
- private void internalArm(Runnable callback) {
- this.callback = callback;
- state = STATE_ARMED;
- captureBuffer.reset();
- }
-
- class ScheduledArm implements ScheduledCommand {
- private Runnable callback;
-
- ScheduledArm(Runnable callback) {
- this.callback = callback;
- }
-
- @Override
- public void run() {
- internalArm(this.callback);
- }
- }
-
- /** Arm the probe at a future time. */
- public void arm(double time, Runnable callback) {
- ScheduledArm command = new ScheduledArm(callback);
- getSynthesisEngine().scheduleCommand(time, command);
- }
-
- @Override
- public void generate(int start, int limit) {
- if (state != STATE_IDLE) {
- TriggerMode triggerMode = triggerModel.getMode();
- double triggerLevel = triggerModel.getTriggerLevel();
- double[] triggerValues = trigger.getValues();
-
- for (int j = 0; j < numChannels; j++) {
- inputValues[j] = input.getValues(j);
- }
-
- for (int i = start; i < limit; i++) {
- // Capture one sample from each channel.
- for (int j = 0; j < numChannels; j++) {
- captureBuffer.saveChannelValue(j, (float) inputValues[j][i]);
- }
- captureBuffer.bumpCursor();
-
- switch (state) {
- case STATE_ARMED:
- if (triggerValues[i] <= triggerLevel) {
- state = STATE_READY;
- autoCountdown = 44100;
- }
- break;
-
- case STATE_READY: {
- boolean triggered = false;
- if (triggerValues[i] > triggerLevel) {
- triggered = true;
- } else if (triggerMode.equals(TriggerMode.AUTO)) {
- if (--autoCountdown == 0) {
- triggered = true;
- }
- }
- if (triggered) {
- captureBuffer.markTrigger();
- state = STATE_TRIGGERED;
- countdown = postTriggerSize;
- }
- }
- break;
-
- case STATE_TRIGGERED:
- countdown -= 1;
- if (countdown <= 0) {
- state = STATE_IDLE;
- switchBuffers();
- fireCallback();
- }
- break;
- }
- }
- }
- }
-
- private void fireCallback() {
- if (callback != null) {
- callback.run();
- }
- }
-
- public float getSample(int bufferIndex, int sampleIndex) {
- return displayBuffer.getSample(bufferIndex, sampleIndex);
- }
-
- public int getTriggerIndex() {
- return displayBuffer.getTriggerIndex();
- }
-
- public int getFramesCaptured() {
- return displayBuffer.getFramesCaptured();
- }
-
- public int getFramesPerBuffer() {
- return FRAMES_PER_BUFFER;
- }
-
- public int getPostTriggerSize() {
- return postTriggerSize;
- }
-
-}
diff --git a/src/com/jsyn/scope/TriggerModel.java b/src/com/jsyn/scope/TriggerModel.java
deleted file mode 100644
index 0367d71..0000000
--- a/src/com/jsyn/scope/TriggerModel.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright 2009 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.scope;
-
-import javax.swing.DefaultComboBoxModel;
-
-import com.jsyn.scope.AudioScope.TriggerMode;
-import com.jsyn.swing.ExponentialRangeModel;
-
-public class TriggerModel {
- private ExponentialRangeModel levelModel;
- private DefaultComboBoxModel<AudioScope.TriggerMode> modeModel;
- private AudioScopeProbe source;
-
- public TriggerModel() {
- modeModel = new DefaultComboBoxModel<AudioScope.TriggerMode>();
- modeModel.addElement(TriggerMode.AUTO);
- modeModel.addElement(TriggerMode.NORMAL);
- levelModel = new ExponentialRangeModel("TriggerLevel", 1000, 0.01, 2.0, 0.04);
- }
-
- public AudioScopeProbe getSource() {
- return source;
- }
-
- public void setSource(AudioScopeProbe source) {
- this.source = source;
- }
-
- public ExponentialRangeModel getLevelModel() {
- return levelModel;
- }
-
- public void setLevelModel(ExponentialRangeModel levelModel) {
- this.levelModel = levelModel;
- }
-
- public DefaultComboBoxModel<TriggerMode> getModeModel() {
- return modeModel;
- }
-
- public void setModeModel(DefaultComboBoxModel<TriggerMode> modeModel) {
- this.modeModel = modeModel;
- }
-
- public double getTriggerLevel() {
- return levelModel.getDoubleValue();
- }
-
- public TriggerMode getMode() {
- return (TriggerMode) modeModel.getSelectedItem();
- }
-}
diff --git a/src/com/jsyn/scope/WaveTraceModel.java b/src/com/jsyn/scope/WaveTraceModel.java
deleted file mode 100644
index e9d8bf9..0000000
--- a/src/com/jsyn/scope/WaveTraceModel.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright 2009 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.scope;
-
-public interface WaveTraceModel {
- int getSize();
-
- int getVisibleSize();
-
- int getStartIndex();
-
- double getSample(int i);
-}
diff --git a/src/com/jsyn/scope/swing/AudioScopeProbeView.java b/src/com/jsyn/scope/swing/AudioScopeProbeView.java
deleted file mode 100644
index 59526e1..0000000
--- a/src/com/jsyn/scope/swing/AudioScopeProbeView.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright 2010 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.scope.swing;
-
-import com.jsyn.scope.AudioScopeProbe;
-
-/**
- * Wave display associated with a probe.
- *
- * @author Phil Burk (C) 2010 Mobileer Inc
- */
-public class AudioScopeProbeView {
- private AudioScopeProbe probeModel;
- private WaveTraceView waveTrace;
-
- public AudioScopeProbeView(AudioScopeProbe probeModel) {
- this.probeModel = probeModel;
- waveTrace = new WaveTraceView(probeModel.getAutoScaleButtonModel(),
- probeModel.getVerticalScaleModel());
- waveTrace.setModel(probeModel.getWaveTraceModel());
- }
-
- public WaveTraceView getWaveTraceView() {
- return waveTrace;
- }
-
- public AudioScopeProbe getModel() {
- return probeModel;
- }
-
-}
diff --git a/src/com/jsyn/scope/swing/AudioScopeView.java b/src/com/jsyn/scope/swing/AudioScopeView.java
deleted file mode 100644
index ec1afa3..0000000
--- a/src/com/jsyn/scope/swing/AudioScopeView.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright 2009 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.scope.swing;
-
-import java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.Dimension;
-import java.util.ArrayList;
-
-import javax.swing.JPanel;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
-
-import com.jsyn.scope.AudioScopeModel;
-import com.jsyn.scope.AudioScopeProbe;
-
-public class AudioScopeView extends JPanel {
- private static final long serialVersionUID = -7507986850757860853L;
- private AudioScopeModel audioScopeModel;
- private ArrayList<AudioScopeProbeView> probeViews = new ArrayList<AudioScopeProbeView>();
- private MultipleWaveDisplay multipleWaveDisplay;
- private boolean showControls = false;
- private ScopeControlPanel controlPanel = null;
-
- public AudioScopeView() {
- setBackground(Color.GREEN);
- }
-
- public void setModel(AudioScopeModel audioScopeModel) {
- this.audioScopeModel = audioScopeModel;
- // Create a view for each probe.
- probeViews.clear();
- for (AudioScopeProbe probeModel : audioScopeModel.getProbes()) {
- AudioScopeProbeView audioScopeProbeView = new AudioScopeProbeView(probeModel);
- probeViews.add(audioScopeProbeView);
- }
- setupGUI();
-
- // Listener for signal change events.
- audioScopeModel.addChangeListener(new ChangeListener() {
- @Override
- public void stateChanged(ChangeEvent e) {
- multipleWaveDisplay.repaint();
- }
- });
-
- }
-
- private void setupGUI() {
- removeAll();
- setLayout(new BorderLayout());
- multipleWaveDisplay = new MultipleWaveDisplay();
-
- for (AudioScopeProbeView probeView : probeViews) {
- multipleWaveDisplay.addWaveTrace(probeView.getWaveTraceView());
- probeView.getModel().setColor(probeView.getWaveTraceView().getColor());
- }
-
- add(multipleWaveDisplay, BorderLayout.CENTER);
-
- setMinimumSize(new Dimension(400, 200));
- setPreferredSize(new Dimension(600, 250));
- setMaximumSize(new Dimension(1200, 300));
- }
-
- /** @deprecated Use setControlsVisible() instead. */
- @Deprecated
- public void setShowControls(boolean show) {
- setControlsVisible(show);
- }
-
- public void setControlsVisible(boolean show) {
- if (this.showControls) {
- if (!show && (controlPanel != null)) {
- remove(controlPanel);
- }
- } else {
- if (show) {
- if (controlPanel == null) {
- controlPanel = new ScopeControlPanel(this);
- }
- add(controlPanel, BorderLayout.EAST);
- validate();
- }
- }
-
- this.showControls = show;
- }
-
- public AudioScopeModel getModel() {
- return audioScopeModel;
- }
-
- public AudioScopeProbeView[] getProbeViews() {
- return probeViews.toArray(new AudioScopeProbeView[0]);
- }
-
-}
diff --git a/src/com/jsyn/scope/swing/MultipleWaveDisplay.java b/src/com/jsyn/scope/swing/MultipleWaveDisplay.java
deleted file mode 100644
index 0259850..0000000
--- a/src/com/jsyn/scope/swing/MultipleWaveDisplay.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright 2011 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.scope.swing;
-
-import java.awt.Color;
-import java.awt.Graphics;
-import java.util.ArrayList;
-
-import javax.swing.JPanel;
-
-/**
- * Display multiple waveforms together in different colors.
- *
- * @author Phil Burk (C) 2011 Mobileer Inc
- */
-public class MultipleWaveDisplay extends JPanel {
- private static final long serialVersionUID = -5157397030540800373L;
-
- private ArrayList<WaveTraceView> waveTraceViews = new ArrayList<WaveTraceView>();
- private Color[] defaultColors = {
- Color.BLUE, Color.RED, Color.BLACK, Color.MAGENTA, Color.GREEN, Color.ORANGE
- };
-
- public MultipleWaveDisplay() {
- setBackground(Color.WHITE);
- }
-
- public void addWaveTrace(WaveTraceView waveTraceView) {
- if (waveTraceView.getColor() == null) {
- waveTraceView.setColor(defaultColors[waveTraceViews.size() % defaultColors.length]);
- }
- waveTraceViews.add(waveTraceView);
- }
-
- @Override
- public void paintComponent(Graphics g) {
- super.paintComponent(g);
- int width = getWidth();
- int height = getHeight();
- for (WaveTraceView waveTraceView : waveTraceViews.toArray(new WaveTraceView[0])) {
- waveTraceView.drawWave(g, width, height);
- }
- }
-}
diff --git a/src/com/jsyn/scope/swing/ScopeControlPanel.java b/src/com/jsyn/scope/swing/ScopeControlPanel.java
deleted file mode 100644
index 7f3a026..0000000
--- a/src/com/jsyn/scope/swing/ScopeControlPanel.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2009 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.scope.swing;
-
-import java.awt.GridLayout;
-
-import javax.swing.JPanel;
-
-import com.jsyn.scope.AudioScopeModel;
-
-public class ScopeControlPanel extends JPanel {
- private static final long serialVersionUID = 7738305116057614812L;
- private AudioScopeModel audioScopeModel;
- private ScopeTriggerPanel triggerPanel;
- private JPanel probeRows;
-
- public ScopeControlPanel(AudioScopeView audioScopeView) {
- setLayout(new GridLayout(0, 1));
- this.audioScopeModel = audioScopeView.getModel();
- triggerPanel = new ScopeTriggerPanel(audioScopeModel);
- add(triggerPanel);
-
- probeRows = new JPanel();
- probeRows.setLayout(new GridLayout(1, 0));
- add(probeRows);
- for (AudioScopeProbeView probeView : audioScopeView.getProbeViews()) {
- ScopeProbePanel probePanel = new ScopeProbePanel(probeView);
- probeRows.add(probePanel);
- }
- }
-
-}
diff --git a/src/com/jsyn/scope/swing/ScopeProbePanel.java b/src/com/jsyn/scope/swing/ScopeProbePanel.java
deleted file mode 100644
index 9cb82af..0000000
--- a/src/com/jsyn/scope/swing/ScopeProbePanel.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright 2009 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.scope.swing;
-
-import java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-
-import javax.swing.BorderFactory;
-import javax.swing.JCheckBox;
-import javax.swing.JPanel;
-import javax.swing.JToggleButton.ToggleButtonModel;
-
-import com.jsyn.scope.AudioScopeProbe;
-import com.jsyn.swing.RotaryTextController;
-
-public class ScopeProbePanel extends JPanel {
- private static final long serialVersionUID = 4511589171299298548L;
- private AudioScopeProbeView audioScopeProbeView;
- private AudioScopeProbe audioScopeProbe;
- private RotaryTextController verticalScaleKnob;
- private JCheckBox autoBox;
- private ToggleButtonModel autoScaleModel;
-
- public ScopeProbePanel(AudioScopeProbeView probeView) {
- this.audioScopeProbeView = probeView;
- setLayout(new BorderLayout());
-
- setBorder(BorderFactory.createLineBorder(Color.GRAY, 3));
-
- // Add a colored box to match the waveform color.
- JPanel colorPanel = new JPanel();
- colorPanel.setMinimumSize(new Dimension(40, 40));
- audioScopeProbe = probeView.getModel();
- colorPanel.setBackground(audioScopeProbe.getColor());
- add(colorPanel, BorderLayout.NORTH);
-
- // Knob for tweaking vertical range.
- verticalScaleKnob = new RotaryTextController(audioScopeProbeView.getWaveTraceView()
- .getVerticalRangeModel(), 5);
- add(verticalScaleKnob, BorderLayout.CENTER);
- verticalScaleKnob.setTitle("YScale");
-
- // Auto ranging checkbox.
- autoBox = new JCheckBox("Auto");
- autoScaleModel = audioScopeProbeView.getWaveTraceView().getAutoButtonModel();
- autoScaleModel.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- ToggleButtonModel model = (ToggleButtonModel) e.getSource();
- boolean enabled = !model.isSelected();
- System.out.println("Knob enabled = " + enabled);
- verticalScaleKnob.setEnabled(!model.isSelected());
- }
- });
- autoBox.setModel(autoScaleModel);
- add(autoBox, BorderLayout.SOUTH);
-
- verticalScaleKnob.setEnabled(!autoScaleModel.isSelected());
-
- setMinimumSize(new Dimension(80, 100));
- setPreferredSize(new Dimension(80, 150));
- setMaximumSize(new Dimension(120, 200));
- }
-
-}
diff --git a/src/com/jsyn/scope/swing/ScopeTriggerPanel.java b/src/com/jsyn/scope/swing/ScopeTriggerPanel.java
deleted file mode 100644
index 9c22aa1..0000000
--- a/src/com/jsyn/scope/swing/ScopeTriggerPanel.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 2009 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.scope.swing;
-
-import java.awt.BorderLayout;
-
-import javax.swing.DefaultComboBoxModel;
-import javax.swing.JComboBox;
-import javax.swing.JPanel;
-
-import com.jsyn.scope.AudioScopeModel;
-import com.jsyn.scope.TriggerModel;
-import com.jsyn.scope.AudioScope.TriggerMode;
-import com.jsyn.swing.RotaryTextController;
-
-public class ScopeTriggerPanel extends JPanel {
- private static final long serialVersionUID = 4511589171299298548L;
- private JComboBox<DefaultComboBoxModel<TriggerMode>> triggerModeComboBox;
- private RotaryTextController triggerLevelKnob;
-
- public ScopeTriggerPanel(AudioScopeModel audioScopeModel) {
- setLayout(new BorderLayout());
- TriggerModel triggerModel = audioScopeModel.getTriggerModel();
- triggerModeComboBox = new JComboBox(triggerModel.getModeModel());
- add(triggerModeComboBox, BorderLayout.NORTH);
-
- triggerLevelKnob = new RotaryTextController(triggerModel.getLevelModel(), 5);
-
- add(triggerLevelKnob, BorderLayout.CENTER);
- triggerLevelKnob.setTitle("Trigger Level");
- }
-
-}
diff --git a/src/com/jsyn/scope/swing/WaveTraceView.java b/src/com/jsyn/scope/swing/WaveTraceView.java
deleted file mode 100644
index 849a6f4..0000000
--- a/src/com/jsyn/scope/swing/WaveTraceView.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright 2009 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.scope.swing;
-
-import java.awt.Color;
-import java.awt.Graphics;
-
-import javax.swing.JToggleButton.ToggleButtonModel;
-
-import com.jsyn.scope.WaveTraceModel;
-import com.jsyn.swing.ExponentialRangeModel;
-
-public class WaveTraceView {
- private static final double AUTO_DECAY = 0.95;
- private WaveTraceModel waveTraceModel;
- private Color color;
- private ExponentialRangeModel verticalScaleModel;
- private ToggleButtonModel autoScaleButtonModel;
-
- private double xScaler;
- private double yScalar;
- private int centerY;
-
- public WaveTraceView(ToggleButtonModel autoButtonModel, ExponentialRangeModel verticalRangeModel) {
- this.verticalScaleModel = verticalRangeModel;
- this.autoScaleButtonModel = autoButtonModel;
- }
-
- public Color getColor() {
- return color;
- }
-
- public void setColor(Color color) {
- this.color = color;
- }
-
- public ExponentialRangeModel getVerticalRangeModel() {
- return verticalScaleModel;
- }
-
- public ToggleButtonModel getAutoButtonModel() {
- return autoScaleButtonModel;
- }
-
- public void setModel(WaveTraceModel waveTraceModel) {
- this.waveTraceModel = waveTraceModel;
- }
-
- public int convertRealToY(double r) {
- return centerY - (int) (yScalar * r);
- }
-
- public void drawWave(Graphics g, int width, int height) {
- double sampleMax = 0.0;
- double sampleMin = 0.0;
- g.setColor(color);
- int numSamples = waveTraceModel.getVisibleSize();
- if (numSamples > 0) {
- xScaler = (double) width / numSamples;
- // Scale by 0.5 because it is bipolar.
- yScalar = 0.5 * height / verticalScaleModel.getDoubleValue();
- centerY = height / 2;
-
- // Calculate position of first point.
- int x1 = 0;
- int offset = waveTraceModel.getStartIndex();
- double value = waveTraceModel.getSample(offset);
- int y1 = convertRealToY(value);
-
- // Draw lines to remaining points.
- for (int i = 1; i < numSamples; i++) {
- int x2 = (int) (i * xScaler);
- value = waveTraceModel.getSample(offset + i);
- int y2 = convertRealToY(value);
- g.drawLine(x1, y1, x2, y2);
- x1 = x2;
- y1 = y2;
- // measure min and max for auto
- if (value > sampleMax) {
- sampleMax = value;
- } else if (value < sampleMin) {
- sampleMin = value;
- }
- }
-
- autoScaleRange(sampleMax);
- }
- }
-
- // Autoscale the vertical range.
- private void autoScaleRange(double sampleMax) {
- if (autoScaleButtonModel.isSelected()) {
- double scaledMax = sampleMax * 1.1;
- double current = verticalScaleModel.getDoubleValue();
- if (scaledMax > current) {
- verticalScaleModel.setDoubleValue(scaledMax);
- } else {
- double decayed = current * AUTO_DECAY;
- if (decayed > verticalScaleModel.getMinimum()) {
- if (scaledMax < decayed) {
- verticalScaleModel.setDoubleValue(decayed);
- }
- }
- }
- }
- }
-
-}
diff --git a/src/com/jsyn/swing/ASCIIMusicKeyboard.java b/src/com/jsyn/swing/ASCIIMusicKeyboard.java
deleted file mode 100644
index f1379d8..0000000
--- a/src/com/jsyn/swing/ASCIIMusicKeyboard.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright 2012 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.swing;
-
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.KeyEvent;
-import java.awt.event.KeyListener;
-import java.util.HashSet;
-
-import javax.swing.JButton;
-import javax.swing.JCheckBox;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-
-/**
- * Support for playing musical scales on the ASCII keyboard of a computer. Has a Sustain checkbox
- * that simulates a sustain pedal. Auto-repeat keys are detected and suppressed.
- *
- * @author Phil Burk (C) 2012 Mobileer Inc
- */
-@SuppressWarnings("serial")
-public abstract class ASCIIMusicKeyboard extends JPanel {
- private final JCheckBox sustainBox;
- private final JButton focusButton;
- public static final String PENTATONIC_KEYS = "zxcvbasdfgqwert12345";
- public static final String SEPTATONIC_KEYS = "zxcvbnmasdfghjqwertyu1234567890";
- private String keyboardLayout = SEPTATONIC_KEYS; /* default music keyboard layout */
- private int basePitch = 48;
- private final KeyListener keyListener;
- private final JLabel countLabel;
- private int onCount;
- private int offCount;
- private int pressedCount;
- private int releasedCount;
- private final HashSet<Integer> pressedKeys = new HashSet<Integer>();
- private final HashSet<Integer> onKeys = new HashSet<Integer>();
-
- public ASCIIMusicKeyboard() {
- focusButton = new JButton("Click here to play ASCII keys.");
- focusButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent arg0) {
- }
- });
- keyListener = new KeyListener() {
-
- @Override
- public void keyPressed(KeyEvent e) {
- int key = e.getKeyChar();
- int idx = keyboardLayout.indexOf(key);
- System.out.println("keyPressed " + idx);
- if (idx >= 0) {
- if (!pressedKeys.contains(idx)) {
- keyOn(convertIndexToPitch(idx));
- onCount++;
- pressedKeys.add(idx);
- onKeys.add(idx);
- }
- }
- pressedCount++;
- updateCountLabel();
- }
-
- @Override
- public void keyReleased(KeyEvent e) {
- int key = e.getKeyChar();
- int idx = keyboardLayout.indexOf(key);
- System.out.println("keyReleased " + idx);
- if (idx >= 0) {
- if (!sustainBox.isSelected()) {
- noteOffInternal(idx);
- onKeys.remove(idx);
- }
- pressedKeys.remove(idx);
- }
- releasedCount++;
- updateCountLabel();
- }
-
- @Override
- public void keyTyped(KeyEvent arg0) {
- }
- };
- focusButton.addKeyListener(keyListener);
- add(focusButton);
-
- sustainBox = new JCheckBox("sustain");
- sustainBox.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent arg0) {
- if (!sustainBox.isSelected()) {
- for (Integer noteIndex : onKeys) {
- noteOffInternal(noteIndex);
- }
- onKeys.clear();
- }
- }
- });
- add(sustainBox);
- sustainBox.addKeyListener(keyListener);
-
- countLabel = new JLabel("0");
- add(countLabel);
- }
-
- private void noteOffInternal(int idx) {
- keyOff(convertIndexToPitch(idx));
- offCount++;
- }
-
- protected void updateCountLabel() {
- countLabel.setText(onCount + "/" + offCount + ", " + pressedCount + "/" + releasedCount);
- }
-
- /**
- * Convert index to a MIDI noteNumber in a major scale. Result will be offset by the basePitch.
- */
- public int convertIndexToPitch(int keyIndex) {
- int scale[] = {
- 0, 2, 4, 5, 7, 9, 11
- };
- int octave = keyIndex / scale.length;
- int idx = keyIndex % scale.length;
- int pitch = (octave * 12) + scale[idx];
- return pitch + basePitch;
- }
-
- /**
- * This will be called when a key is released. It may also be called for sustaining notes when
- * the Sustain check box is turned off.
- *
- * @param keyIndex
- */
- public abstract void keyOff(int keyIndex);
-
- /**
- * This will be called when a key is pressed.
- *
- * @param keyIndex
- */
- public abstract void keyOn(int keyIndex);
-
- public String getKeyboardLayout() {
- return keyboardLayout;
- }
-
- /**
- * Specify the keys that will be active for music.
- * For example "qwertyui".
- * If the first character in the layout is
- * pressed then keyOn() will be called with 0. Default is SEPTATONIC_KEYS.
- *
- * @param keyboardLayout defines order of playable keys
- */
- public void setKeyboardLayout(String keyboardLayout) {
- this.keyboardLayout = keyboardLayout;
- }
-
- public int getBasePitch() {
- return basePitch;
- }
-
- /**
- * Define offset used by convertIndexToPitch().
- *
- * @param basePitch
- */
- public void setBasePitch(int basePitch) {
- this.basePitch = basePitch;
- }
-
- /**
- * @return
- */
- public KeyListener getKeyListener() {
- return keyListener;
- }
-}
diff --git a/src/com/jsyn/swing/DoubleBoundedRangeModel.java b/src/com/jsyn/swing/DoubleBoundedRangeModel.java
deleted file mode 100644
index 647e8da..0000000
--- a/src/com/jsyn/swing/DoubleBoundedRangeModel.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright 2002 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.swing;
-
-import javax.swing.DefaultBoundedRangeModel;
-
-/**
- * Double precision data model for sliders and knobs. Maps integer range info to a double value.
- *
- * @author Phil Burk, (C) 2002 SoftSynth.com, PROPRIETARY and CONFIDENTIAL
- */
-public class DoubleBoundedRangeModel extends DefaultBoundedRangeModel {
- private static final long serialVersionUID = 284361767102120148L;
- protected String name;
- private double dmin;
- private double dmax;
-
- public DoubleBoundedRangeModel(String name, int resolution, double dmin, double dmax,
- double dval) {
- this.name = name;
- this.dmin = dmin;
- this.dmax = dmax;
- setMinimum(0);
- setMaximum(resolution);
- setDoubleValue(dval);
- }
-
- public boolean equivalentTo(Object other) {
- if (!(other instanceof DoubleBoundedRangeModel))
- return false;
- DoubleBoundedRangeModel otherModel = (DoubleBoundedRangeModel) other;
- return (getValue() == otherModel.getValue());
- }
-
- /** Set name of value. This may be used in labels or when saving the value. */
- public void setName(String name) {
- this.name = name;
- }
-
- public String getName() {
- return name;
- }
-
- public double getDoubleMinimum() {
- return dmin;
- }
-
- public double getDoubleMaximum() {
- return dmax;
- }
-
- public double sliderToDouble(int sliderValue) {
- double doubleMin = getDoubleMinimum();
- return doubleMin + ((getDoubleMaximum() - doubleMin) * sliderValue / getMaximum());
- }
-
- public int doubleToSlider(double dval) {
- double doubleMin = getDoubleMinimum();
- // TODO consider using Math.floor() instead of (int) if not too slow.
- return (int) Math.round(getMaximum() * (dval - doubleMin)
- / (getDoubleMaximum() - doubleMin));
- }
-
- public double getDoubleValue() {
- return sliderToDouble(getValue());
- }
-
- public void setDoubleValue(double dval) {
- setValue(doubleToSlider(dval));
- }
-
-}
diff --git a/src/com/jsyn/swing/DoubleBoundedRangeSlider.java b/src/com/jsyn/swing/DoubleBoundedRangeSlider.java
deleted file mode 100644
index 3642221..0000000
--- a/src/com/jsyn/swing/DoubleBoundedRangeSlider.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright 2002 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.swing;
-
-import java.util.Hashtable;
-
-import javax.swing.BorderFactory;
-import javax.swing.JLabel;
-import javax.swing.JSlider;
-import javax.swing.border.TitledBorder;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
-
-import com.jsyn.util.NumericOutput;
-
-/**
- * Slider that takes a DoubleBoundedRangeModel. It displays the current value in a titled border.
- *
- * @author Phil Burk, (C) 2002 SoftSynth.com, PROPRIETARY and CONFIDENTIAL
- */
-
-public class DoubleBoundedRangeSlider extends JSlider {
- /**
- *
- */
- private static final long serialVersionUID = -440390322602838998L;
- /** Places after decimal point for display. */
- private int places;
-
- public DoubleBoundedRangeSlider(DoubleBoundedRangeModel model) {
- this(model, 5);
- }
-
- public DoubleBoundedRangeSlider(DoubleBoundedRangeModel model, int places) {
- super(model);
- this.places = places;
- setBorder(BorderFactory.createTitledBorder(generateTitleText()));
- model.addChangeListener(new ChangeListener() {
- @Override
- public void stateChanged(ChangeEvent e) {
- updateTitle();
- }
- });
- }
-
- protected void updateTitle() {
- TitledBorder border = (TitledBorder) getBorder();
- if (border != null) {
- border.setTitle(generateTitleText());
- repaint();
- }
- }
-
- String generateTitleText() {
- DoubleBoundedRangeModel model = (DoubleBoundedRangeModel) getModel();
- double val = model.getDoubleValue();
- String valText = NumericOutput.doubleToString(val, 0, places);
- return model.getName() + " = " + valText;
- }
-
- public void makeStandardLabels(int labelSpacing) {
- setMajorTickSpacing(labelSpacing / 2);
- setLabelTable(createStandardLabels(labelSpacing));
- setPaintTicks(true);
- setPaintLabels(true);
- }
-
- public double nextLabelValue(double current, double delta) {
- return current + delta;
- }
-
- public void makeLabels(double start, double delta, int places) {
- DoubleBoundedRangeModel model = (DoubleBoundedRangeModel) getModel();
- // Create the label table
- Hashtable<Integer, JLabel> labelTable = new Hashtable<Integer, JLabel>();
- double dval = start;
- while (dval <= model.getDoubleMaximum()) {
- int sliderValue = model.doubleToSlider(dval);
- String text = NumericOutput.doubleToString(dval, 0, places);
- labelTable.put(new Integer(sliderValue), new JLabel(text));
- dval = nextLabelValue(dval, delta);
- }
- setLabelTable(labelTable);
- setPaintLabels(true);
- }
-
-}
diff --git a/src/com/jsyn/swing/DoubleBoundedTextField.java b/src/com/jsyn/swing/DoubleBoundedTextField.java
deleted file mode 100644
index 3301bb1..0000000
--- a/src/com/jsyn/swing/DoubleBoundedTextField.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright 2000 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.swing;
-
-import java.awt.Color;
-import java.awt.event.KeyAdapter;
-import java.awt.event.KeyEvent;
-
-import javax.swing.JTextField;
-import javax.swing.SwingConstants;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
-
-/**
- * TextField that turns pink when modified, and white when the value is entered.
- *
- * @author (C) 2000-2010 Phil Burk, Mobileer Inc
- * @version 16
- */
-
-public class DoubleBoundedTextField extends JTextField {
- private static final long serialVersionUID = 6882779668177620812L;
- boolean modified = false;
- int numCharacters;
- private DoubleBoundedRangeModel model;
-
- public DoubleBoundedTextField(DoubleBoundedRangeModel pModel, int numCharacters) {
- super(numCharacters);
- this.model = pModel;
- this.numCharacters = numCharacters;
- setHorizontalAlignment(SwingConstants.LEADING);
- setValue(model.getDoubleValue());
- addKeyListener(new KeyAdapter() {
- @Override
- public void keyTyped(KeyEvent e) {
- if (e.getKeyChar() == '\n') {
- model.setDoubleValue(getValue());
- } else {
- markDirty();
- }
- }
- });
- model.addChangeListener(new ChangeListener() {
- @Override
- public void stateChanged(ChangeEvent e) {
- setValue(model.getDoubleValue());
- }
- });
- }
-
- private void markDirty() {
- modified = true;
- setBackground(Color.pink);
- repaint();
- }
-
- private void markClean() {
- modified = false;
- setBackground(Color.white);
- setCaretPosition(0);
- repaint();
- }
-
- @Override
- public void setText(String text) {
- markDirty();
- super.setText(text);
- }
-
- private double getValue() throws NumberFormatException {
- double val = Double.valueOf(getText()).doubleValue();
- markClean();
- return val;
- }
-
- private void setValue(double value) {
- super.setText(String.format("%6.4f", value));
- markClean();
- }
-}
diff --git a/src/com/jsyn/swing/EnvelopeEditorBox.java b/src/com/jsyn/swing/EnvelopeEditorBox.java
deleted file mode 100644
index aab5762..0000000
--- a/src/com/jsyn/swing/EnvelopeEditorBox.java
+++ /dev/null
@@ -1,573 +0,0 @@
-/*
- * 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.swing;
-
-import java.awt.Color;
-import java.awt.Graphics;
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseListener;
-import java.awt.event.MouseMotionListener;
-import java.util.ArrayList;
-
-import com.jsyn.data.SegmentedEnvelope;
-import com.jsyn.unitgen.VariableRateDataReader;
-
-/**
- * Edit a list of ordered duration,value pairs suitable for use with a SegmentedEnvelope.
- *
- * @author (C) 1997-2013 Phil Burk, SoftSynth.com
- * @see EnvelopePoints
- * @see SegmentedEnvelope
- * @see VariableRateDataReader
- */
-
-/* ========================================================================== */
-public class EnvelopeEditorBox extends XYController implements MouseListener, MouseMotionListener {
- EnvelopePoints points;
- ArrayList<EditListener> listeners = new ArrayList<EditListener>();
- int dragIndex = -1;
- double dragLowLimit;
- double dragHighLimit;
- double draggedPoint[];
- double xBefore; // WX value before point
- double xPicked; // WX value of picked point
- double dragWX;
- double dragWY;
- int maxPoints = Integer.MAX_VALUE;
- int radius = 4;
- double verticalBarSpacing = 1.0;
- boolean verticalBarsEnabled = false;
- double maximumXRange = Double.MAX_VALUE;
- double minimumXRange = 0.1;
- int rangeStart = -1; // gx coordinates
- int rangeEnd = -1;
- int mode = EDIT_POINTS;
- public final static int EDIT_POINTS = 0;
- public final static int SELECT_SUSTAIN = 1;
- public final static int SELECT_RELEASE = 2;
-
- Color rangeColor = Color.RED;
- Color sustainColor = Color.BLUE;
- Color releaseColor = Color.YELLOW;
- Color overlapColor = Color.GREEN;
- Color firstLineColor = Color.GRAY;
-
- public interface EditListener {
- public void objectEdited(Object editor, Object edited);
- }
-
- public EnvelopeEditorBox() {
- addMouseListener(this);
- addMouseMotionListener(this);
- }
-
- public void setMaximumXRange(double maxXRange) {
- maximumXRange = maxXRange;
- }
-
- public double getMaximumXRange() {
- return maximumXRange;
- }
-
- public void setMinimumXRange(double minXRange) {
- minimumXRange = minXRange;
- }
-
- public double getMinimumXRange() {
- return minimumXRange;
- }
-
- public void setSelection(int start, int end) {
- switch (mode) {
- case SELECT_SUSTAIN:
- points.setSustainLoop(start, end);
- break;
- case SELECT_RELEASE:
- points.setReleaseLoop(start, end);
- break;
- }
- // System.out.println("start = " + start + ", end = " + end );
- }
-
- /** Set mode to either EDIT_POINTS or SELECT_SUSTAIN, SELECT_RELEASE; */
- public void setMode(int mode) {
- this.mode = mode;
- }
-
- public int getMode() {
- return mode;
- }
-
- /**
- * Add a listener to receive edit events. Listener will be passed the editor object and the
- * edited object.
- */
- public void addEditListener(EditListener listener) {
- listeners.add(listener);
- }
-
- public void removeEditListener(EditListener listener) {
- listeners.remove(listener);
- }
-
- /** Send event to every subscribed listener. */
- public void fireObjectEdited() {
- for (EditListener listener : listeners) {
- listener.objectEdited(this, points);
- }
- }
-
- public void setMaxPoints(int maxPoints) {
- this.maxPoints = maxPoints;
- }
-
- public int getMaxPoints() {
- return maxPoints;
- }
-
- public int getNumPoints() {
- return points.size();
- }
-
- public void setPoints(EnvelopePoints points) {
- this.points = points;
- setMaxWorldY(points.getMaximumValue());
- }
-
- public EnvelopePoints getPoints() {
- return points;
- }
-
- /**
- * Return index of point before this X position.
- */
- private int findPointBefore(double wx) {
- int pnt = -1;
- double px = 0.0;
- xBefore = 0.0;
- for (int i = 0; i < points.size(); i++) {
- px += points.getDuration(i);
- if (px > wx)
- break;
- pnt = i;
- xBefore = px;
- }
- return pnt;
- }
-
- private int pickPoint(double wx, double wxAperture, double wy, double wyAperture) {
- double px = 0.0;
- double wxLow = wx - wxAperture;
- double wxHigh = wx + wxAperture;
- // System.out.println("wxLow = " + wxLow + ", wxHigh = " + wxHigh );
- double wyLow = wy - wyAperture;
- double wyHigh = wy + wyAperture;
- // System.out.println("wyLow = " + wyLow + ", wyHigh = " + wyHigh );
- double wxScale = 1.0 / wxAperture; // only divide once, then multiply
- double wyScale = 1.0 / wyAperture;
- int bestPoint = -1;
- double bestDistance = Double.MAX_VALUE;
- for (int i = 0; i < points.size(); i++) {
- double dar[] = points.getPoint(i);
- px += dar[0];
- double py = dar[1];
- // System.out.println("px = " + px + ", py = " + py );
- if ((px > wxLow) && (px < wxHigh) && (py > wyLow) && (py < wyHigh)) {
- /* Inside pick range. Calculate distance squared. */
- double ndx = (px - wx) * wxScale;
- double ndy = (py - wy) * wyScale;
- double dist = (ndx * ndx) + (ndy * ndy);
- // System.out.println("dist = " + dist );
- if (dist < bestDistance) {
- bestPoint = i;
- bestDistance = dist;
- xPicked = px;
- }
- }
- }
- return bestPoint;
- }
-
- private void clickDownRange(boolean shiftDown, int gx, int gy) {
- setSelection(-1, -1);
- rangeStart = rangeEnd = gx;
- repaint();
- }
-
- private void dragRange(int gx, int gy) {
- rangeEnd = gx;
- repaint();
- }
-
- private void clickUpRange(int gx, int gy) {
- dragRange(gx, gy);
- if (rangeEnd < rangeStart) {
- int temp = rangeEnd;
- rangeEnd = rangeStart;
- rangeStart = temp;
- }
- // System.out.println("clickUpRange: gx = " + gx + ", rangeStart = " +
- // rangeStart );
- double wx = convertGXtoWX(rangeStart);
- int i0 = findPointBefore(wx);
- wx = convertGXtoWX(rangeEnd);
- int i1 = findPointBefore(wx);
-
- if (i1 == i0) {
- // set single point at zero so there is nothing played for queueOn()
- if (gx < 0) {
- setSelection(0, 0);
- }
- // else clear any existing loop
- } else if (i1 == (i0 + 1)) {
- setSelection(i1 + 1, i1 + 1); // set to a single point
- } else if (i1 > (i0 + 1)) {
- setSelection(i0 + 1, i1 + 1); // set to a range of two or more
- }
-
- rangeStart = -1;
- rangeEnd = -1;
- fireObjectEdited();
- }
-
- private void clickDownPoints(boolean shiftDown, int gx, int gy) {
- dragIndex = -1;
- double wx = convertGXtoWX(gx);
- double wy = convertGYtoWY(gy);
- // calculate world values for aperture
- double wxAp = convertGXtoWX(radius + 2) - convertGXtoWX(0);
- // System.out.println("wxAp = " + wxAp );
- double wyAp = convertGYtoWY(0) - convertGYtoWY(radius + 2);
- // System.out.println("wyAp = " + wyAp );
- int pnt = pickPoint(wx, wxAp, wy, wyAp);
- // System.out.println("pickPoint = " + pnt);
- if (shiftDown) {
- if (pnt >= 0) {
- points.removePoint(pnt);
- repaint();
- }
- } else {
- if (pnt < 0) // didn't hit one so look for point to left of click
- {
- if (points.size() < maxPoints) // add if room
- {
- pnt = findPointBefore(wx);
- // System.out.println("pointBefore = " + pnt);
- dragIndex = pnt + 1;
- if (pnt == (points.size() - 1)) {
- points.add(wx - xBefore, wy);
- } else {
- points.insert(dragIndex, wx - xBefore, wy);
- }
- dragLowLimit = xBefore;
- dragHighLimit = wx + (maximumXRange - points.getTotalDuration());
- repaint();
- }
- } else
- // hit one so drag it
- {
- dragIndex = pnt;
- if (dragIndex <= 0)
- dragLowLimit = 0.0; // FIXME envelope drag limit
- else
- dragLowLimit = xPicked - points.getPoint(dragIndex)[0];
- dragHighLimit = xPicked + (maximumXRange - points.getTotalDuration());
- // System.out.println("dragLowLimit = " + dragLowLimit );
- }
- }
- // Set up drag point if we are dragging.
- if (dragIndex >= 0) {
- draggedPoint = points.getPoint(dragIndex);
- }
-
- }
-
- private void dragPoint(int gx, int gy) {
- if (dragIndex < 0)
- return;
-
- double wx = convertGXtoWX(gx);
- if (wx < dragLowLimit)
- wx = dragLowLimit;
- else if (wx > dragHighLimit)
- wx = dragHighLimit;
- draggedPoint[0] = wx - dragLowLimit; // duration
-
- double wy = convertGYtoWY(gy);
- wy = clipWorldY(wy);
- draggedPoint[1] = wy;
- dragWY = wy;
- dragWX = wx;
- points.setDirty(true);
- repaint();
- }
-
- private void clickUpPoints(int gx, int gy) {
- dragPoint(gx, gy);
- fireObjectEdited();
- dragIndex = -1;
- }
-
- // Implement the MouseMotionListener interface for AWT 1.1
- @Override
- public void mouseDragged(MouseEvent e) {
- int x = e.getX();
- int y = e.getY();
- if (points == null)
- return;
- if (mode == EDIT_POINTS) {
- dragPoint(x, y);
- } else {
- dragRange(x, y);
- }
- }
-
- @Override
- public void mouseMoved(MouseEvent e) {
- }
-
- // Implement the MouseListener interface for AWT 1.1
- @Override
- public void mousePressed(MouseEvent e) {
- int x = e.getX();
- int y = e.getY();
- if (points == null)
- return;
- if (mode == EDIT_POINTS) {
- clickDownPoints(e.isShiftDown(), x, y);
- } else {
- clickDownRange(e.isShiftDown(), x, y);
- }
- }
-
- @Override
- public void mouseClicked(MouseEvent e) {
- }
-
- @Override
- public void mouseReleased(MouseEvent e) {
- int x = e.getX();
- int y = e.getY();
- if (points == null)
- return;
- if (mode == EDIT_POINTS) {
- clickUpPoints(x, y);
- } else {
- clickUpRange(x, y);
- }
- }
-
- @Override
- public void mouseEntered(MouseEvent e) {
- }
-
- @Override
- public void mouseExited(MouseEvent e) {
- }
-
- /**
- * Draw selected range.
- */
- private void drawRange(Graphics g) {
- if (rangeStart >= 0) {
- int height = getHeight();
- int gx0 = 0, gx1 = 0;
-
- if (rangeEnd < rangeStart) {
- gx0 = rangeEnd;
- gx1 = rangeStart;
- } else {
- gx0 = rangeStart;
- gx1 = rangeEnd;
- }
- g.setColor(rangeColor);
- g.fillRect(gx0, 0, gx1 - gx0, height);
- }
- }
-
- private void drawUnderSelection(Graphics g, int start, int end) {
- if (start >= 0) {
- int height = getHeight();
- int gx0 = 0, gx1 = radius;
- double wx = 0.0;
- for (int i = 0; i <= (end - 1); i++) {
- double dar[] = (double[]) points.elementAt(i);
- wx += dar[0];
- if (start == (i + 1)) {
- gx0 = convertWXtoGX(wx) + radius;
- }
- if (end == (i + 1)) {
- gx1 = convertWXtoGX(wx) + radius;
- }
- }
- if (gx0 == gx1)
- gx0 = gx0 - radius;
- g.fillRect(gx0, 0, gx1 - gx0, height);
- }
- }
-
- private void drawSelections(Graphics g) {
- int sus0 = points.getSustainBegin();
- int sus1 = points.getSustainEnd();
- int rel0 = points.getReleaseBegin();
- int rel1 = points.getReleaseEnd();
-
- g.setColor(sustainColor);
- drawUnderSelection(g, sus0, sus1);
- g.setColor(releaseColor);
- drawUnderSelection(g, rel0, rel1);
- // draw overlapping sustain and release region
- if (sus1 >= rel0) {
- int sel1 = (rel1 < sus1) ? rel1 : sus1;
- g.setColor(overlapColor);
- drawUnderSelection(g, rel0, sel1);
- }
- }
-
- /**
- * Override this to draw a grid or other stuff under the envelope.
- */
- public void drawUnderlay(Graphics g) {
- if (dragIndex < 0) {
- drawSelections(g);
- drawRange(g);
- }
- if (verticalBarsEnabled)
- drawVerticalBars(g);
- }
-
- public void setVerticalBarsEnabled(boolean flag) {
- verticalBarsEnabled = flag;
- }
-
- public boolean areVerticalBarsEnabled() {
- return verticalBarsEnabled;
- }
-
- /**
- * Set spacing in world coordinates.
- */
- public void setVerticalBarSpacing(double spacing) {
- verticalBarSpacing = spacing;
- }
-
- public double getVerticalBarSpacing() {
- return verticalBarSpacing;
- }
-
- /**
- * Draw vertical lines.
- */
- private void drawVerticalBars(Graphics g) {
- int width = getWidth();
- int height = getHeight();
- double wx = verticalBarSpacing;
- int gx;
-
- // g.setColor( getBackground().darker() );
- g.setColor(Color.lightGray);
- while (true) {
- gx = convertWXtoGX(wx);
- if (gx > width)
- break;
- g.drawLine(gx, 0, gx, height);
- wx += verticalBarSpacing;
- }
- }
-
- public void drawPoints(Graphics g, Color lineColor) {
- double wx = 0.0;
- int gx1 = 0;
- int gy1 = getHeight();
- for (int i = 0; i < points.size(); i++) {
- double dar[] = (double[]) points.elementAt(i);
- wx += dar[0];
- double wy = dar[1];
- int gx2 = convertWXtoGX(wx);
- int gy2 = convertWYtoGY(wy);
- if (i == 0) {
- g.setColor(isEnabled() ? firstLineColor : firstLineColor.darker());
- g.drawLine(gx1, gy1, gx2, gy2);
- g.setColor(isEnabled() ? lineColor : lineColor.darker());
- } else if (i > 0) {
- g.drawLine(gx1, gy1, gx2, gy2);
- }
- int diameter = (2 * radius) + 1;
- g.fillOval(gx2 - radius, gy2 - radius, diameter, diameter);
- gx1 = gx2;
- gy1 = gy2;
- }
- }
-
- public void drawAllPoints(Graphics g) {
- drawPoints(g, getForeground());
- }
-
- /* Override default paint action. */
- @Override
- public void paint(Graphics g) {
- double wx = 0.0;
- int width = getWidth();
- int height = getHeight();
-
- // draw background and erase all values
- g.setColor(isEnabled() ? getBackground() : getBackground().darker());
- g.fillRect(0, 0, width, height);
-
- if (points == null) {
- g.setColor(getForeground());
- g.drawString("No EnvelopePoints", 10, 30);
- return;
- }
-
- // Determine total duration.
- if (points.size() > 0) {
- wx = points.getTotalDuration();
- // Adjust max X so that we see entire circle of last point.
- double radiusWX = this.convertGXtoWX(radius) - this.getMinWorldX();
- double wxFar = wx + radiusWX;
- if (wxFar > getMaxWorldX()) {
- if (wx > maximumXRange)
- wxFar = maximumXRange;
- setMaxWorldX(wxFar);
- } else if (wx < (getMaxWorldX() * 0.7)) {
- double newMax = wx / 0.7001; // make slightly larger to prevent
- // endless jitter, FIXME - still
- // needed after repaint()
- // removed from setMaxWorldX?
- // System.out.println("newMax = " + newMax );
- if (newMax < minimumXRange)
- newMax = minimumXRange;
- setMaxWorldX(newMax);
- }
- }
- // System.out.println("total X = " + wx );
-
- drawUnderlay(g);
-
- drawAllPoints(g);
-
- /* Show X,Y,TotalX as text. */
- g.drawString(points.getName() + ", len=" + String.format("%7.3f", wx), 5, 15);
- if ((draggedPoint != null) && (dragIndex >= 0)) {
- String s = "i=" + dragIndex + ", dur="
- + String.format("%7.3f", draggedPoint[0]) + ", y = "
- + String.format("%8.4f", draggedPoint[1]);
- g.drawString(s, 5, 30);
- }
- }
-}
diff --git a/src/com/jsyn/swing/EnvelopeEditorPanel.java b/src/com/jsyn/swing/EnvelopeEditorPanel.java
deleted file mode 100644
index dc9f2cd..0000000
--- a/src/com/jsyn/swing/EnvelopeEditorPanel.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright 2009 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.swing;
-
-import java.awt.BorderLayout;
-import java.awt.Button;
-import java.awt.Checkbox;
-import java.awt.CheckboxGroup;
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Label;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.ItemEvent;
-import java.awt.event.ItemListener;
-
-import javax.swing.JPanel;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
-
-public class EnvelopeEditorPanel extends JPanel {
- EnvelopeEditorBox editor;
- Checkbox pointsBox;
- Checkbox sustainBox;
- Checkbox releaseBox;
- Checkbox autoBox;
- Button onButton;
- Button offButton;
- Button clearButton;
- Button yUpButton;
- Button yDownButton;
- DoubleBoundedTextField zoomField;
-
- public EnvelopeEditorPanel(EnvelopePoints points, int maxFrames) {
- setSize(600, 300);
-
- setLayout(new BorderLayout());
- editor = new EnvelopeEditorBox();
- editor.setMaxPoints(maxFrames);
- editor.setBackground(Color.cyan);
- editor.setPoints(points);
- editor.setMinimumSize(new Dimension(500, 300));
-
- add(editor, "Center");
-
- JPanel buttonPanel = new JPanel();
- add(buttonPanel, "South");
-
- CheckboxGroup cbg = new CheckboxGroup();
- pointsBox = new Checkbox("points", cbg, true);
- pointsBox.addItemListener(new ItemListener() {
- @Override
- public void itemStateChanged(ItemEvent e) {
- editor.setMode(EnvelopeEditorBox.EDIT_POINTS);
- }
- });
- buttonPanel.add(pointsBox);
-
- sustainBox = new Checkbox("onLoop", cbg, false);
- sustainBox.addItemListener(new ItemListener() {
- @Override
- public void itemStateChanged(ItemEvent e) {
- editor.setMode(EnvelopeEditorBox.SELECT_SUSTAIN);
- }
- });
- buttonPanel.add(sustainBox);
-
- releaseBox = new Checkbox("offLoop", cbg, false);
- releaseBox.addItemListener(new ItemListener() {
- @Override
- public void itemStateChanged(ItemEvent e) {
- editor.setMode(EnvelopeEditorBox.SELECT_RELEASE);
- }
- });
- buttonPanel.add(releaseBox);
-
- autoBox = new Checkbox("AutoStop", false);
- /*
- * buttonPanel.add( onButton = new Button( "On" ) ); onButton.addActionListener( module );
- * buttonPanel.add( offButton = new Button( "Off" ) ); offButton.addActionListener( module
- * ); buttonPanel.add( clearButton = new Button( "Clear" ) ); clearButton.addActionListener(
- * module );
- */
- buttonPanel.add(yUpButton = new Button("Y*2"));
- yUpButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- scaleEnvelopeValues(2.0);
- }
- });
-
- buttonPanel.add(yDownButton = new Button("Y/2"));
- yDownButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- scaleEnvelopeValues(0.5);
- }
- });
-
- /* Add a TextField for setting the Y scale. */
- double max = getMaxEnvelopeValue(editor.getPoints());
- editor.setMaxWorldY(max);
- buttonPanel.add(new Label("YMax ="));
- final DoubleBoundedRangeModel model = new DoubleBoundedRangeModel("YMax", 100000, 1.0,
- 100001.0, 1.0);
- buttonPanel.add(zoomField = new DoubleBoundedTextField(model, 8));
- model.addChangeListener(new ChangeListener() {
- @Override
- public void stateChanged(ChangeEvent e) {
- try {
- double val = model.getDoubleValue();
- editor.setMaxWorldY(val);
- editor.repaint();
- } catch (NumberFormatException exp) {
- zoomField.setText("ERROR");
- zoomField.selectAll();
- }
- }
- });
-
- validate();
- }
-
- /**
- * Multiply all the values in the envelope by scalar.
- */
- double getMaxEnvelopeValue(EnvelopePoints points) {
- double max = 1.0;
- for (int i = 0; i < points.size(); i++) {
- double value = points.getValue(i);
- if (value > max) {
- max = value;
- }
- }
- return max;
- }
-
- /**
- * Multiply all the values in the envelope by scalar.
- */
- void scaleEnvelopeValues(double scalar) {
- EnvelopePoints points = editor.getPoints();
- for (int i = 0; i < points.size(); i++) {
- double[] dar = points.getPoint(i);
- dar[1] = dar[1] * scalar; // scale value
- }
- points.setDirty(true);
- editor.repaint();
- }
-}
diff --git a/src/com/jsyn/swing/EnvelopePoints.java b/src/com/jsyn/swing/EnvelopePoints.java
deleted file mode 100644
index ab4ed03..0000000
--- a/src/com/jsyn/swing/EnvelopePoints.java
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * 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.swing;
-
-import java.util.Vector;
-
-import com.jsyn.data.SegmentedEnvelope;
-
-/**
- * Vector that contains duration,value pairs. Used by EnvelopeEditor
- *
- * @author (C) 1997 Phil Burk, SoftSynth.com
- */
-
-/* ========================================================================== */
-public class EnvelopePoints extends Vector {
- private String name = "";
- private double maximumValue = 1.0;
- private int sustainBegin = -1;
- private int sustainEnd = -1;
- private int releaseBegin = -1;
- private int releaseEnd = -1;
- private boolean dirty = false;
-
- /**
- * Update only if points or loops were modified.
- */
- public void updateEnvelopeIfDirty(SegmentedEnvelope envelope) {
- if (dirty) {
- updateEnvelope(envelope);
- }
- }
-
- /**
- * The editor works on a vector of points, not a real envelope. The data must be written to a
- * real SynthEnvelope in order to use it.
- */
- public void updateEnvelope(SegmentedEnvelope envelope) {
- int numFrames = size();
- for (int i = 0; i < numFrames; i++) {
- envelope.write(i, getPoint(i), 0, 1);
- }
- envelope.setSustainBegin(getSustainBegin());
- envelope.setSustainEnd(getSustainEnd());
- envelope.setReleaseBegin(getReleaseBegin());
- envelope.setReleaseEnd(getReleaseEnd());
- envelope.setNumFrames(numFrames);
- dirty = false;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String getName() {
- return name;
- }
-
- public void setMaximumValue(double maximumValue) {
- this.maximumValue = maximumValue;
- }
-
- public double getMaximumValue() {
- return maximumValue;
- }
-
- public void add(double dur, double value) {
- double dar[] = {
- dur, value
- };
- addElement(dar);
- dirty = true;
- }
-
- /**
- * Insert point without changing total duration by reducing next points duration.
- */
- public void insert(int index, double dur, double y) {
- double dar[] = {
- dur, y
- };
- if (index < size()) {
- ((double[]) elementAt(index))[0] -= dur;
- }
- insertElementAt(dar, index);
-
- if (index <= sustainBegin)
- sustainBegin += 1;
- if (index <= sustainEnd)
- sustainEnd += 1;
- if (index <= releaseBegin)
- releaseBegin += 1;
- if (index <= releaseEnd)
- releaseEnd += 1;
- dirty = true;
- }
-
- /**
- * Remove indexed point and update sustain and release loops if necessary. Did not name this
- * "remove()" because of conflicts with new JDK 1.3 method with the same name.
- */
- public void removePoint(int index) {
- super.removeElementAt(index);
- // move down loop if points below or inside loop removed
- if (index < sustainBegin)
- sustainBegin -= 1;
- if (index <= sustainEnd)
- sustainEnd -= 1;
- if (index < releaseBegin)
- releaseBegin -= 1;
- if (index <= releaseEnd)
- releaseEnd -= 1;
-
- // was entire loop removed?
- if (sustainBegin > sustainEnd) {
- sustainBegin = -1;
- sustainEnd = -1;
- }
- // was entire loop removed?
- if (releaseBegin > releaseEnd) {
- releaseBegin = -1;
- releaseEnd = -1;
- }
- dirty = true;
- }
-
- public double getDuration(int index) {
- return ((double[]) elementAt(index))[0];
- }
-
- public double getValue(int index) {
- return ((double[]) elementAt(index))[1];
- }
-
- public double[] getPoint(int index) {
- return (double[]) elementAt(index);
- }
-
- public double getTotalDuration() {
- double sum = 0.0;
- for (int i = 0; i < size(); i++) {
- double dar[] = (double[]) elementAt(i);
- sum += dar[0];
- }
- return sum;
- }
-
- /**
- * Set location of Sustain Loop in units of Frames. Set SustainBegin to -1 if no Sustain Loop.
- * SustainEnd value is the frame index of the frame just past the end of the loop. The number of
- * frames included in the loop is (SustainEnd - SustainBegin).
- */
- public void setSustainLoop(int startFrame, int endFrame) {
- this.sustainBegin = startFrame;
- this.sustainEnd = endFrame;
- dirty = true;
- }
-
- /***
- * @return Beginning of sustain loop or -1 if no loop.
- */
- public int getSustainBegin() {
- return this.sustainBegin;
- }
-
- /***
- * @return End of sustain loop or -1 if no loop.
- */
- public int getSustainEnd() {
- return this.sustainEnd;
- }
-
- /***
- * @return Size of sustain loop in frames, 0 if no loop.
- */
- public int getSustainSize() {
- return (this.sustainEnd - this.sustainBegin);
- }
-
- /**
- * Set location of Release Loop in units of Frames. Set ReleaseBegin to -1 if no ReleaseLoop.
- * ReleaseEnd value is the frame index of the frame just past the end of the loop. The number of
- * frames included in the loop is (ReleaseEnd - ReleaseBegin).
- */
- public void setReleaseLoop(int startFrame, int endFrame) {
- this.releaseBegin = startFrame;
- this.releaseEnd = endFrame;
- dirty = true;
- }
-
- /***
- * @return Beginning of release loop or -1 if no loop.
- */
- public int getReleaseBegin() {
- return this.releaseBegin;
- }
-
- /***
- * @return End of release loop or -1 if no loop.
- */
- public int getReleaseEnd() {
- return this.releaseEnd;
- }
-
- /***
- * @return Size of release loop in frames, 0 if no loop.
- */
- public int getReleaseSize() {
- return (this.releaseEnd - this.releaseBegin);
- }
-
- public boolean isDirty() {
- return dirty;
- }
-
- public void setDirty(boolean b) {
- dirty = b;
- }
-
-}
diff --git a/src/com/jsyn/swing/ExponentialRangeModel.java b/src/com/jsyn/swing/ExponentialRangeModel.java
deleted file mode 100644
index 4411947..0000000
--- a/src/com/jsyn/swing/ExponentialRangeModel.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright 2011 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.swing;
-
-/**
- * Maps integer range info to a double value along an exponential scale.
- *
- * <pre>
- *
- * x = ival / resolution
- * f(x) = a*(root&circ;cx) + b
- * f(0.0) = dmin
- * f(1.0) = dmax
- * b = dmin - a
- * a = (dmax - dmin) / (root&circ;c - 1)
- *
- * Inverse function:
- * x = log( (y-b)/a ) / log(root)
- *
- * </pre>
- *
- * @author Phil Burk, (C) 2011 Mobileer Inc
- */
-public class ExponentialRangeModel extends DoubleBoundedRangeModel {
- private static final long serialVersionUID = -142785624892302160L;
- double a = 1.0;
- double b = -1.0;
- double span = 1.0;
- double root = 10.0;
-
- /** Use default root of 10.0 and span of 1.0. */
- public ExponentialRangeModel(String name, int resolution, double dmin, double dmax, double dval) {
- this(name, resolution, dmin, dmax, dval, 1.0);
- }
-
- /** Set span before setting double value so it is translated correctly. */
- ExponentialRangeModel(String name, int resolution, double dmin, double dmax, double dval,
- double span) {
- super(name, resolution, dmin, dmax, dval);
- setRoot(10.0);
- setSpan(span);
- /* Set again after coefficients setup. */
- setDoubleValue(dval);
- }
-
- private void updateCoefficients() {
- a = (getDoubleMaximum() - getDoubleMinimum()) / (Math.pow(root, span) - 1.0);
- b = getDoubleMinimum() - a;
- }
-
- private void setRoot(double w) {
- root = w;
- updateCoefficients();
- }
-
- public double getRoot() {
- return root;
- }
-
- public void setSpan(double c) {
- this.span = c;
- updateCoefficients();
- }
-
- public double getSpan() {
- return span;
- }
-
- @Override
- public double sliderToDouble(int sliderValue) {
- updateCoefficients(); // TODO optimize when we call this
- double x = (double) sliderValue / getMaximum();
- double y = (a * Math.pow(root, span * x)) + b;
- return y;
- }
-
- @Override
- public int doubleToSlider(double dval) {
- updateCoefficients(); // TODO optimize when we call this
- double z = (dval - b) / a;
- double x = Math.log(z) / (span * Math.log(root));
- return (int) Math.round(x * getMaximum());
- }
-
- public void test(int sliderValue) {
- double dval = sliderToDouble(sliderValue);
- int ival = doubleToSlider(dval);
- System.out.println(sliderValue + " => " + dval + " => " + ival);
- }
-
-}
diff --git a/src/com/jsyn/swing/InstrumentBrowser.java b/src/com/jsyn/swing/InstrumentBrowser.java
deleted file mode 100644
index 55575a3..0000000
--- a/src/com/jsyn/swing/InstrumentBrowser.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright 2012 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.swing;
-
-import java.awt.Dimension;
-import java.awt.GridLayout;
-import java.util.ArrayList;
-
-import javax.swing.JList;
-import javax.swing.JPanel;
-import javax.swing.JScrollPane;
-import javax.swing.ListSelectionModel;
-import javax.swing.event.ListSelectionEvent;
-import javax.swing.event.ListSelectionListener;
-
-import com.jsyn.util.InstrumentLibrary;
-import com.jsyn.util.VoiceDescription;
-
-/**
- * Display a list of VoiceDescriptions and their associated presets. Notify PresetSelectionListeners
- * when a preset is selected.
- *
- * @author Phil Burk (C) 2012 Mobileer Inc
- */
-@SuppressWarnings("serial")
-public class InstrumentBrowser extends JPanel {
- private InstrumentLibrary library;
- private JScrollPane listScroller2;
- private VoiceDescription voiceDescription;
- private ArrayList<PresetSelectionListener> listeners = new ArrayList<PresetSelectionListener>();
-
- public InstrumentBrowser(InstrumentLibrary library) {
- this.library = library;
- JPanel horizontalPanel = new JPanel();
- horizontalPanel.setLayout(new GridLayout(1, 2));
-
- final JList<VoiceDescription> instrumentList = new JList<VoiceDescription>(library.getVoiceDescriptions());
- setupList(instrumentList);
- instrumentList.addListSelectionListener(new ListSelectionListener() {
- @Override
- public void valueChanged(ListSelectionEvent e) {
- if (e.getValueIsAdjusting() == false) {
- int n = instrumentList.getSelectedIndex();
- if (n >= 0) {
- showPresetList(n);
- }
- }
- }
- });
-
- JScrollPane listScroller1 = new JScrollPane(instrumentList);
- listScroller1.setPreferredSize(new Dimension(250, 120));
- add(listScroller1);
-
- instrumentList.setSelectedIndex(0);
- }
-
- public void addPresetSelectionListener(PresetSelectionListener listener) {
- listeners.add(listener);
- }
-
- public void removePresetSelectionListener(PresetSelectionListener listener) {
- listeners.remove(listener);
- }
-
- private void firePresetSelectionListeners(VoiceDescription voiceDescription, int presetIndex) {
- for (PresetSelectionListener listener : listeners) {
- listener.presetSelected(voiceDescription, presetIndex);
- }
- }
-
- private void showPresetList(int n) {
- if (listScroller2 != null) {
- remove(listScroller2);
- }
- voiceDescription = library.getVoiceDescriptions()[n];
- final JList<String> presetList = new JList<String>(voiceDescription.getPresetNames());
- setupList(presetList);
- presetList.addListSelectionListener(new ListSelectionListener() {
- @Override
- public void valueChanged(ListSelectionEvent e) {
- if (e.getValueIsAdjusting() == false) {
- int n = presetList.getSelectedIndex();
- if (n >= 0) {
- firePresetSelectionListeners(voiceDescription, n);
- }
- }
- }
- });
-
- listScroller2 = new JScrollPane(presetList);
- listScroller2.setPreferredSize(new Dimension(250, 120));
- add(listScroller2);
- presetList.setSelectedIndex(0);
- validate();
- }
-
- private void setupList(@SuppressWarnings("rawtypes") JList list) {
- list.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
- list.setLayoutOrientation(JList.VERTICAL);
- list.setVisibleRowCount(-1);
- }
-}
diff --git a/src/com/jsyn/swing/JAppletFrame.java b/src/com/jsyn/swing/JAppletFrame.java
deleted file mode 100644
index 53bd65b..0000000
--- a/src/com/jsyn/swing/JAppletFrame.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.swing;
-
-import java.awt.event.WindowAdapter;
-import java.awt.event.WindowEvent;
-
-import javax.swing.JApplet;
-import javax.swing.JFrame;
-
-/**
- * Frame that allows a program to be run as either an Application or an Applet. Used by JSyn example
- * programs.
- *
- * @author (C) 1997 Phil Burk, SoftSynth.com
- */
-
-public class JAppletFrame extends JFrame {
- private static final long serialVersionUID = -6047247494856379114L;
- JApplet applet;
-
- public JAppletFrame(String frameTitle, final JApplet pApplet) {
- super(frameTitle);
- this.applet = pApplet;
- getContentPane().add(applet);
- repaint();
-
- addWindowListener(new WindowAdapter() {
- @Override
- public void windowClosing(WindowEvent e) {
- applet.stop();
- applet.destroy();
- try {
- System.exit(0);
- } catch (SecurityException exc) {
- System.err.println("System.exit(0) not allowed by Java VM.");
- }
- }
-
- @Override
- public void windowClosed(WindowEvent e) {
- }
- });
- }
-
- public void test() {
- applet.init();
- applet.start();
- }
-
-}
diff --git a/src/com/jsyn/swing/PortBoundedRangeModel.java b/src/com/jsyn/swing/PortBoundedRangeModel.java
deleted file mode 100644
index a5cf841..0000000
--- a/src/com/jsyn/swing/PortBoundedRangeModel.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright 2011 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.swing;
-
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
-
-import com.jsyn.ports.UnitInputPort;
-
-/**
- * A bounded range model that drives a UnitInputPort. The range of the model is set based on the min
- * and max of the port.
- *
- * @author Phil Burk (C) 2011 Mobileer Inc
- */
-public class PortBoundedRangeModel extends DoubleBoundedRangeModel {
- private static final long serialVersionUID = -8011867146560305808L;
- private UnitInputPort port;
-
- public PortBoundedRangeModel(UnitInputPort pPort) {
- super(pPort.getName(), 10000, pPort.getMinimum(), pPort.getMaximum(), pPort.getValue());
- this.port = pPort;
- addChangeListener(new ChangeListener() {
- @Override
- public void stateChanged(ChangeEvent e) {
- port.set(getDoubleValue());
- }
- });
- }
-
-}
diff --git a/src/com/jsyn/swing/PortControllerFactory.java b/src/com/jsyn/swing/PortControllerFactory.java
deleted file mode 100644
index a73d047..0000000
--- a/src/com/jsyn/swing/PortControllerFactory.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2010 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.swing;
-
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
-
-import com.jsyn.ports.UnitInputPort;
-
-/**
- * Factory class for making various controllers for JSyn ports.
- *
- * @author Phil Burk (C) 2010 Mobileer Inc
- */
-public class PortControllerFactory {
- private static final int RESOLUTION = 100000;
-
- public static DoubleBoundedRangeSlider createPortSlider(final UnitInputPort port) {
- DoubleBoundedRangeModel rangeModel = new DoubleBoundedRangeModel(port.getName(),
- RESOLUTION, port.getMinimum(), port.getMaximum(), port.get());
- rangeModel.addChangeListener(new ChangeListener() {
- @Override
- public void stateChanged(ChangeEvent e) {
- DoubleBoundedRangeModel model = (DoubleBoundedRangeModel) e.getSource();
- double value = model.getDoubleValue();
- port.set(value);
- }
- });
- return new DoubleBoundedRangeSlider(rangeModel, 4);
- }
-
- public static DoubleBoundedRangeSlider createExponentialPortSlider(final UnitInputPort port) {
- ExponentialRangeModel rangeModel = new ExponentialRangeModel(port.getName(), RESOLUTION,
- port.getMinimum(), port.getMaximum(), port.get());
- rangeModel.addChangeListener(new ChangeListener() {
- @Override
- public void stateChanged(ChangeEvent e) {
- ExponentialRangeModel model = (ExponentialRangeModel) e.getSource();
- double value = model.getDoubleValue();
- port.set(value);
- }
- });
- return new DoubleBoundedRangeSlider(rangeModel, 4);
- }
-
-}
diff --git a/src/com/jsyn/swing/PortModelFactory.java b/src/com/jsyn/swing/PortModelFactory.java
deleted file mode 100644
index 8bec76a..0000000
--- a/src/com/jsyn/swing/PortModelFactory.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright 2009 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.swing;
-
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
-
-import com.jsyn.ports.UnitInputPort;
-
-public class PortModelFactory {
- private static final int RESOLUTION = 1000000;
-
- public static DoubleBoundedRangeModel createLinearModel(final UnitInputPort pPort) {
- final DoubleBoundedRangeModel model = new DoubleBoundedRangeModel(pPort.getName(),
- RESOLUTION, pPort.getMinimum(), pPort.getMaximum(), pPort.get());
- model.addChangeListener(new ChangeListener() {
- @Override
- public void stateChanged(ChangeEvent e) {
- pPort.set(model.getDoubleValue());
- }
- });
- return model;
- }
-
- public static ExponentialRangeModel createExponentialModel(final UnitInputPort pPort) {
- final ExponentialRangeModel model = new ExponentialRangeModel(pPort.getName(), RESOLUTION,
- pPort.getMinimum(), pPort.getMaximum(), pPort.get());
- model.addChangeListener(new ChangeListener() {
- @Override
- public void stateChanged(ChangeEvent e) {
- pPort.set(model.getDoubleValue());
- }
- });
- return model;
- }
-
- public static ExponentialRangeModel createExponentialModel(final int partNum,
- final UnitInputPort pPort) {
- final ExponentialRangeModel model = new ExponentialRangeModel(pPort.getName(), RESOLUTION,
- pPort.getMinimum(), pPort.getMaximum(), pPort.get());
- model.addChangeListener(new ChangeListener() {
- @Override
- public void stateChanged(ChangeEvent e) {
- pPort.set(partNum, model.getDoubleValue());
- }
- });
- return model;
- }
-
-}
diff --git a/src/com/jsyn/swing/PresetSelectionListener.java b/src/com/jsyn/swing/PresetSelectionListener.java
deleted file mode 100644
index daf0310..0000000
--- a/src/com/jsyn/swing/PresetSelectionListener.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright 2009 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.swing;
-
-import com.jsyn.util.VoiceDescription;
-
-public interface PresetSelectionListener {
- public void presetSelected(VoiceDescription voiceDescription, int presetIndex);
-}
diff --git a/src/com/jsyn/swing/RotaryController.java b/src/com/jsyn/swing/RotaryController.java
deleted file mode 100644
index c26c37f..0000000
--- a/src/com/jsyn/swing/RotaryController.java
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * Copyright 2010 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.swing;
-
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.RenderingHints;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseMotionAdapter;
-
-import javax.swing.BoundedRangeModel;
-import javax.swing.JPanel;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
-
-/**
- * Rotary controller looks like a knob on a synthesizer. You control this knob by clicking on it and
- * dragging <b>up</b> or <b>down</b>. If you move the mouse to the <b>left</b> of the knob then you
- * will have <b>coarse</b> control. If you move the mouse to the <b>right</b> of the knob then you
- * will have <b>fine</b> control.
- * <P>
- *
- * @author (C) 2010 Phil Burk, Mobileer Inc
- * @version 16.1
- */
-public class RotaryController extends JPanel {
- private static final long serialVersionUID = 6681532871556659546L;
- private static final double SENSITIVITY = 0.01;
- private final BoundedRangeModel model;
-
- private final double minAngle = 1.4 * Math.PI;
- private final double maxAngle = -0.4 * Math.PI;
- private final double unitIncrement = 0.01;
- private int lastY;
- private int startX;
- private Color knobColor = Color.LIGHT_GRAY;
- private Color lineColor = Color.RED;
- private double baseValue;
-
- public enum Style {
- LINE, LINEDOT, ARROW, ARC
- };
-
- private Style style = Style.ARC;
-
- public RotaryController(BoundedRangeModel model) {
- this.model = model;
- setMinimumSize(new Dimension(50, 50));
- setPreferredSize(new Dimension(50, 50));
- addMouseListener(new MouseHandler());
- addMouseMotionListener(new MouseMotionHandler());
- model.addChangeListener(new ChangeListener() {
- @Override
- public void stateChanged(ChangeEvent e) {
- safeRepaint();
- }
-
- });
- }
-
- // This can be overridden in subclasses to workaround OpenJDK bugs.
- public void safeRepaint() {
- repaint();
- }
-
- public BoundedRangeModel getModel() {
- return model;
- }
-
- private class MouseHandler extends MouseAdapter {
-
- @Override
- public void mousePressed(MouseEvent e) {
- lastY = e.getY();
- startX = e.getX();
- }
-
- @Override
- public void mouseReleased(MouseEvent e) {
- if (isEnabled()) {
- setKnobByXY(e.getX(), e.getY());
- }
- }
- }
-
- private class MouseMotionHandler extends MouseMotionAdapter {
- @Override
- public void mouseDragged(MouseEvent e) {
- if (isEnabled()) {
- setKnobByXY(e.getX(), e.getY());
- }
- }
- }
-
- private int getModelRange() {
- return (((model.getMaximum() - model.getExtent()) - model.getMinimum()));
- }
-
- /**
- * A fractional value is useful for drawing.
- *
- * @return model value as a normalized fraction between 0.0 and 1.0
- */
- public double getFractionFromModel() {
- double value = model.getValue();
- return convertValueToFraction(value);
- }
-
- private double convertValueToFraction(double value) {
- return (value - model.getMinimum()) / getModelRange();
- }
-
- private void setKnobByXY(int x, int y) {
- // Scale increment by X position.
- int xdiff = startX - x; // More to left causes bigger increments.
- double power = xdiff * SENSITIVITY;
- double perPixel = unitIncrement * Math.pow(2.0, power);
-
- int ydiff = lastY - y;
- double fractionalDelta = ydiff * perPixel;
- // Only update the model if we actually change values.
- // This is needed in case the range is small.
- int valueDelta = (int) Math.round(fractionalDelta * getModelRange());
- if (valueDelta != 0) {
- model.setValue(model.getValue() + valueDelta);
- lastY = y;
- }
- }
-
- private double fractionToAngle(double fraction) {
- return (fraction * (maxAngle - minAngle)) + minAngle;
- }
-
- private void drawLineIndicator(Graphics g, int x, int y, int radius, double angle,
- boolean drawDot) {
- double arrowSize = radius * 0.95;
- int arrowX = (int) (arrowSize * Math.sin(angle));
- int arrowY = (int) (arrowSize * Math.cos(angle));
- g.setColor(lineColor);
- g.drawLine(x, y, x + arrowX, y - arrowY);
- if (drawDot) {
- // draw little dot at end
- double dotScale = 0.1;
- int dotRadius = (int) (dotScale * arrowSize);
- if (dotRadius > 1) {
- int dotX = x + (int) ((0.99 - dotScale) * arrowX) - dotRadius;
- int dotY = y - (int) ((0.99 - dotScale) * arrowY) - dotRadius;
- g.fillOval(dotX, dotY, dotRadius * 2, dotRadius * 2);
- }
- }
- }
-
- private void drawArrowIndicator(Graphics g, int x0, int y0, int radius, double angle) {
- int arrowSize = (int) (radius * 0.95);
- int arrowWidth = (int) (radius * 0.2);
- int xp[] = {
- 0, arrowWidth, 0, -arrowWidth
- };
- int yp[] = {
- arrowSize, -arrowSize / 2, 0, -arrowSize / 2
- };
- double sa = Math.sin(angle);
- double ca = Math.cos(angle);
- for (int i = 0; i < xp.length; i++) {
- int x = xp[i];
- int y = yp[i];
- xp[i] = x0 - (int) ((x * ca) - (y * sa));
- yp[i] = y0 - (int) ((x * sa) + (y * ca));
- }
- g.fillPolygon(xp, yp, xp.length);
- }
-
- private void drawArcIndicator(Graphics g, int x, int y, int radius, double angle) {
- final double DEGREES_PER_RADIAN = 180.0 / Math.PI;
- final int minAngleDegrees = (int) (minAngle * DEGREES_PER_RADIAN);
- final int maxAngleDegrees = (int) (maxAngle * DEGREES_PER_RADIAN);
-
- int zeroAngleDegrees = (int) (fractionToAngle(baseValue) * DEGREES_PER_RADIAN);
-
- double arrowSize = radius * 0.95;
- int arcX = x - radius;
- int arcY = y - radius;
- int arcAngle = (int) (angle * DEGREES_PER_RADIAN);
- int arrowX = (int) (arrowSize * Math.cos(angle));
- int arrowY = (int) (arrowSize * Math.sin(angle));
-
- g.setColor(knobColor.darker().darker());
- g.fillArc(arcX, arcY, 2 * radius, 2 * radius, minAngleDegrees, maxAngleDegrees
- - minAngleDegrees);
- g.setColor(Color.ORANGE);
- g.fillArc(arcX, arcY, 2 * radius, 2 * radius, zeroAngleDegrees, arcAngle - zeroAngleDegrees);
-
- // fill in middle
- int arcWidth = radius / 4;
- int diameter = ((radius - arcWidth) * 2);
- g.setColor(knobColor);
- g.fillOval(arcWidth + x - radius, arcWidth + y - radius, diameter, diameter);
-
- g.setColor(lineColor);
- g.drawLine(x, y, x + arrowX, y - arrowY);
-
- }
-
- /**
- * Override this method if you want to draw your own line or dot on the knob.
- */
- public void drawIndicator(Graphics g, int x, int y, int radius, double angle) {
- g.setColor(isEnabled() ? lineColor : lineColor.darker());
- switch (style) {
- case LINE:
- drawLineIndicator(g, x, y, radius, angle, false);
- break;
- case LINEDOT:
- drawLineIndicator(g, x, y, radius, angle, true);
- break;
- case ARROW:
- drawArrowIndicator(g, x, y, radius, angle);
- break;
- case ARC:
- drawArcIndicator(g, x, y, radius, angle);
- break;
- }
- }
-
- /**
- * Override this method if you want to draw your own knob.
- *
- * @param g graphics context
- * @param x position of center of knob
- * @param y position of center of knob
- * @param radius of knob in pixels
- * @param angle in radians. Zero is straight up.
- */
- public void drawKnob(Graphics g, int x, int y, int radius, double angle) {
- Graphics2D g2 = (Graphics2D) g;
- g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
-
- int diameter = radius * 2;
- // Draw shaded side.
- g.setColor(knobColor.darker());
- g.fillOval(x - radius + 2, y - radius + 2, diameter, diameter);
- g.setColor(knobColor);
- g.fillOval(x - radius, y - radius, diameter, diameter);
-
- // Draw line or other indicator of knob position.
- drawIndicator(g, x, y, radius, angle);
- }
-
- // Draw the round knob based on the current size and model value.
- // This used to have a bug where the scope would draw in this components background.
- // Then I changed it from overriding paint() to overriding paintComponent() and it worked.
- @Override
- public void paintComponent(Graphics g) {
- super.paintComponent(g);
-
- int width = getWidth();
- int height = getHeight();
- int x = width / 2;
- int y = height / 2;
-
- // Calculate radius from size of component.
- int diameter = (width < height) ? width : height;
- diameter -= 4;
- int radius = diameter / 2;
-
- double angle = fractionToAngle(getFractionFromModel());
- drawKnob(g, x, y, radius, angle);
- }
-
- public Color getKnobColor() {
- return knobColor;
- }
-
- /**
- * @param knobColor color of body of knob
- */
- public void setKnobColor(Color knobColor) {
- this.knobColor = knobColor;
- }
-
- public Color getLineColor() {
- return lineColor;
- }
-
- /**
- * @param lineColor color of indicator on knob like a line or arrow
- */
- public void setLineColor(Color lineColor) {
- this.lineColor = lineColor;
- }
-
- public void setStyle(Style style) {
- this.style = style;
- }
-
- public Style getStyle() {
- return style;
- }
-
- public double getBaseValue() {
- return baseValue;
- }
-
- /*
- * Specify where the orange arc originates. For example a pan knob with a centered arc would
- * have a baseValue of 0.5.
- * @param baseValue a fraction between 0.0 and 1.0.
- */
- public void setBaseValue(double baseValue) {
- if (baseValue < 0.0) {
- baseValue = 0.0;
- } else if (baseValue > 1.0) {
- baseValue = 1.0;
- }
- this.baseValue = baseValue;
- }
-
-}
diff --git a/src/com/jsyn/swing/RotaryTextController.java b/src/com/jsyn/swing/RotaryTextController.java
deleted file mode 100644
index 81d6614..0000000
--- a/src/com/jsyn/swing/RotaryTextController.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2010 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.swing;
-
-import java.awt.BorderLayout;
-
-import javax.swing.BorderFactory;
-import javax.swing.JPanel;
-
-/**
- * Combine a RotaryController and a DoubleBoundedTextField into a convenient package.
- *
- * @author Phil Burk (C) 2010 Mobileer Inc
- */
-public class RotaryTextController extends JPanel {
- private static final long serialVersionUID = -2931828326251895375L;
- private RotaryController rotary;
- private DoubleBoundedTextField textField;
-
- public RotaryTextController(DoubleBoundedRangeModel pModel, int numDigits) {
- rotary = new RotaryController(pModel);
- textField = new DoubleBoundedTextField(pModel, numDigits);
- setLayout(new BorderLayout());
- add(rotary, BorderLayout.CENTER);
- add(textField, BorderLayout.SOUTH);
- }
-
- /** Display the title in a border. */
- public void setTitle(String label) {
- setBorder(BorderFactory.createTitledBorder(label));
- }
-
- @Override
- public void setEnabled(boolean enabled) {
- super.setEnabled(enabled);
- rotary.setEnabled(enabled);
- textField.setEnabled(enabled);
- }
-}
diff --git a/src/com/jsyn/swing/SoundTweaker.java b/src/com/jsyn/swing/SoundTweaker.java
deleted file mode 100644
index 043677e..0000000
--- a/src/com/jsyn/swing/SoundTweaker.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright 2009 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.swing;
-
-import java.awt.Component;
-import java.awt.GridLayout;
-import java.util.ArrayList;
-import java.util.logging.Logger;
-
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-
-import com.jsyn.Synthesizer;
-import com.jsyn.ports.UnitInputPort;
-import com.jsyn.ports.UnitPort;
-import com.jsyn.unitgen.UnitGenerator;
-import com.jsyn.unitgen.UnitSource;
-import com.jsyn.unitgen.UnitVoice;
-import com.jsyn.util.Instrument;
-import com.softsynth.math.AudioMath;
-
-@SuppressWarnings("serial")
-public class SoundTweaker extends JPanel {
- private UnitSource source;
- private ASCIIMusicKeyboard keyboard;
- private Synthesizer synth;
-
- static Logger logger = Logger.getLogger(SoundTweaker.class.getName());
-
- public SoundTweaker(Synthesizer synth, String title, UnitSource source) {
- this.synth = synth;
- this.source = source;
-
- setLayout(new GridLayout(0, 2));
-
- UnitGenerator ugen = source.getUnitGenerator();
- ArrayList<Component> sliders = new ArrayList<Component>();
-
- add(new JLabel(title));
-
- if (source instanceof Instrument) {
- add(keyboard = createPolyphonicKeyboard());
- } else if (source instanceof UnitVoice) {
- add(keyboard = createMonophonicKeyboard());
- }
-
- // Arrange the faders in a stack.
- // Iterate through the ports.
- for (UnitPort port : ugen.getPorts()) {
- if (port instanceof UnitInputPort) {
- UnitInputPort inputPort = (UnitInputPort) port;
- Component slider;
- // Use an exponential slider if it seems appropriate.
- if ((inputPort.getMinimum() > 0.0)
- && ((inputPort.getMaximum() / inputPort.getMinimum()) > 4.0)) {
- slider = PortControllerFactory.createExponentialPortSlider(inputPort);
- } else {
- slider = PortControllerFactory.createPortSlider(inputPort);
-
- }
- add(slider);
- sliders.add(slider);
- }
- }
-
- if (keyboard != null) {
- for (Component slider : sliders) {
- slider.addKeyListener(keyboard.getKeyListener());
- }
- }
- validate();
- }
-
- @SuppressWarnings("serial")
- private ASCIIMusicKeyboard createPolyphonicKeyboard() {
- ASCIIMusicKeyboard keyboard = new ASCIIMusicKeyboard() {
- @Override
- public void keyOff(int pitch) {
- ((Instrument) source).noteOff(pitch, synth.createTimeStamp());
- }
-
- @Override
- public void keyOn(int pitch) {
- double freq = AudioMath.pitchToFrequency(pitch);
- ((Instrument) source).noteOn(pitch, freq, 0.5, synth.createTimeStamp());
- }
- };
- return keyboard;
- }
-
- @SuppressWarnings("serial")
- private ASCIIMusicKeyboard createMonophonicKeyboard() {
- ASCIIMusicKeyboard keyboard = new ASCIIMusicKeyboard() {
- @Override
- public void keyOff(int pitch) {
- ((UnitVoice) source).noteOff(synth.createTimeStamp());
- }
-
- @Override
- public void keyOn(int pitch) {
- double freq = AudioMath.pitchToFrequency(pitch);
- ((UnitVoice) source).noteOn(freq, 0.5, synth.createTimeStamp());
- }
- };
- return keyboard;
- }
-
-}
diff --git a/src/com/jsyn/swing/XYController.java b/src/com/jsyn/swing/XYController.java
deleted file mode 100644
index 0d97c62..0000000
--- a/src/com/jsyn/swing/XYController.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * 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.swing;
-
-import javax.swing.JPanel;
-
-/**
- * Root class for 2 dimensional X,Y controller for wave editors, Theremins, etc. Maps pixel
- * coordinates into "world" coordinates.
- *
- * @author (C) 1997 Phil Burk, SoftSynth.com
- */
-
-public class XYController extends JPanel {
- double minWorldX = 0.0;
- double maxWorldX = 1.0;
- double minWorldY = 0.0;
- double maxWorldY = 1.0;
-
- public XYController() {
- }
-
- public XYController(double minWX, double minWY, double maxWX, double maxWY) {
- setMinWorldX(minWX);
- setMaxWorldX(maxWX);
- setMinWorldY(minWY);
- setMaxWorldY(maxWY);
- }
-
- /**
- * Set minimum World coordinate value for the horizontal X dimension. The minimum value
- * corresponds to the left of the component.
- */
- public void setMinWorldX(double minWX) {
- minWorldX = minWX;
- }
-
- public double getMinWorldX() {
- return minWorldX;
- }
-
- /**
- * Set maximum World coordinate value for the horizontal X dimension. The minimum value
- * corresponds to the right of the component.
- */
- public void setMaxWorldX(double maxWX) {
- maxWorldX = maxWX;
- }
-
- public double getMaxWorldX() {
- return maxWorldX;
- }
-
- /**
- * Set minimum World coordinate value for the vertical Y dimension. The minimum value
- * corresponds to the bottom of the component.
- */
- public void setMinWorldY(double minWY) {
- minWorldY = minWY;
- }
-
- public double getMinWorldY() {
- return minWorldY;
- }
-
- /**
- * Set maximum World coordinate value for the vertical Y dimension. The maximum value
- * corresponds to the top of the component.
- */
- public void setMaxWorldY(double maxWY) {
- maxWorldY = maxWY;
- }
-
- public double getMaxWorldY() {
- return maxWorldY;
- }
-
- /** Convert from graphics coordinates (pixels) to world coordinates. */
- public double convertGXtoWX(int gx) {
- int width = getWidth();
- return minWorldX + ((maxWorldX - minWorldX) * gx) / width;
- }
-
- public double convertGYtoWY(int gy) {
- int height = getHeight();
- return minWorldY + ((maxWorldY - minWorldY) * (height - gy)) / height;
- }
-
- /** Convert from world coordinates to graphics coordinates (pixels). */
- public int convertWXtoGX(double wx) {
- int width = getWidth();
- return (int) (((wx - minWorldX) * width) / (maxWorldX - minWorldX));
- }
-
- public int convertWYtoGY(double wy) {
- int height = getHeight();
- return height - (int) (((wy - minWorldY) * height) / (maxWorldY - minWorldY));
- }
-
- /** Clip wx to the min and max World X values. */
- public double clipWorldX(double wx) {
- if (wx < minWorldX)
- wx = minWorldX;
- else if (wx > maxWorldX)
- wx = maxWorldX;
- return wx;
- }
-
- /** Clip wy to the min and max World Y values. */
- public double clipWorldY(double wy) {
- if (wy < minWorldY)
- wy = minWorldY;
- else if (wy > maxWorldY)
- wy = maxWorldY;
- return wy;
- }
-
-}
diff --git a/src/com/jsyn/unitgen/Add.java b/src/com/jsyn/unitgen/Add.java
deleted file mode 100644
index 5a2a24c..0000000
--- a/src/com/jsyn/unitgen/Add.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2009 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;
-
-/**
- * This unit performs a signed addition on its two inputs. <br>
- *
- * <pre>
- * output = inputA + inputB
- * </pre>
- *
- * <br>
- * Note that signals connected to an InputPort are automatically added together so you may not need
- * this unit.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- * @version 016
- * @see MultiplyAdd
- * @see Subtract
- */
-public class Add extends UnitBinaryOperator {
-
- @Override
- public void generate(int start, int limit) {
- double[] aValues = inputA.getValues();
- double[] bValues = inputB.getValues();
- double[] outputs = output.getValues();
-
- // System.out.println("adder = " + this);
- // System.out.println("A = " + aValues[0]);
- for (int i = start; i < limit; i++) {
- outputs[i] = aValues[i] + bValues[i];
- }
- // System.out.println("add out = " + outputs[0]);
- }
-}
diff --git a/src/com/jsyn/unitgen/AsymptoticRamp.java b/src/com/jsyn/unitgen/AsymptoticRamp.java
deleted file mode 100644
index 8b51294..0000000
--- a/src/com/jsyn/unitgen/AsymptoticRamp.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright 2009 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;
-import com.jsyn.ports.UnitVariablePort;
-
-/**
- * Output approaches Input exponentially. This unit provides a slowly changing value that approaches
- * its Input value exponentially. The equation is:
- *
- * <PRE>
- * Output = Output + Rate * (Input - Output);
- * </PRE>
- *
- * Note that the output may never reach the value of the input. It approaches the input
- * asymptotically. The Rate is calculated internally based on the value on the halfLife port. Rate
- * is generally just slightly less than 1.0.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- * @version 016
- * @see LinearRamp
- * @see ExponentialRamp
- * @see ContinuousRamp
- */
-public class AsymptoticRamp extends UnitFilter {
- public UnitVariablePort current;
- public UnitInputPort halfLife;
- private double previousHalfLife = -1.0;
- private double decayScalar = 0.99;
-
- /* Define Unit Ports used by connect() and set(). */
- public AsymptoticRamp() {
- addPort(halfLife = new UnitInputPort(1, "HalfLife", 0.1));
- addPort(current = new UnitVariablePort("Current"));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] outputs = output.getValues();
- double[] inputs = input.getValues();
- double currentHalfLife = halfLife.getValues()[0];
- double currentValue = current.getValue();
- double inputValue = currentValue;
-
- if (currentHalfLife != previousHalfLife) {
- decayScalar = this.convertHalfLifeToMultiplier(currentHalfLife);
- previousHalfLife = currentHalfLife;
- }
-
- for (int i = start; i < limit; i++) {
- inputValue = inputs[i];
- currentValue = currentValue + decayScalar * (inputValue - currentValue);
- outputs[i] = currentValue;
- }
-
- /*
- * When current gets close to input, set current to input to prevent FP underflow, which can
- * cause a severe performance degradation in 'C'.
- */
- if (Math.abs(inputValue - currentValue) < VERY_SMALL_FLOAT) {
- currentValue = inputValue;
- }
-
- current.setValue(currentValue);
- }
-}
diff --git a/src/com/jsyn/unitgen/BrownNoise.java b/src/com/jsyn/unitgen/BrownNoise.java
deleted file mode 100644
index e70b7f4..0000000
--- a/src/com/jsyn/unitgen/BrownNoise.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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;
-import com.jsyn.ports.UnitOutputPort;
-import com.jsyn.util.PseudoRandom;
-
-/**
- * BrownNoise unit. This unit uses a pseudo-random number generator to produce a noise related to
- * Brownian Motion. A DC blocker is used to prevent runaway drift.
- *
- * <pre>
- * <code>
- * output = (previous * (1.0 - damping)) + (random * amplitude)
- * </code>
- * </pre>
- *
- * The output drifts quite a bit and will generally exceed the range of +/1 amplitude.
- *
- * @author (C) 1997-2011 Phil Burk, Mobileer Inc
- * @see WhiteNoise
- * @see RedNoise
- * @see PinkNoise
- */
-public class BrownNoise extends UnitGenerator implements UnitSource {
- private PseudoRandom randomNum;
- /** Increasing the damping will effectively increase the cutoff
- * frequency of a high pass filter that is used to block DC bias.
- * Warning: setting this too close to zero can result in very large output values.
- */
- public UnitInputPort damping;
- public UnitInputPort amplitude;
- public UnitOutputPort output;
- private double previous;
-
- public BrownNoise() {
- randomNum = new PseudoRandom();
- addPort(damping = new UnitInputPort("Damping"));
- damping.setup(0.0001, 0.01, 0.1);
- addPort(amplitude = new UnitInputPort("Amplitude", UnitOscillator.DEFAULT_AMPLITUDE));
- addPort(output = new UnitOutputPort("Output"));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] amplitudes = amplitude.getValues();
- double[] outputs = output.getValues();
- double damper = 1.0 - damping.getValues()[0];
-
- for (int i = start; i < limit; i++) {
- double r = randomNum.nextRandomDouble() * amplitudes[i];
- outputs[i] = previous = (damper * previous) + r;
- }
- }
-
- @Override
- public UnitOutputPort getOutput() {
- return output;
- }
-}
diff --git a/src/com/jsyn/unitgen/ChannelIn.java b/src/com/jsyn/unitgen/ChannelIn.java
deleted file mode 100644
index c440b4f..0000000
--- a/src/com/jsyn/unitgen/ChannelIn.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2009 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.UnitOutputPort;
-
-/**
- * Provides access to one specific channel of the audio input. For ChannelIn to work you must call
- * the {@link com.jsyn.Synthesizer} start() method with numInputChannels &gt; 0.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- * @see ChannelOut
- * @see LineIn
- */
-public class ChannelIn extends UnitGenerator {
- public UnitOutputPort output;
- private int channelIndex;
-
- public ChannelIn() {
- this(0);
- }
-
- public ChannelIn(int channelIndex) {
- addPort(output = new UnitOutputPort());
- setChannelIndex(channelIndex);
- }
-
- public int getChannelIndex() {
- return channelIndex;
- }
-
- public void setChannelIndex(int channelIndex) {
- this.channelIndex = channelIndex;
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] outputs = output.getValues(0);
- double[] buffer = synthesisEngine.getInputBuffer(channelIndex);
- for (int i = start; i < limit; i++) {
- outputs[i] = buffer[i];
- }
- }
-
-}
diff --git a/src/com/jsyn/unitgen/ChannelOut.java b/src/com/jsyn/unitgen/ChannelOut.java
deleted file mode 100644
index 8ef0677..0000000
--- a/src/com/jsyn/unitgen/ChannelOut.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 2009 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;
-
-/**
- * Provides access to one channel of the audio output.
- * For more than two channels you must call
- * the {@link com.jsyn.Synthesizer} start() method with numOutputChannels &gt; 2.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- * @see ChannelIn
- */
-public class ChannelOut extends UnitGenerator {
- public UnitInputPort input;
- private int channelIndex;
-
- public ChannelOut() {
- addPort(input = new UnitInputPort("Input"));
- }
-
- public int getChannelIndex() {
- return channelIndex;
- }
-
- public void setChannelIndex(int channelIndex) {
- this.channelIndex = channelIndex;
- }
-
- /**
- * This unit won't do anything unless you start() it.
- */
- @Override
- public boolean isStartRequired() {
- return true;
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] inputs = input.getValues(0);
- double[] buffer = synthesisEngine.getOutputBuffer(channelIndex);
- for (int i = start; i < limit; i++) {
- buffer[i] += inputs[i];
- }
- }
-
-}
diff --git a/src/com/jsyn/unitgen/Circuit.java b/src/com/jsyn/unitgen/Circuit.java
deleted file mode 100644
index 01cb860..0000000
--- a/src/com/jsyn/unitgen/Circuit.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright 2009 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 java.util.ArrayList;
-import java.util.LinkedHashMap;
-
-import com.jsyn.engine.SynthesisEngine;
-import com.jsyn.ports.UnitPort;
-
-/**
- * Contains a list of units that are executed together.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public class Circuit extends UnitGenerator {
- private ArrayList<UnitGenerator> units = new ArrayList<UnitGenerator>();
-
- private final LinkedHashMap<String, UnitPort> portAliases = new LinkedHashMap<String, UnitPort>();
-
- @Override
- public void generate(int start, int limit) {
- for (UnitGenerator unit : units) {
- unit.generate(start, limit);
- }
- }
-
- /**
- * Call flattenOutputs on subunits. Flatten output ports so we don't output a changing signal
- * when stopped.
- */
- @Override
- public void flattenOutputs() {
- for (UnitGenerator unit : units) {
- unit.flattenOutputs();
- }
- }
-
- /**
- * Call setEnabled on subunits.
- */
- @Override
- public void setEnabled(boolean enabled) {
- super.setEnabled(enabled);
- for (UnitGenerator unit : units) {
- unit.setEnabled(enabled);
- }
- }
-
- /**
- * @deprecated ignored, frameRate comes from the SynthesisEngine
- * @param frameRate
- */
- @Deprecated
- @Override
- public void setFrameRate(int frameRate) {
- super.setFrameRate(frameRate);
- for (UnitGenerator unit : units) {
- unit.setFrameRate(frameRate);
- }
- }
-
- @Override
- public void setSynthesisEngine(SynthesisEngine engine) {
- super.setSynthesisEngine(engine);
- for (UnitGenerator unit : units) {
- unit.setSynthesisEngine(engine);
- }
- }
-
- /** Add a unit to the circuit. */
- public void add(UnitGenerator unit) {
- units.add(unit);
- unit.setCircuit(this);
- // Propagate circuit properties down into subunits.
- unit.setEnabled(isEnabled());
- }
-
- public void usePreset(int presetIndex) {
- }
-
-
- /**
- * Add an alternate name for looking up a port.
- * @param port
- * @param alias
- */
- public void addPortAlias(UnitPort port, String alias) {
- // Store in a hash table by an alternate name.
- portAliases.put(alias.toLowerCase(), port);
- }
-
-
- /**
- * Case-insensitive search for a port by its name or alias.
- * @param portName
- * @return matching port or null
- */
- @Override
- public UnitPort getPortByName(String portName) {
- UnitPort port = super.getPortByName(portName);
- if (port == null) {
- port = portAliases.get(portName.toLowerCase());
- }
- return port;
- }
-
-}
diff --git a/src/com/jsyn/unitgen/Compare.java b/src/com/jsyn/unitgen/Compare.java
deleted file mode 100644
index 7de2e53..0000000
--- a/src/com/jsyn/unitgen/Compare.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2009 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;
-
-/**
- *
- Output 1.0 if inputA &gt; inputB. Otherwise output 0.0.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- * @version 016
- * @see Maximum
- */
-public class Compare extends UnitBinaryOperator {
- @Override
- public void generate(int start, int limit) {
- double[] aValues = inputA.getValues();
- double[] bValues = inputB.getValues();
- double[] outputs = output.getValues();
-
- for (int i = start; i < limit; i++) {
- outputs[i] = (aValues[i] > bValues[i]) ? 1.0 : 0.0;
- }
- }
-}
diff --git a/src/com/jsyn/unitgen/ContinuousRamp.java b/src/com/jsyn/unitgen/ContinuousRamp.java
deleted file mode 100644
index dd90445..0000000
--- a/src/com/jsyn/unitgen/ContinuousRamp.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright 2009 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;
-import com.jsyn.ports.UnitVariablePort;
-
-/**
- * A ramp whose function over time is continuous in value and in slope. Also called an "S curve".
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- * @version 016
- * @see LinearRamp
- * @see ExponentialRamp
- * @see AsymptoticRamp
- */
-public class ContinuousRamp extends UnitFilter {
- public UnitVariablePort current;
- /**
- * Time it takes to get from current value to input value when input is changed. Default value
- * is 1.0 seconds.
- */
- public UnitInputPort time;
- private double previousInput = Double.MIN_VALUE;
- // Coefficients for cubic polynomial.
- private double a;
- private double b;
- private double d;
- private int framesLeft;
-
- /* Define Unit Ports used by connect() and set(). */
- public ContinuousRamp() {
- addPort(time = new UnitInputPort(1, "Time", 1.0));
- addPort(current = new UnitVariablePort("Current"));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] outputs = output.getValues();
- double[] inputs = input.getValues();
- double currentTime = time.getValues()[0];
- double currentValue = current.getValue();
- double inputValue = currentValue;
-
- for (int i = start; i < limit; i++) {
- inputValue = inputs[i];
- double x;
- if (inputValue != previousInput) {
- x = framesLeft;
- // Calculate coefficients.
- double currentSlope = x * ((3 * a * x) + (2 * b));
-
- framesLeft = (int) (getSynthesisEngine().getFrameRate() * currentTime);
- if (framesLeft < 1) {
- framesLeft = 1;
- }
- x = framesLeft;
- // Calculate coefficients.
- d = inputValue;
- double xsq = x * x;
- b = ((3 * currentValue) - (currentSlope * x) - (3 * d)) / xsq;
- a = (currentSlope - (2 * b * x)) / (3 * xsq);
- previousInput = inputValue;
- }
-
- if (framesLeft > 0) {
- x = --framesLeft;
- // Cubic polynomial. c==0
- currentValue = (x * (x * ((x * a) + b))) + d;
- }
-
- outputs[i] = currentValue;
- }
-
- current.setValue(currentValue);
- }
-}
diff --git a/src/com/jsyn/unitgen/CrossFade.java b/src/com/jsyn/unitgen/CrossFade.java
deleted file mode 100644
index 4375fa6..0000000
--- a/src/com/jsyn/unitgen/CrossFade.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2009 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;
-import com.jsyn.ports.UnitOutputPort;
-
-/**
- * Linear CrossFade between parts of the input.
- * <P>
- * Mix input[0] and input[1] based on the value of "fade". When fade is -1, output is all input[0].
- * When fade is 0, output is half input[0] and half input[1]. When fade is +1, output is all
- * input[1].
- * <P>
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- * @version 016
- * @see Pan
- */
-public class CrossFade extends UnitGenerator {
- public UnitInputPort input;
- public UnitInputPort fade;
- public UnitOutputPort output;
-
- /* Define Unit Ports used by connect() and set(). */
- public CrossFade() {
- addPort(input = new UnitInputPort(2, "Input"));
- addPort(fade = new UnitInputPort("Fade"));
- fade.setup(-1.0, 0.0, 1.0);
- addPort(output = new UnitOutputPort());
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] input0s = input.getValues(0);
- double[] input1s = input.getValues(1);
- double[] fades = fade.getValues();
- double[] outputs = output.getValues();
- for (int i = start; i < limit; i++) {
- // Scale and offset to 0.0 to 1.0 range.
- double gain = (fades[i] * 0.5) + 0.5;
- outputs[i] = (input0s[i] * (1.0 - gain)) + (input1s[i] * gain);
- }
- }
-
-}
diff --git a/src/com/jsyn/unitgen/Delay.java b/src/com/jsyn/unitgen/Delay.java
deleted file mode 100644
index aa450a9..0000000
--- a/src/com/jsyn/unitgen/Delay.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2009 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;
-
-/**
- * Simple non-interpolating delay. The delay line must be allocated by calling allocate(n).
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- * @version 016
- * @see InterpolatingDelay
- */
-
-public class Delay extends UnitFilter {
- private float[] buffer;
- private int cursor;
- private int numSamples;
-
- /**
- * Allocate an internal array for the delay line.
- *
- * @param numSamples
- */
- public void allocate(int numSamples) {
- this.numSamples = numSamples;
- buffer = new float[numSamples];
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] inputs = input.getValues();
- double[] outputs = output.getValues();
-
- for (int i = start; i < limit; i++) {
- outputs[i] = buffer[cursor];
- buffer[cursor] = (float) inputs[i];
- cursor += 1;
- if (cursor >= numSamples) {
- cursor = 0;
- }
- }
- }
-
-}
diff --git a/src/com/jsyn/unitgen/Divide.java b/src/com/jsyn/unitgen/Divide.java
deleted file mode 100644
index cddcd7c..0000000
--- a/src/com/jsyn/unitgen/Divide.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2009 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;
-
-/**
- * This unit divides its two inputs. <br>
- *
- * <pre>
- * output = inputA / inputB
- * </pre>
- *
- * <br>
- * Note that this unit is protected from dividing by zero. But you can still get some very big
- * outputs.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- * @version 016
- * @see Multiply
- * @see Subtract
- */
-public class Divide extends UnitBinaryOperator {
-
- @Override
- public void generate(int start, int limit) {
- double[] aValues = inputA.getValues();
- double[] bValues = inputB.getValues();
- double[] outputs = output.getValues();
- for (int i = start; i < limit; i++) {
- /* Prevent divide by zero crash. */
- double b = bValues[i];
- if (b == 0.0) {
- b = 0.0000001;
- }
-
- outputs[i] = aValues[i] / b;
- }
- }
-
-}
diff --git a/src/com/jsyn/unitgen/DualInTwoOut.java b/src/com/jsyn/unitgen/DualInTwoOut.java
deleted file mode 100644
index ec7dff5..0000000
--- a/src/com/jsyn/unitgen/DualInTwoOut.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2009 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;
-import com.jsyn.ports.UnitOutputPort;
-
-/**
- * This unit splits a dual (stereo) input to two discrete outputs. <br>
- *
- * <pre>
- * outputA = input[0];
- * outputB = input[1];
- * </pre>
- *
- * <br>
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- * @version 016
- */
-
-public class DualInTwoOut extends UnitGenerator {
- public UnitInputPort input;
- public UnitOutputPort outputA;
- public UnitOutputPort outputB;
-
- public DualInTwoOut() {
- addPort(input = new UnitInputPort(2, "Input"));
- addPort(outputA = new UnitOutputPort("OutputA"));
- addPort(outputB = new UnitOutputPort("OutputB"));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] input0s = input.getValues(0);
- double[] input1s = input.getValues(1);
- double[] outputAs = outputA.getValues();
- double[] outputBs = outputB.getValues();
-
- for (int i = start; i < limit; i++) {
- outputAs[i] = input0s[i];
- outputBs[i] = input1s[i];
- }
- }
-}
diff --git a/src/com/jsyn/unitgen/EdgeDetector.java b/src/com/jsyn/unitgen/EdgeDetector.java
deleted file mode 100644
index e314f7d..0000000
--- a/src/com/jsyn/unitgen/EdgeDetector.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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;
-
-/**
- * Output 1.0 if the input crosses from zero while rising. Otherwise output zero. The output is a
- * single sample wide impulse. This can be used with a Latch to implement a "sample and hold"
- * circuit.
- *
- * @author (C) 1997-2010 Phil Burk, Mobileer Inc
- * @see Latch
- */
-public class EdgeDetector extends UnitFilter {
- private double previous = 0.0;
-
- public EdgeDetector() {
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] inputs = input.getValues();
- double[] outputs = output.getValues();
-
- for (int i = start; i < limit; i++) {
- double in = inputs[i];
- outputs[i] = ((previous <= 0.0) && (in > 0.0)) ? 1.0 : 0.0;
- previous = in;
- }
- }
-}
diff --git a/src/com/jsyn/unitgen/EnvelopeAttackDecay.java b/src/com/jsyn/unitgen/EnvelopeAttackDecay.java
deleted file mode 100644
index db3ecaa..0000000
--- a/src/com/jsyn/unitgen/EnvelopeAttackDecay.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright 2011 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.engine.SynthesisEngine;
-import com.jsyn.ports.UnitInputPort;
-
-/**
- * Two stage Attack/Decay envelope that is triggered by an input level greater than THRESHOLD. This
- * does not sustain.
- *
- * @author Phil Burk (C) 2011 Mobileer Inc
- */
-public class EnvelopeAttackDecay extends UnitGate {
- public static final double THRESHOLD = 0.01;
- private static final double MIN_DURATION = (1.0 / 100000.0);
-
- /**
- * Time in seconds for the rising stage of the envelope to go from 0.0 to 1.0. The attack is a
- * linear ramp.
- */
- public UnitInputPort attack;
- /**
- * Time in seconds for the falling stage to go from 0 dB to -90 dB.
- */
- public UnitInputPort decay;
-
- public UnitInputPort amplitude;
-
- private enum State {
- IDLE, ATTACKING, DECAYING
- }
-
- private State state = State.IDLE;
- private double scaler = 1.0;
- private double level;
- private double increment;
-
- public EnvelopeAttackDecay() {
- super();
- addPort(attack = new UnitInputPort("Attack"));
- attack.setup(0.001, 0.05, 8.0);
- addPort(decay = new UnitInputPort("Decay"));
- decay.setup(0.001, 0.2, 8.0);
- addPort(amplitude = new UnitInputPort("Amplitude", 1.0));
- startIdle();
- }
-
- public void export(Circuit circuit, String prefix) {
- circuit.addPort(attack, prefix + attack.getName());
- circuit.addPort(decay, prefix + decay.getName());
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] amplitudes = amplitude.getValues();
- double[] outputs = output.getValues();
-
- for (int i = start; i < limit;) {
- boolean triggered = input.checkGate(i);
- switch (state) {
- case IDLE:
- for (; i < limit; i++) {
- outputs[i] = level;
- if (triggered) {
- startAttack(i);
- break;
- }
- }
- break;
- case ATTACKING:
- for (; i < limit; i++) {
- // Increment first so we can render fast attacks.
- level += increment;
- if (level >= 1.0) {
- level = 1.0;
- outputs[i] = level * amplitudes[i];
- startDecay(i);
- break;
- }
- outputs[i] = level * amplitudes[i];
- }
- break;
- case DECAYING:
- for (; i < limit; i++) {
- outputs[i] = level * amplitudes[i];
- level *= scaler;
- if (triggered) {
- startAttack(i);
- break;
- } else if (level < SynthesisEngine.DB90) {
- input.checkAutoDisable();
- startIdle();
- break;
- }
- }
- break;
- }
- }
- }
-
- private void startIdle() {
- state = State.IDLE;
- level = 0.0;
- }
-
- private void startAttack(int i) {
- double[] attacks = attack.getValues();
- double duration = attacks[i];
- if (duration < MIN_DURATION) {
- level = 1.0;
- startDecay(i);
- } else {
- // assume going from 0.0 to 1.0 even if retriggering
- increment = getFramePeriod() / duration;
- state = State.ATTACKING;
- }
- }
-
- private void startDecay(int i) {
- double[] decays = decay.getValues();
- double duration = decays[i];
- if (duration < MIN_DURATION) {
- startIdle();
- } else {
- scaler = getSynthesisEngine().convertTimeToExponentialScaler(duration);
- state = State.DECAYING;
- }
- }
-
-}
diff --git a/src/com/jsyn/unitgen/EnvelopeDAHDSR.java b/src/com/jsyn/unitgen/EnvelopeDAHDSR.java
deleted file mode 100644
index c5ebe83..0000000
--- a/src/com/jsyn/unitgen/EnvelopeDAHDSR.java
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * Copyright 2010 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.data.SegmentedEnvelope;
-import com.jsyn.engine.SynthesisEngine;
-import com.jsyn.ports.UnitInputPort;
-import com.jsyn.ports.UnitOutputPort;
-
-/**
- * Six stage envelope similar to an ADSR. DAHDSR is like an ADSR but with an additional Delay stage
- * before the attack, and a Hold stage after the Attack. If Delay and Hold are both set to zero then
- * it will act like an ADSR. The envelope is triggered when the input goes above THRESHOLD. The
- * envelope is released when the input goes below THRESHOLD. The THRESHOLD is currently 0.01 but may
- * change so it would be best to use an input signal that went from 0 to 1. Mathematically an
- * exponential Release will never reach 0.0. But when it reaches -96 dB the DAHDSR just sets its
- * output to 0.0 and stops. There is an example program in the ZIP archive called HearDAHDSR. It
- * drives a DAHDSR with a square wave.
- *
- * @author Phil Burk (C) 2010 Mobileer Inc
- * @see SegmentedEnvelope
- */
-public class EnvelopeDAHDSR extends UnitGate implements UnitSource {
- private static final double MIN_DURATION = (1.0 / 100000.0);
-
- /**
- * Time in seconds for first stage of the envelope, before the attack. Typically zero.
- */
- public UnitInputPort delay;
- /**
- * Time in seconds for the rising stage of the envelope to go from 0.0 to 1.0. The attack is a
- * linear ramp.
- */
- public UnitInputPort attack;
- /** Time in seconds for the plateau between the attack and decay stages. */
- public UnitInputPort hold;
- /**
- * Time in seconds for the falling stage to go from 0 dB to -90 dB. The decay stage will stop at
- * the sustain level. But we calculate the time to fall to -90 dB so that the decay
- * <em>rate</em> will be unaffected by the sustain level.
- */
- public UnitInputPort decay;
- /**
- * Level for the sustain stage. The envelope will hold here until the input goes to zero or
- * less. This should be set between 0.0 and 1.0.
- */
- public UnitInputPort sustain;
- /**
- * Time in seconds to go from 0 dB to -90 dB. This stage is triggered when the input goes to
- * zero or less. The release stage will start from the sustain level. But we calculate the time
- * to fall from full amplitude so that the release <em>rate</em> will be unaffected by the
- * sustain level.
- */
- public UnitInputPort release;
- public UnitInputPort amplitude;
-
- enum State {
- IDLE, DELAYING, ATTACKING, HOLDING, DECAYING, SUSTAINING, RELEASING
- }
-
- private State state = State.IDLE;
- private double countdown;
- private double scaler = 1.0;
- private double level;
- private double increment;
-
- public EnvelopeDAHDSR() {
- super();
- addPort(delay = new UnitInputPort("Delay", 0.0));
- delay.setup(0.0, 0.0, 2.0);
- addPort(attack = new UnitInputPort("Attack", 0.1));
- attack.setup(0.01, 0.1, 8.0);
- addPort(hold = new UnitInputPort("Hold", 0.0));
- hold.setup(0.0, 0.0, 2.0);
- addPort(decay = new UnitInputPort("Decay", 0.2));
- decay.setup(0.01, 0.2, 8.0);
- addPort(sustain = new UnitInputPort("Sustain", 0.5));
- sustain.setup(0.0, 0.5, 1.0);
- addPort(release = new UnitInputPort("Release", 0.3));
- release.setup(0.01, 0.3, 8.0);
- addPort(amplitude = new UnitInputPort("Amplitude", 1.0));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] sustains = sustain.getValues();
- double[] amplitudes = amplitude.getValues();
- double[] outputs = output.getValues();
-
- for (int i = start; i < limit;) {
- boolean triggered = input.checkGate(i);
- switch (state) {
- case IDLE:
- for (; i < limit; i++) {
- outputs[i] = level * amplitudes[i];
- if (triggered) {
- startDelay(i);
- break;
- }
- }
- break;
-
- case DELAYING:
- for (; i < limit; i++) {
- outputs[i] = level * amplitudes[i];
- if (input.isOff()) {
- startRelease(i);
- break;
- } else {
- countdown -= 1;
- if (countdown <= 0) {
- startAttack(i);
- break;
- }
- }
- }
- break;
-
- case ATTACKING:
- for (; i < limit; i++) {
- // Increment first so we can render fast attacks.
- level += increment;
- if (level >= 1.0) {
- level = 1.0;
- outputs[i] = level * amplitudes[i];
- startHold(i);
- break;
- } else {
- outputs[i] = level * amplitudes[i];
- if (input.isOff()) {
- startRelease(i);
- break;
- }
- }
- }
- break;
-
- case HOLDING:
- for (; i < limit; i++) {
- outputs[i] = amplitudes[i]; // level is 1.0
- countdown -= 1;
- if (countdown <= 0) {
- startDecay(i);
- break;
- } else if (input.isOff()) {
- startRelease(i);
- break;
- }
- }
- break;
-
- case DECAYING:
- for (; i < limit; i++) {
- outputs[i] = level * amplitudes[i];
- level *= scaler; // exponential decay
- if (triggered) {
- startDelay(i);
- break;
- } else if (level < sustains[i]) {
- level = sustains[i];
- startSustain(i);
- break;
- } else if (level < SynthesisEngine.DB96) {
- input.checkAutoDisable();
- startIdle();
- break;
- } else if (input.isOff()) {
- startRelease(i);
- break;
- }
- }
- break;
-
- case SUSTAINING:
- for (; i < limit; i++) {
- level = sustains[i];
- outputs[i] = level * amplitudes[i];
- if (triggered) {
- startDelay(i);
- break;
- } else if (input.isOff()) {
- startRelease(i);
- break;
- }
- }
- break;
-
- case RELEASING:
- for (; i < limit; i++) {
- outputs[i] = level * amplitudes[i];
- level *= scaler; // exponential decay
- if (triggered) {
- startDelay(i);
- break;
- } else if (level < SynthesisEngine.DB96) {
- input.checkAutoDisable();
- startIdle();
- break;
- }
- }
- break;
- }
- }
- }
-
- private void startIdle() {
- state = State.IDLE;
- level = 0.0;
- }
-
- private void startDelay(int i) {
- double[] delays = delay.getValues();
- if (delays[i] <= 0.0) {
- startAttack(i);
- } else {
- countdown = (int) (delays[i] * getFrameRate());
- state = State.DELAYING;
- }
- }
-
- private void startAttack(int i) {
- double[] attacks = attack.getValues();
- double duration = attacks[i];
- if (duration < MIN_DURATION) {
- level = 1.0;
- startHold(i);
- } else {
- increment = getFramePeriod() / duration;
- state = State.ATTACKING;
- }
- }
-
- private void startHold(int i) {
- double[] holds = hold.getValues();
- if (holds[i] <= 0.0) {
- startDecay(i);
- } else {
- countdown = (int) (holds[i] * getFrameRate());
- state = State.HOLDING;
- }
- }
-
- private void startDecay(int i) {
- double[] decays = decay.getValues();
- double duration = decays[i];
- if (duration < MIN_DURATION) {
- startSustain(i);
- } else {
- scaler = getSynthesisEngine().convertTimeToExponentialScaler(duration);
- state = State.DECAYING;
- }
- }
-
- private void startSustain(int i) {
- state = State.SUSTAINING;
- }
-
- private void startRelease(int i) {
- double[] releases = release.getValues();
- double duration = releases[i];
- if (duration < MIN_DURATION) {
- duration = MIN_DURATION;
- }
- scaler = getSynthesisEngine().convertTimeToExponentialScaler(duration);
- state = State.RELEASING;
- }
-
- public void export(Circuit circuit, String prefix) {
- circuit.addPort(attack, prefix + attack.getName());
- circuit.addPort(decay, prefix + decay.getName());
- circuit.addPort(sustain, prefix + sustain.getName());
- circuit.addPort(release, prefix + release.getName());
- }
-
- @Override
- public UnitOutputPort getOutput() {
- return output;
- }
-
-}
diff --git a/src/com/jsyn/unitgen/ExponentialRamp.java b/src/com/jsyn/unitgen/ExponentialRamp.java
deleted file mode 100644
index 36159b4..0000000
--- a/src/com/jsyn/unitgen/ExponentialRamp.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright 2010 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;
-import com.jsyn.ports.UnitVariablePort;
-
-/**
- * Output approaches Input exponentially and will reach it in the specified time.
- *
- * @author Phil Burk (C) 2010 Mobileer Inc
- * @version 016
- * @see LinearRamp
- * @see AsymptoticRamp
- * @see ContinuousRamp
- */
-public class ExponentialRamp extends UnitFilter {
- public UnitInputPort time;
- public UnitVariablePort current;
-
- private double target;
- private double timeHeld = 0.0;
- private double scaler = 1.0;
-
- public ExponentialRamp() {
- addPort(time = new UnitInputPort("Time"));
- input.setup(0.0001, 1.0, 1.0);
- addPort(current = new UnitVariablePort("Current", 1.0));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] outputs = output.getValues();
- double currentInput = input.getValues()[0];
- double currentTime = time.getValues()[0];
- double currentValue = current.getValue();
-
- if (currentTime != timeHeld) {
- scaler = convertTimeToExponentialScaler(currentTime, currentValue, currentInput);
- timeHeld = currentTime;
- }
-
- // If input has changed, start new segment.
- // Equality check is OK because we set them exactly equal below.
- if (currentInput != target) {
- scaler = convertTimeToExponentialScaler(currentTime, currentValue, currentInput);
- target = currentInput;
- }
-
- if (currentValue < target) {
- // Going up.
- for (int i = start; i < limit; i++) {
- currentValue = currentValue * scaler;
- if (currentValue > target) {
- currentValue = target;
- scaler = 1.0;
- }
- outputs[i] = currentValue;
- }
- } else if (currentValue > target) {
- // Going down.
- for (int i = start; i < limit; i++) {
- currentValue = currentValue * scaler;
- if (currentValue < target) {
- currentValue = target;
- scaler = 1.0;
- }
- outputs[i] = currentValue;
- }
-
- } else if (currentValue == target) {
- for (int i = start; i < limit; i++) {
- outputs[i] = target;
- }
- }
-
- current.setValue(currentValue);
- }
-
- private double convertTimeToExponentialScaler(double duration, double source, double target) {
- double product = source * target;
- if (product <= 0.0000001) {
- throw new IllegalArgumentException(
- "Exponential ramp crosses zero or gets too close to zero.");
- }
- // Calculate scaler so that scaler^frames = target/source
- double numFrames = duration * getFrameRate();
- return Math.pow((target / source), (1.0 / numFrames));
- }
-}
diff --git a/src/com/jsyn/unitgen/FFT.java b/src/com/jsyn/unitgen/FFT.java
deleted file mode 100644
index 63fce50..0000000
--- a/src/com/jsyn/unitgen/FFT.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2013 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;
-
-/**
- * Periodically transform the complex input signal using an FFT to a complex spectral stream. This
- * is probably not as useful as the SpectralFFT, which outputs complete spectra.
- *
- * @author Phil Burk (C) 2013 Mobileer Inc
- * @see IFFT
- * @see SpectralFFT
- */
-public class FFT extends FFTBase {
- public FFT() {
- super();
- }
-
- @Override
- protected int getSign() {
- return 1; // 1 for FFT
- }
-}
diff --git a/src/com/jsyn/unitgen/FFTBase.java b/src/com/jsyn/unitgen/FFTBase.java
deleted file mode 100644
index 055c04b..0000000
--- a/src/com/jsyn/unitgen/FFTBase.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright 2013 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.data.Spectrum;
-import com.jsyn.ports.UnitInputPort;
-import com.jsyn.ports.UnitOutputPort;
-import com.softsynth.math.FourierMath;
-
-/**
- * Periodically transform the complex input signal using an FFT to a complex spectral stream.
- *
- * @author Phil Burk (C) 2013 Mobileer Inc
- * @version 016
- * @see IFFT
- */
-public abstract class FFTBase extends UnitGenerator {
- public UnitInputPort inputReal;
- public UnitInputPort inputImaginary;
- public UnitOutputPort outputReal;
- public UnitOutputPort outputImaginary;
- protected double[] realInput;
- protected double[] realOutput;
- protected double[] imaginaryInput;
- protected double[] imaginaryOutput;
- protected int cursor;
-
- protected FFTBase() {
- addPort(inputReal = new UnitInputPort("InputReal"));
- addPort(inputImaginary = new UnitInputPort("InputImaginary"));
- addPort(outputReal = new UnitOutputPort("OutputReal"));
- addPort(outputImaginary = new UnitOutputPort("OutputImaginary"));
- setSize(Spectrum.DEFAULT_SIZE);
- }
-
- public void setSize(int size) {
- realInput = new double[size];
- realOutput = new double[size];
- imaginaryInput = new double[size];
- imaginaryOutput = new double[size];
- cursor = 0;
- }
-
- public int getSize() {
- return realInput.length;
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] inputRs = inputReal.getValues();
- double[] inputIs = inputImaginary.getValues();
- double[] outputRs = outputReal.getValues();
- double[] outputIs = outputImaginary.getValues();
- for (int i = start; i < limit; i++) {
- realInput[cursor] = inputRs[i];
- imaginaryInput[cursor] = inputIs[i];
- outputRs[i] = realOutput[cursor];
- outputIs[i] = imaginaryOutput[cursor];
- cursor += 1;
- // When it is full, do the FFT.
- if (cursor == realInput.length) {
- // Copy to output buffer so we can do the FFT in place.
- System.arraycopy(realInput, 0, realOutput, 0, realInput.length);
- System.arraycopy(imaginaryInput, 0, imaginaryOutput, 0, imaginaryInput.length);
- FourierMath.transform(getSign(), realOutput.length, realOutput, imaginaryOutput);
- cursor = 0;
- }
- }
- }
-
- protected abstract int getSign();
-}
diff --git a/src/com/jsyn/unitgen/FilterAllPass.java b/src/com/jsyn/unitgen/FilterAllPass.java
deleted file mode 100644
index 749b2d6..0000000
--- a/src/com/jsyn/unitgen/FilterAllPass.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 2014 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;
-
-/**
- * AllPass filter using the following formula:
- *
- * <pre>
- * y(n) = -gain * x(n) + x(n - 1) + gain * y(n - 1)
- * </pre>
- *
- * where y(n) is Output, x(n) is Input, x(n-1) is a delayed copy of the input, and y(n-1) is a
- * delayed copy of the output. An all-pass filter will pass all frequencies with equal amplitude.
- * But it changes the phase relationships of the partials by delaying them by an amount proportional
- * to their wavelength,.
- *
- * @author (C) 2014 Phil Burk, SoftSynth.com
- * @see FilterLowPass
- */
-
-public class FilterAllPass extends UnitFilter {
- /** Feedback gain. Should be less than 1.0. Default is 0.8. */
- public UnitInputPort gain;
-
- private double x1;
- private double y1;
-
- public FilterAllPass() {
- addPort(gain = new UnitInputPort("Gain", 0.8));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] inputs = input.getValues();
- double[] outputs = output.getValues();
- double g = gain.getValue();
-
- for (int i = start; i < limit; i++) {
- double x0 = inputs[i];
- y1 = (g * (y1 - x0)) + x1;
- x1 = x0;
- outputs[i] = y1;
- }
-
- }
-}
diff --git a/src/com/jsyn/unitgen/FilterBandPass.java b/src/com/jsyn/unitgen/FilterBandPass.java
deleted file mode 100644
index b103400..0000000
--- a/src/com/jsyn/unitgen/FilterBandPass.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2009 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.
- */
-/**
- * Aug 21, 2009
- * com.jsyn.engine.units.Filter_HighPass.java
- */
-
-package com.jsyn.unitgen;
-
-/**
- * Filter that allows frequencies around the center frequency to pass and blocks others. This filter
- * is based on the BiQuad filter. Coefficients are updated whenever the frequency or Q changes.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc Translated from 'C' to Java by Lisa
- * Tolentino.
- */
-public class FilterBandPass extends FilterBiquadCommon {
- /**
- * This method is by Filter_Biquad to update coefficients for the Filter_BandPass filter.
- */
- @Override
- public void updateCoefficients() {
- double scalar = 1.0 / (1.0 + alpha);
-
- a0 = alpha * scalar;
- a1 = 0.0;
- a2 = -a0;
- b1 = -2.0 * cos_omega * scalar;
- b2 = (1.0 - alpha) * scalar;
- }
-}
diff --git a/src/com/jsyn/unitgen/FilterBandStop.java b/src/com/jsyn/unitgen/FilterBandStop.java
deleted file mode 100644
index d4f5249..0000000
--- a/src/com/jsyn/unitgen/FilterBandStop.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright 2009 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;
-
-/**
- * Filter that blocks frequencies around the center frequency. This filter is based on the BiQuad
- * filter. Coefficients are updated whenever the frequency or Q changes.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc Translated from 'C' to Java by Lisa
- * Tolentino.
- */
-public class FilterBandStop extends FilterBiquadCommon {
-
- @Override
- public void updateCoefficients() {
-
- // scalar = 1.0f / (1.0f + BQCM.alpha);
- // A1_B1_Value = -2.0f * BQCM.cos_omega * scalar;
- //
- // csFilter->csFBQ_A0 = scalar;
- // csFilter->csFBQ_A1 = A1_B1_Value;
- // csFilter->csFBQ_A2 = scalar;
- // csFilter->csFBQ_B1 = A1_B1_Value;
- // csFilter->csFBQ_B2 = (1.0f - BQCM.alpha) * scalar;
-
- double scalar = 1.0 / (1.0 + alpha);
- double a1_b1_value = -2.0 * cos_omega * scalar;
-
- this.a0 = scalar;
- this.a1 = a1_b1_value;
- this.a2 = scalar;
- this.b1 = a1_b1_value;
- this.b2 = (1.0 - alpha) * scalar;
- }
-}
diff --git a/src/com/jsyn/unitgen/FilterBiquad.java b/src/com/jsyn/unitgen/FilterBiquad.java
deleted file mode 100644
index f9b792f..0000000
--- a/src/com/jsyn/unitgen/FilterBiquad.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright 2011 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;
-
-/**
- * Base class for a set of IIR filters.
- *
- * @author Phil Burk (C) 2011 Mobileer Inc
- * @see FilterBandStop
- * @see FilterBandPass
- * @see FilterLowPass
- * @see FilterHighPass
- * @see FilterTwoPolesTwoZeros
- */
-public abstract class FilterBiquad extends TunableFilter {
- public UnitInputPort amplitude;
-
- protected static final double MINIMUM_FREQUENCY = 0.00001;
- protected static final double MINIMUM_GAIN = 0.00001;
- protected static final double RATIO_MINIMUM = 0.499;
- protected double a0;
- protected double a1;
- protected double a2;
- protected double b1;
- protected double b2;
- private double x1;
- private double x2;
- private double y1;
- private double y2;
- protected double previousFrequency;
- protected double omega;
- protected double sin_omega;
- protected double cos_omega;
-
- public FilterBiquad() {
- addPort(amplitude = new UnitInputPort("Amplitude", 1.0));
- }
-
- /**
- * Generic generate(int start, int limit) method calls this filter's recalculate() and
- * performBiquadFilter(int, int) methods.
- */
- @Override
- public void generate(int start, int limit) {
- recalculate();
- performBiquadFilter(start, limit);
- }
-
- protected abstract void recalculate();
-
- /**
- * Each filter calls performBiquadFilter() through the generate(int, int) method. This method
- * has converted Robert Bristow-Johnson's coefficients for the Direct I form in this way: Here
- * is the equation that JSyn uses for this filter:
- *
- * <pre>
- * y(n) = A0*x(n) + A1*x(n-1) + A2*x(n-2) -vB1*y(n-1) - B2*y(n-2)
- * </pre>
- *
- * Here is the equation that Robert Bristow-Johnson uses:
- *
- * <pre>
- * y[n] = (b0/a0)*x[n] + (b1/a0)*x[n-1] + (b2/a0)*x[n-2] - (a1/a0)*y[n-1] - (a2/a0)*y[n-2]
- * </pre>
- *
- * So to translate between JSyn coefficients and RBJ coefficients:
- *
- * <pre>
- * JSyn =&gt; RBJ
- * A0 =&gt; b0/a0
- * A1 =&gt; b1/a0
- * A2 =&gt; b2/a0
- * B1 =&gt; a1/a0
- * B2 =&gt; a2/a0
- * </pre>
- *
- * @param start
- * @param limit
- */
- public void performBiquadFilter(int start, int limit) {
- double[] inputs = input.getValues();
- double[] amplitudes = amplitude.getValues();
- double[] outputs = output.getValues();
- double a0_jsyn, a1_jsyn, a2_jsyn, b1_jsyn, b2_jsyn;
- double x0_jsyn, x1_jsyn, x2_jsyn, y1_jsyn, y2_jsyn;
-
- x1_jsyn = this.x1;
- x2_jsyn = this.x2;
-
- y1_jsyn = this.y1;
- y2_jsyn = this.y2;
-
- a0_jsyn = this.a0;
- a1_jsyn = this.a1;
- a2_jsyn = this.a2;
-
- b1_jsyn = this.b1;
- b2_jsyn = this.b2;
-
- // Permute filter operations to reduce data movement.
- for (int i = start; i < limit; i += 2)
-
- {
- x0_jsyn = inputs[i];
- y2_jsyn = (a0_jsyn * x0_jsyn) + (a1_jsyn * x1_jsyn) + (a2_jsyn * x2_jsyn)
- - (b1_jsyn * y1_jsyn) - (b2_jsyn * y2_jsyn);
-
- outputs[i] = amplitudes[i] * y2_jsyn;
-
- x2_jsyn = inputs[i + 1];
- y1_jsyn = (a0_jsyn * x2_jsyn) + (a1_jsyn * x0_jsyn) + (a2_jsyn * x1_jsyn)
- - (b1_jsyn * y2_jsyn) - (b2_jsyn * y1_jsyn);
-
- outputs[i + 1] = amplitudes[i + 1] * y1_jsyn;
-
- x1_jsyn = x2_jsyn;
- x2_jsyn = x0_jsyn;
- }
-
- this.x1 = x1_jsyn; // save filter state for next time
- this.x2 = x2_jsyn;
-
- // apply small bipolar impulse to prevent arithmetic underflow
- this.y1 = y1_jsyn + VERY_SMALL_FLOAT;
- this.y2 = y2_jsyn - VERY_SMALL_FLOAT;
- }
-
- protected void calculateOmega(double ratio) {
- if (ratio >= FilterBiquad.RATIO_MINIMUM) // keep a minimum
- // distance from Nyquist
- {
- ratio = FilterBiquad.RATIO_MINIMUM;
- }
-
- omega = 2.0 * Math.PI * ratio;
- cos_omega = Math.cos(omega); // compute cosine
- sin_omega = Math.sin(omega); // compute sine
- }
-
-}
diff --git a/src/com/jsyn/unitgen/FilterBiquadCommon.java b/src/com/jsyn/unitgen/FilterBiquadCommon.java
deleted file mode 100644
index f21c8e7..0000000
--- a/src/com/jsyn/unitgen/FilterBiquadCommon.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright 2009 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;
-
-/**
- * Extend this class to create a filter that implements a Biquad filter with a Q port.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc Translated from 'C' to Java by Lisa
- * Tolentino.
- */
-public abstract class FilterBiquadCommon extends FilterBiquad {
- public UnitInputPort Q;
-
- protected final static double MINIMUM_Q = 0.00001;
- private double previousQ;
- protected double alpha;
-
- /**
- * No-argument constructor instantiates the Biquad common and adds a Q port to this filter.
- */
- public FilterBiquadCommon() {
- addPort(Q = new UnitInputPort("Q"));
- Q.setup(0.1, 1.0, 10.0);
- }
-
- /**
- * Calculate coefficients based on the filter type, eg. LowPass.
- */
- public abstract void updateCoefficients();
-
- public void computeBiquadCommon(double ratio, double Q) {
- if (ratio >= FilterBiquad.RATIO_MINIMUM) // keep a minimum distance
- // from Nyquist
- {
- ratio = FilterBiquad.RATIO_MINIMUM;
- }
-
- omega = 2.0 * Math.PI * ratio;
- cos_omega = Math.cos(omega); // compute cosine
- sin_omega = Math.sin(omega); // compute sine
- alpha = sin_omega / (2.0 * Q); // set alpha
- // System.out.println("Q = " + Q + ", omega = " + omega +
- // ", cos(omega) = " + cos_omega + ", alpha = " + alpha );
- }
-
- /**
- * The recalculate() method checks and ensures that the frequency and Q values are at a minimum.
- * It also only updates the Biquad coefficients if either frequency or Q have changed.
- */
- @Override
- public void recalculate() {
- double frequencyValue = frequency.getValues()[0]; // grab frequency
- // element (we'll
- // only use
- // element[0])
- double qValue = Q.getValues()[0]; // grab Q element (we'll only use
- // element[0])
-
- if (frequencyValue < MINIMUM_FREQUENCY) // ensure a minimum frequency
- {
- frequencyValue = MINIMUM_FREQUENCY;
- }
-
- if (qValue < MINIMUM_Q) // ensure a minimum Q
- {
- qValue = MINIMUM_Q;
- }
- // only update changed values
- if (isRecalculationNeeded(frequencyValue, qValue)) {
- previousFrequency = frequencyValue; // hold previous frequency
- previousQ = qValue; // hold previous Q
-
- double ratio = frequencyValue * getFramePeriod();
- computeBiquadCommon(ratio, qValue);
- updateCoefficients();
- }
- }
-
- protected boolean isRecalculationNeeded(double frequencyValue, double qValue) {
- return (frequencyValue != previousFrequency) || (qValue != previousQ);
- }
-
-}
diff --git a/src/com/jsyn/unitgen/FilterBiquadShelf.java b/src/com/jsyn/unitgen/FilterBiquadShelf.java
deleted file mode 100644
index 737d18d..0000000
--- a/src/com/jsyn/unitgen/FilterBiquadShelf.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright 2009 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;
-
-/**
- * This filter is based on the BiQuad filter and is used as a base class for FilterLowShelf and
- * FilterHighShelf. Coefficients are updated whenever the frequency, gain or slope changes.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public abstract class FilterBiquadShelf extends FilterBiquad {
- protected final static double MINIMUM_SLOPE = 0.00001;
-
- /**
- * Gain of peak. Use 1.0 for flat response.
- */
- public UnitInputPort gain;
-
- /**
- * Shelf Slope parameter. When S = 1, the shelf slope is as steep as you can get it and remain
- * monotonically increasing or decreasing gain with frequency.
- */
- public UnitInputPort slope;
-
- private double prevGain;
- private double prevSlope;
-
- private double beta;
- protected double alpha;
- protected double factorA;
- protected double AP1;
- protected double AM1;
- protected double beta_sn;
- protected double AP1cs;
- protected double AM1cs;
-
- public FilterBiquadShelf() {
- addPort(gain = new UnitInputPort("Gain", 1.0));
- addPort(slope = new UnitInputPort("Slope", 1.0));
- }
-
- /**
- * Abstract method. Each filter must implement its update of coefficients.
- */
- public abstract void updateCoefficients();
-
- /**
- * Compute coefficients for shelf filter if frequency, gain or slope have changed.
- */
- @Override
- public void recalculate() {
- // Just look at first value to save time.
- double frequencyValue = frequency.getValues()[0];
- if (frequencyValue < MINIMUM_FREQUENCY) {
- frequencyValue = MINIMUM_FREQUENCY;
- }
-
- double gainValue = gain.getValues()[0];
- if (gainValue < MINIMUM_GAIN) {
- gainValue = MINIMUM_GAIN;
- }
-
- double slopeValue = slope.getValues()[0];
- if (slopeValue < MINIMUM_SLOPE) {
- slopeValue = MINIMUM_SLOPE;
- }
-
- // Only do complex calculations if input changed.
- if ((frequencyValue != previousFrequency) || (gainValue != prevGain)
- || (slopeValue != prevSlope)) {
- previousFrequency = frequencyValue; // hold previous frequency
- prevGain = gainValue;
- prevSlope = slopeValue;
-
- double ratio = frequencyValue * getFramePeriod();
- calculateOmega(ratio);
-
- factorA = Math.sqrt(gainValue);
-
- AP1 = factorA + 1.0;
- AM1 = factorA - 1.0;
-
- /* Avoid sqrt(r<0) which hangs filter. */
- double beta2 = ((gainValue + 1.0) / slopeValue) - (AM1 * AM1);
- beta = (beta2 < 0.0) ? 0.0 : Math.sqrt(beta2);
-
- beta_sn = beta * sin_omega;
- AP1cs = AP1 * cos_omega;
- AM1cs = AM1 * cos_omega;
-
- updateCoefficients();
- }
- }
-
-}
diff --git a/src/com/jsyn/unitgen/FilterFourPoles.java b/src/com/jsyn/unitgen/FilterFourPoles.java
deleted file mode 100644
index 39a47c7..0000000
--- a/src/com/jsyn/unitgen/FilterFourPoles.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright 2014 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;
-
-/**
- * Resonant filter in the style of the Moog ladder filter. This implementation is loosely based on:
- * http://www.musicdsp.org/archive.php?classid=3#26
- * More interesting reading:
- * http://dafx04.na.infn.it/WebProc/Proc/P_061.pdf
- * http://www.acoustics.ed.ac.uk/wp-content/uploads/AMT_MSc_FinalProjects
- * /2012__Daly__AMT_MSc_FinalProject_MoogVCF.pdf
- * http://www.music.mcgill.ca/~ich/research/misc/papers/cr1071.pdf
- *
- * @author Phil Burk (C) 2014 Mobileer Inc
- * @see FilterLowPass
- */
-public class FilterFourPoles extends TunableFilter {
- public UnitInputPort Q;
- public UnitInputPort gain;
-
- private static final double MINIMUM_FREQUENCY = 1.0; // blows up if near 0.01
- private static final double MINIMUM_Q = 0.00001;
-
- //private static final double SATURATION_COEFFICIENT = 0.1666667;
- private static final double SATURATION_COEFFICIENT = 0.2;
- // Inflection point where slope is zero.
- private static final double SATURATION_UPPER_INPUT = 1.0 / Math.sqrt(3.0 * SATURATION_COEFFICIENT);
- private static final double SATURATION_LOWER_INPUT = 0.0 - SATURATION_UPPER_INPUT;
- private static final double SATURATION_UPPER_OUTPUT = cubicPolynomial(SATURATION_UPPER_INPUT);
- private static final double SATURATION_LOWER_OUTPUT = cubicPolynomial(SATURATION_LOWER_INPUT);
-
- private double x1;
- private double x2;
- private double x3;
- private double x4;
- private double y1;
- private double y2;
- private double y3;
- private double y4;
-
- private double previousFrequency;
- private double previousQ;
- // filter coefficients
- private double f;
- private double fTo4th;
- private double feedback;
-
- private boolean oversampled = true;
-
- public FilterFourPoles() {
- addPort(Q = new UnitInputPort("Q"));
- frequency.setup(40.0, DEFAULT_FREQUENCY, 4000.0);
- Q.setup(0.1, 2.0, 10.0);
- }
-
- /**
- * The recalculate() method checks and ensures that the frequency and Q values are at a minimum.
- * It also only updates the coefficients if either frequency or Q have changed.
- */
- public void recalculate() {
- double frequencyValue = frequency.getValues()[0];
- double qValue = Q.getValues()[0];
-
- if (frequencyValue < MINIMUM_FREQUENCY) // ensure a minimum frequency
- {
- frequencyValue = MINIMUM_FREQUENCY;
- }
- if (qValue < MINIMUM_Q) // ensure a minimum Q
- {
- qValue = MINIMUM_Q;
- }
-
- // Only recompute coefficients if changed.
- if ((frequencyValue != previousFrequency) || (qValue != previousQ)) {
- previousFrequency = frequencyValue;
- previousQ = qValue;
- computeCoefficients();
- }
- }
-
- private void computeCoefficients() {
- double normalizedFrequency = previousFrequency * getFramePeriod();
- double fudge = 4.9 - 0.27 * previousQ;
- if (fudge < 3.0)
- fudge = 3.0;
- f = normalizedFrequency * (oversampled ? 1.0 : 2.0) * fudge;
-
- double fSquared = f * f;
- fTo4th = fSquared * fSquared;
- feedback = 0.5 * previousQ * (1.0 - 0.15 * fSquared);
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] inputs = input.getValues();
- double[] outputs = output.getValues();
-
- recalculate();
-
- for (int i = start; i < limit; i++) {
- double x0 = inputs[i];
-
- if (oversampled) {
- oneSample(0.0);
- }
- oneSample(x0);
- outputs[i] = y4;
- }
-
- // apply small bipolar impulse to prevent arithmetic underflow
- y1 += VERY_SMALL_FLOAT;
- y2 -= VERY_SMALL_FLOAT;
- }
-
- private void oneSample(double x0) {
- final double coeff = 0.3;
- x0 -= y4 * feedback; // feedback
- x0 *= 0.35013 * fTo4th;
- y1 = x0 + coeff * x1 + (1 - f) * y1; // pole 1
- x1 = x0;
- y2 = y1 + coeff * x2 + (1 - f) * y2; // pole 2
- x2 = y1;
- y3 = y2 + coeff * x3 + (1 - f) * y3; // pole 3
- x3 = y2;
- y4 = y3 + coeff * x4 + (1 - f) * y4; // pole 4
- y4 = clip(y4);
- x4 = y3;
- }
-
- public boolean isOversampled() {
- return oversampled;
- }
-
- public void setOversampled(boolean oversampled) {
- this.oversampled = oversampled;
- }
-
- // Soft saturation. This used to blow up the filter!
- private static double cubicPolynomial(double x) {
- return x - (x * x * x * SATURATION_COEFFICIENT);
- }
-
- private static double clip(double x) {
- if (x > SATURATION_UPPER_INPUT) {
- return SATURATION_UPPER_OUTPUT;
- } else if (x < SATURATION_LOWER_INPUT) {
- return SATURATION_LOWER_OUTPUT;
- } else {
- return cubicPolynomial(x);
- }
- }
-
- public void reset() {
- x1 = 0.0;
- x2 = 0.0;
- x3 = 0.0;
- x4 = 0.0;
- y1 = 0.0;
- y2 = 0.0;
- y3 = 0.0;
- y4 = 0.0;
-
- previousFrequency = 0.0;
- previousQ = 0.0;
- f = 0.0;
- fTo4th = 0.0;
- feedback = 0.0;
- }
-}
diff --git a/src/com/jsyn/unitgen/FilterHighPass.java b/src/com/jsyn/unitgen/FilterHighPass.java
deleted file mode 100644
index 76ad6b9..0000000
--- a/src/com/jsyn/unitgen/FilterHighPass.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2009 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.
- */
-/**
- * Aug 21, 2009
- * com.jsyn.engine.units.Filter_HighPass.java
- */
-
-package com.jsyn.unitgen;
-
-/**
- * Filter that allows frequencies above the center frequency to pass. This filter is based on the
- * BiQuad filter. Coefficients are updated whenever the frequency or Q changes.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc Translated from 'C' to Java by Lisa
- * Tolentino.
- */
-public class FilterHighPass extends FilterBiquadCommon {
- /**
- * This method is used by Filter_Biquad to update coefficients for the Filter_HighPass filter.
- */
- @Override
- public void updateCoefficients() {
- double scalar = 1.0 / (1.0 + alpha);
- double onePlusCosine = 1.0 + cos_omega;
- double a0_a2_value = onePlusCosine * 0.5 * scalar;
-
- this.a0 = a0_a2_value;
- this.a1 = -onePlusCosine * scalar;
- this.a2 = a0_a2_value;
- this.b1 = -2.0 * cos_omega * scalar;
- this.b2 = (1.0 - alpha) * scalar;
- }
-}
diff --git a/src/com/jsyn/unitgen/FilterHighShelf.java b/src/com/jsyn/unitgen/FilterHighShelf.java
deleted file mode 100644
index 449090a..0000000
--- a/src/com/jsyn/unitgen/FilterHighShelf.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2009 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;
-
-/**
- * HighShelf Filter. This creates a flat response above the cutoff frequency. This filter is
- * sometimes used at the end of a bank of EQ filters.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public class FilterHighShelf extends FilterBiquadShelf {
- /**
- * This method is called by by Filter_BiquadShelf to update coefficients.
- */
- @Override
- public void updateCoefficients() {
- double scalar = 1.0 / (AP1 - AM1cs + beta_sn);
- a0 = factorA * (AP1 + AM1cs + beta_sn) * scalar;
- a1 = -2.0 * factorA * (AM1 + AP1cs) * scalar;
- a2 = factorA * (AP1 + AM1cs - beta_sn) * scalar;
- b1 = 2.0 * (AM1 - AP1cs) * scalar;
- b2 = (AP1 - AM1cs - beta_sn) * scalar;
- }
-}
diff --git a/src/com/jsyn/unitgen/FilterLowPass.java b/src/com/jsyn/unitgen/FilterLowPass.java
deleted file mode 100644
index 1557367..0000000
--- a/src/com/jsyn/unitgen/FilterLowPass.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright 2009 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.
- */
-/**
- * Aug 21, 2009
- * com.jsyn.engine.units.Filter_HighPass.java
- */
-
-package com.jsyn.unitgen;
-
-/**
- * Filter that allows frequencies below the center frequency to pass. This filter is based on the
- * BiQuad filter. Coefficients are updated whenever the frequency or Q changes.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc Translated from 'C' to Java by Lisa
- * Tolentino.
- *
- * @see FilterFourPoles
- */
-public class FilterLowPass extends FilterBiquadCommon {
-
- /**
- * This method is by FilterBiquad to update coefficients for the lowpass filter.
- */
- @Override
- public void updateCoefficients() {
-
- // scalar = 1.0f / (1.0f + BQCM.alpha);
- // omc = (1.0f - BQCM.cos_omega);
- // A0_A2_Value = omc * 0.5f * scalar;
- // // translating from RBJ coefficients
- // // A0 = (b0/(2*a0)
- // // = ((1 - cos_omega)/2) / (1 + alpha)
- // // = (omc*0.5) / (1 + alpha)
- // // = (omc*0.5) * (1.0/(1 + alpha))
- // // = omc * 0.5 * scalar
- // csFilter->csFBQ_A0 = A0_A2_Value;
- // csFilter->csFBQ_A1 = omc * scalar;
- // csFilter->csFBQ_A2 = A0_A2_Value;
- // csFilter->csFBQ_B1 = -2.0f * BQCM.cos_omega * scalar;
- // csFilter->csFBQ_B2 = (1.0f - BQCM.alpha) * scalar;
-
- double scalar = 1.0 / (1.0 + alpha);
- double oneMinusCosine = 1.0 - cos_omega;
- double a0_a2_value = oneMinusCosine * 0.5 * scalar;
-
- this.a0 = a0_a2_value;
- this.a1 = oneMinusCosine * scalar;
- this.a2 = a0_a2_value;
- this.b1 = -2.0 * cos_omega * scalar;
- this.b2 = (1.0 - alpha) * scalar;
- }
-}
diff --git a/src/com/jsyn/unitgen/FilterLowShelf.java b/src/com/jsyn/unitgen/FilterLowShelf.java
deleted file mode 100644
index cf41f45..0000000
--- a/src/com/jsyn/unitgen/FilterLowShelf.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2009 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;
-
-/**
- * LowShelf Filter. This creates a flat response below the cutoff frequency. This filter is
- * sometimes used at the end of a bank of EQ filters. This filter is based on the BiQuad filter.
- * Coefficients are updated whenever the frequency or Q changes.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public class FilterLowShelf extends FilterBiquadShelf {
-
- /**
- * This method is called by Filter_BiquadShelf to update coefficients.
- */
- @Override
- public void updateCoefficients() {
- double scalar = 1.0 / (AP1 + AM1cs + beta_sn);
- a0 = factorA * (AP1 - AM1cs + beta_sn) * scalar;
- a1 = 2.0 * factorA * (AM1 - AP1cs) * scalar;
- a2 = factorA * (AP1 - AM1cs - beta_sn) * scalar;
- b1 = -2.0 * (AM1 + AP1cs) * scalar;
- b2 = (AP1 + AM1cs - beta_sn) * scalar;
- }
-}
diff --git a/src/com/jsyn/unitgen/FilterOnePole.java b/src/com/jsyn/unitgen/FilterOnePole.java
deleted file mode 100644
index 090e42b..0000000
--- a/src/com/jsyn/unitgen/FilterOnePole.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 2009 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.UnitVariablePort;
-
-/**
- * First Order, One Pole filter using the following formula:
- *
- * <pre>
- * y(n) = A0 * x(n) - B1 * y(n - 1)
- * </pre>
- *
- * where y(n) is Output, x(n) is Input and y(n-1) is a delayed copy of the output. This filter is a
- * recursive IIR or Infinite Impulse Response filter. It can be unstable depending on the values of
- * the coefficients. This can be useful as a low-pass filter, or a "leaky integrator". A thorough
- * description of the digital filter theory needed to fully describe this filter is beyond the scope
- * of this document. Calculating coefficients is non-intuitive; the interested user is referred to
- * one of the standard texts on filter theory (e.g., Moore, "Elements of Computer Music", section
- * 2.4).
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- * @see FilterLowPass
- */
-public class FilterOnePole extends UnitFilter {
- public UnitVariablePort a0;
- public UnitVariablePort b1;
- private double y1;
-
- public FilterOnePole() {
- addPort(a0 = new UnitVariablePort("A0", 0.6));
- addPort(b1 = new UnitVariablePort("B1", -0.3));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] inputs = input.getValues();
- double[] outputs = output.getValues();
- double a0v = a0.getValue();
- double b1v = b1.getValue();
-
- for (int i = start; i < limit; i++) {
- double x0 = inputs[i];
- outputs[i] = y1 = (a0v * x0) - (b1v * y1);
- }
-
- }
-}
diff --git a/src/com/jsyn/unitgen/FilterOnePoleOneZero.java b/src/com/jsyn/unitgen/FilterOnePoleOneZero.java
deleted file mode 100644
index ed1868c..0000000
--- a/src/com/jsyn/unitgen/FilterOnePoleOneZero.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.UnitVariablePort;
-
-/**
- * First Order, One Pole, One Zero filter using the following formula:
- *
- * <pre>
- * y(n) = A0 * x(n) + A1 * x(n - 1) - B1 * y(n - 1)
- * </pre>
- *
- * where y(n) is Output, x(n) is Input, x(n-1) is a delayed copy of the input, and y(n-1) is a
- * delayed copy of the output. This filter is a recursive IIR or Infinite Impulse Response filter.
- * it can be unstable depending on the values of the coefficients. A thorough description of the
- * digital filter theory needed to fully describe this filter is beyond the scope of this document.
- * Calculating coefficients is non-intuitive; the interested user is referred to one of the standard
- * texts on filter theory (e.g., Moore, "Elements of Computer Music", section 2.4).
- *
- * @author (C) 1997-2009 Phil Burk, SoftSynth.com
- * @see FilterLowPass
- */
-
-public class FilterOnePoleOneZero extends UnitFilter {
- public UnitVariablePort a0;
- public UnitVariablePort a1;
- public UnitVariablePort b1;
-
- private double x1;
- private double y1;
-
- public FilterOnePoleOneZero() {
- addPort(a0 = new UnitVariablePort("A0"));
- addPort(a1 = new UnitVariablePort("A1"));
- addPort(b1 = new UnitVariablePort("B1"));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] inputs = input.getValues();
- double[] outputs = output.getValues();
- double a0v = a0.getValue();
- double a1v = a1.getValue();
- double b1v = b1.getValue();
-
- for (int i = start; i < limit; i++) {
- double x0 = inputs[i];
- outputs[i] = y1 = (a0v * x0) + (a1v * x1) + (b1v * y1);
- x1 = x0;
- }
-
- }
-}
diff --git a/src/com/jsyn/unitgen/FilterOneZero.java b/src/com/jsyn/unitgen/FilterOneZero.java
deleted file mode 100644
index 2a07a16..0000000
--- a/src/com/jsyn/unitgen/FilterOneZero.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright 2011 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.UnitVariablePort;
-
-/**
- * First Order, One Zero filter using the following formula:
- *
- * <pre>
- * y(n) = A0 * x(n) + A1 * x(n - 1)
- * </pre>
- *
- * where y(n) is Output, x(n) is Input and x(n-1) is Input at the prior sample tick. Setting A1
- * positive gives a low-pass response; setting A1 negative gives a high-pass response. The bandwidth
- * of this filter is fairly high, so it often serves a building block by being cascaded with other
- * filters. If A0 and A1 are both 0.5, then this filter is a simple averaging lowpass filter, with a
- * zero at SR/2 = 22050 Hz. If A0 is 0.5 and A1 is -0.5, then this filter is a high pass filter,
- * with a zero at 0.0 Hz. A thorough description of the digital filter theory needed to fully
- * describe this filter is beyond the scope of this document. Calculating coefficients is
- * non-intuitive; the interested user is referred to one of the standard texts on filter theory
- * (e.g., Moore, "Elements of Computer Music", section 2.4).
- *
- * @author Phil Burk (C) 2011 Mobileer Inc
- * @see FilterLowPass
- */
-public class FilterOneZero extends UnitFilter {
- public UnitVariablePort a0;
- public UnitVariablePort a1;
- private double x1;
-
- public FilterOneZero() {
- addPort(a0 = new UnitVariablePort("A0", 0.5));
- addPort(a1 = new UnitVariablePort("A1", 0.5));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] inputs = input.getValues();
- double[] outputs = output.getValues();
- double a0v = a0.getValue();
- double a1v = a1.getValue();
-
- for (int i = start; i < limit; i++) {
- double x0 = inputs[i];
- outputs[i] = (a0v * x0) + (a1v * x1);
- x1 = x0;
- }
-
- }
-}
diff --git a/src/com/jsyn/unitgen/FilterPeakingEQ.java b/src/com/jsyn/unitgen/FilterPeakingEQ.java
deleted file mode 100644
index bec7096..0000000
--- a/src/com/jsyn/unitgen/FilterPeakingEQ.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright 2009 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;
-
-/**
- * PeakingEQ Filter. This can be used to raise or lower the gain around the cutoff frequency. This
- * filter is sometimes used in the middle of a bank of EQ filters. This filter is based on the
- * BiQuad filter. Coefficients are updated whenever the frequency or Q changes.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public class FilterPeakingEQ extends FilterBiquadCommon {
- public UnitInputPort gain;
-
- private double previousGain;
-
- public FilterPeakingEQ() {
- addPort(gain = new UnitInputPort("Gain", 1.0));
- }
-
- @Override
- protected boolean isRecalculationNeeded(double frequencyValue, double qValue) {
- double currentGain = gain.getValues()[0];
- if (currentGain < MINIMUM_GAIN) {
- currentGain = MINIMUM_GAIN;
- }
-
- boolean needed = super.isRecalculationNeeded(frequencyValue, qValue);
- needed |= (previousGain != currentGain);
-
- previousGain = currentGain;
- return needed;
- }
-
- @Override
- public void updateCoefficients() {
- double factorA = Math.sqrt(previousGain);
- double alphaTimesA = alpha * factorA;
- double alphaOverA = alpha / factorA;
- // Note this is not the normal scalar!
- double scalar = 1.0 / (1.0 + alphaOverA);
- double a1_b1_value = -2.0 * cos_omega * scalar;
-
- this.a0 = (1.0 + alphaTimesA) * scalar;
-
- this.a1 = a1_b1_value;
- this.a2 = (1.0 - alphaTimesA) * scalar;
-
- this.b1 = a1_b1_value;
- this.b2 = (1.0 - alphaOverA) * scalar;
- }
-}
diff --git a/src/com/jsyn/unitgen/FilterStateVariable.java b/src/com/jsyn/unitgen/FilterStateVariable.java
deleted file mode 100644
index 74dde5e..0000000
--- a/src/com/jsyn/unitgen/FilterStateVariable.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright 2009 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;
-import com.jsyn.ports.UnitOutputPort;
-
-/**
- * A versatile filter described in Hal Chamberlain's "Musical Applications of MicroProcessors". It
- * is convenient because its frequency and resonance can each be controlled by a single value. The
- * "output" port of this filter is the "lowPass" output multiplied by the "amplitude"
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- * @see FilterLowPass
- * @see FilterHighPass
- * @see FilterFourPoles
- */
-public class FilterStateVariable extends TunableFilter {
- /**
- * Amplitude of Output in the range of 0.0 to 1.0. SIGNAL_TYPE_RAW_SIGNED Defaults to 1.0
- * <P>
- * Note that the amplitude only affects the "output" port and not the lowPass, bandPass or
- * highPass signals. Use a Multiply unit if you need to scale those signals.
- */
- public UnitInputPort amplitude;
-
- /**
- * Controls feedback that causes self oscillation. Actually 1/Q - SIGNAL_TYPE_RAW_SIGNED in the
- * range of 0.0 to 1.0. Defaults to 0.125.
- */
- public UnitInputPort resonance;
- /**
- * Low pass filtered signal.
- * <P>
- * Note that this signal is not affected by the amplitude port.
- */
- public UnitOutputPort lowPass;
- /**
- * Band pass filtered signal.
- * <P>
- * Note that this signal is not affected by the amplitude port.
- */
- public UnitOutputPort bandPass;
- /**
- * High pass filtered signal.
- * <P>
- * Note that this signal is not affected by the amplitude port.
- */
- public UnitOutputPort highPass;
-
- private double freqInternal;
- private double previousFrequency = Double.MAX_VALUE; // So we trigger an immediate update.
- private double lowPassValue;
- private double bandPassValue;
-
- /**
- * No-argument constructor instantiates the Biquad common and adds an amplitude port to this
- * filter.
- */
- public FilterStateVariable() {
- frequency.set(440.0);
- addPort(resonance = new UnitInputPort("Resonance", 0.2));
- addPort(amplitude = new UnitInputPort("Amplitude", 1.0));
- addPort(lowPass = new UnitOutputPort("LowPass"));
- addPort(bandPass = new UnitOutputPort("BandPass"));
- addPort(highPass = new UnitOutputPort("HighPass"));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] inputs = input.getValues();
- double[] outputs = output.getValues();
- double[] frequencies = frequency.getValues();
- double[] amplitudes = amplitude.getValues();
- double[] reses = resonance.getValues();
- double[] lows = lowPass.getValues();
- double[] highs = highPass.getValues();
- double[] bands = bandPass.getValues();
-
- double newFreq = frequencies[0];
- if (newFreq != previousFrequency) {
- previousFrequency = newFreq;
- freqInternal = 2.0 * Math.sin(Math.PI * newFreq * getFramePeriod());
- }
-
- for (int i = start; i < limit; i++) {
- lowPassValue = (freqInternal * bandPassValue) + lowPassValue;
- // Clip between -1 and +1 to prevent blowup.
- lowPassValue = (lowPassValue < -1.0) ? -1.0 : ((lowPassValue > 1.0) ? 1.0
- : lowPassValue);
- lows[i] = lowPassValue;
-
- outputs[i] = lowPassValue * (amplitudes[i]);
- double highPassValue = inputs[i] - (reses[i] * bandPassValue) - lowPassValue;
- // System.out.println("low = " + lowPassValue + ", band = " + bandPassValue +
- // ", high = " + highPassValue );
- highs[i] = highPassValue;
-
- bandPassValue = (freqInternal * highPassValue) + bandPassValue;
- bands[i] = bandPassValue;
- // System.out.println("low = " + lowPassValue + ", band = " + bandPassValue +
- // ", high = " + highPassValue );
- }
- }
-
-}
diff --git a/src/com/jsyn/unitgen/FilterTwoPoles.java b/src/com/jsyn/unitgen/FilterTwoPoles.java
deleted file mode 100644
index 0c68a64..0000000
--- a/src/com/jsyn/unitgen/FilterTwoPoles.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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.UnitVariablePort;
-
-/**
- * Second Order, Two Pole filter using the following formula:
- *
- * <pre>
- * y(n) = A0 * x(n) - B1 * y(n - 1) - B2 * y(n - 2)
- * </pre>
- *
- * where y(n) is Output, x(n) is Input, and y(n-1) is a delayed copy of the output. This filter is a
- * recursive IIR or Infinite Impulse Response filter. it can be unstable depending on the values of
- * the coefficients. A thorough description of the digital filter theory needed to fully describe
- * this filter is beyond the scope of this document. Calculating coefficients is non-intuitive; the
- * interested user is referred to one of the standard texts on filter theory (e.g., Moore,
- * "Elements of Computer Music", section 2.4).
- *
- * @author (C) 1997-2009 Phil Burk, Mobileer Inc
- */
-
-public class FilterTwoPoles extends UnitFilter {
- public UnitVariablePort a0;
- public UnitVariablePort b1;
- public UnitVariablePort b2;
- private double y1;
- private double y2;
-
- public FilterTwoPoles() {
- addPort(a0 = new UnitVariablePort("A0"));
- addPort(b1 = new UnitVariablePort("B1"));
- addPort(b2 = new UnitVariablePort("B2"));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] inputs = input.getValues();
- double[] outputs = output.getValues();
- double a0v = a0.getValue();
- double b1v = b1.getValue();
- double b2v = b2.getValue();
-
- for (int i = start; i < limit; i++) {
- double x0 = inputs[i];
- outputs[i] = y1 = 2.0 * ((a0v * x0) + (b1v * y1) + (b2v * y2));
- y2 = y1;
- }
-
- }
-}
diff --git a/src/com/jsyn/unitgen/FilterTwoPolesTwoZeros.java b/src/com/jsyn/unitgen/FilterTwoPolesTwoZeros.java
deleted file mode 100644
index cde279f..0000000
--- a/src/com/jsyn/unitgen/FilterTwoPolesTwoZeros.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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.UnitVariablePort;
-
-/**
- * Second Order, Two Pole, Two Zero filter using the following formula:
- *
- * <pre>
- * y(n) = 2.0 * (A0 * x(n) + A1 * x(n - 1) + A2 * x(n - 2) - B1 * y(n - 1) - B2 * y(n - 2))
- * </pre>
- *
- * where y(n) is Output, x(n) is Input, x(n-1) is a delayed copy of the input, and y(n-1) is a
- * delayed copy of the output. This filter is a recursive IIR or Infinite Impulse Response filter.
- * It can be unstable depending on the values of the coefficients. This filter is basically the same
- * as the FilterBiquad with different ports. A thorough description of the digital filter theory
- * needed to fully describe this filter is beyond the scope of this document. Calculating
- * coefficients is non-intuitive; the interested user is referred to one of the standard texts on
- * filter theory (e.g., Moore, "Elements of Computer Music", section 2.4). Special thanks to Robert
- * Bristow-Johnson for contributing his filter equations to the music-dsp list. They were used for
- * calculating the coefficients for the lowPass, highPass, and other parametric filter calculations.
- *
- * @author (C) 1997-2009 Phil Burk, SoftSynth.com
- */
-
-public class FilterTwoPolesTwoZeros extends UnitFilter {
- public UnitVariablePort a0;
- public UnitVariablePort a1;
- public UnitVariablePort a2;
- public UnitVariablePort b1;
- public UnitVariablePort b2;
- private double x1;
- private double y1;
- private double x2;
- private double y2;
-
- public FilterTwoPolesTwoZeros() {
- addPort(a0 = new UnitVariablePort("A0"));
- addPort(a1 = new UnitVariablePort("A1"));
- addPort(a2 = new UnitVariablePort("A2"));
- addPort(b1 = new UnitVariablePort("B1"));
- addPort(b2 = new UnitVariablePort("B2"));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] inputs = input.getValues();
- double[] outputs = output.getValues();
- double a0v = a0.getValue();
- double a1v = a1.getValue();
- double a2v = a2.getValue();
- double b1v = b1.getValue();
- double b2v = b2.getValue();
-
- for (int i = start; i < limit; i++) {
- double x0 = inputs[i];
- outputs[i] = y1 = 2.0 * ((a0v * x0) + (a1v * x1) + (a2v * x2) + (b1v * y1) + (b2v * y2));
- x2 = x1;
- x1 = x0;
- y2 = y1;
- }
-
- }
-}
diff --git a/src/com/jsyn/unitgen/FixedRateMonoReader.java b/src/com/jsyn/unitgen/FixedRateMonoReader.java
deleted file mode 100644
index c6edc23..0000000
--- a/src/com/jsyn/unitgen/FixedRateMonoReader.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2009 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.UnitOutputPort;
-
-/**
- * Simple sample player. Play one sample per audio frame with no interpolation.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public class FixedRateMonoReader extends SequentialDataReader {
-
- public FixedRateMonoReader() {
- addPort(output = new UnitOutputPort());
- }
-
- @Override
- public void generate(int start, int limit) {
-
- double[] amplitudes = amplitude.getValues();
- double[] outputs = output.getValues();
-
- for (int i = start; i < limit; i++) {
- if (dataQueue.hasMore()) {
- double fdata = dataQueue.readNextMonoDouble(getFramePeriod());
- outputs[i] = fdata * amplitudes[i];
- } else {
- outputs[i] = 0.0;
- if (dataQueue.testAndClearAutoStop()) {
- autoStop();
- }
- }
- dataQueue.firePendingCallbacks();
- }
- }
-
-}
diff --git a/src/com/jsyn/unitgen/FixedRateMonoWriter.java b/src/com/jsyn/unitgen/FixedRateMonoWriter.java
deleted file mode 100644
index c215c55..0000000
--- a/src/com/jsyn/unitgen/FixedRateMonoWriter.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright 2009 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;
-
-/**
- * Simple sample writer. Write one sample per audio frame with no interpolation. This can be used to
- * record audio or to build delay lines.
- *
- * Note that you must call start() on this unit because it does not have an output for pulling data.
- *
- * @see FixedRateStereoWriter
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public class FixedRateMonoWriter extends SequentialDataWriter {
-
- public FixedRateMonoWriter() {
- addPort(input = new UnitInputPort("Input"));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] inputs = input.getValues();
-
- for (int i = start; i < limit; i++) {
- if (dataQueue.hasMore()) {
- double value = inputs[i];
- dataQueue.writeNextDouble(value);
- } else {
- if (dataQueue.testAndClearAutoStop()) {
- autoStop();
- }
- }
- dataQueue.firePendingCallbacks();
- }
-
- }
-
-}
diff --git a/src/com/jsyn/unitgen/FixedRateStereoReader.java b/src/com/jsyn/unitgen/FixedRateStereoReader.java
deleted file mode 100644
index c5c00ce..0000000
--- a/src/com/jsyn/unitgen/FixedRateStereoReader.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2009 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.UnitOutputPort;
-
-/**
- * Simple stereo sample player. Play one sample per audio frame with no interpolation.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public class FixedRateStereoReader extends SequentialDataReader {
- public FixedRateStereoReader() {
- addPort(output = new UnitOutputPort(2, "Output"));
- dataQueue.setNumChannels(2);
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] amplitudes = amplitude.getValues();
- double[] output0s = output.getValues(0);
- double[] output1s = output.getValues(1);
-
- for (int i = start; i < limit; i++) {
- if (dataQueue.hasMore()) {
- dataQueue.beginFrame(getFramePeriod());
- double fdata = dataQueue.readCurrentChannelDouble(0);
- // System.out.println("SampleReader_16F2: left = " + fdata );
- double amp = amplitudes[i];
- output0s[i] = fdata * amp;
- fdata = dataQueue.readCurrentChannelDouble(1);
- // System.out.println("SampleReader_16F2: right = " + fdata );
- output1s[i] = fdata * amp;
- dataQueue.endFrame();
- } else {
- output0s[i] = 0.0;
- output1s[i] = 0.0;
- if (dataQueue.testAndClearAutoStop()) {
- autoStop();
- }
- }
- dataQueue.firePendingCallbacks();
- }
- }
-}
diff --git a/src/com/jsyn/unitgen/FixedRateStereoWriter.java b/src/com/jsyn/unitgen/FixedRateStereoWriter.java
deleted file mode 100644
index e4502f9..0000000
--- a/src/com/jsyn/unitgen/FixedRateStereoWriter.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2009 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;
-
-/**
- * Simple stereo sample writer. Write two samples per audio frame with no interpolation. This can be
- * used to record audio or to build delay lines.
- *
- * Note that you must call start() on this unit because it does not have an output for pulling data.
- *
- * @see FixedRateMonoWriter
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public class FixedRateStereoWriter extends SequentialDataWriter {
-
- public FixedRateStereoWriter() {
- addPort(input = new UnitInputPort(2, "Input"));
- dataQueue.setNumChannels(2);
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] input0s = input.getValues(0);
- double[] input1s = input.getValues(1);
-
- for (int i = start; i < limit; i++) {
- if (dataQueue.hasMore()) {
- dataQueue.beginFrame(getFramePeriod());
- double value = input0s[i];
- dataQueue.writeCurrentChannelDouble(0, value);
- value = input1s[i];
- dataQueue.writeCurrentChannelDouble(1, value);
- dataQueue.endFrame();
- } else {
- if (dataQueue.testAndClearAutoStop()) {
- autoStop();
- }
- }
- dataQueue.firePendingCallbacks();
- }
-
- }
-
-}
diff --git a/src/com/jsyn/unitgen/FourWayFade.java b/src/com/jsyn/unitgen/FourWayFade.java
deleted file mode 100644
index c7fd22a..0000000
--- a/src/com/jsyn/unitgen/FourWayFade.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * 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;
-import com.jsyn.ports.UnitOutputPort;
-
-/**
- * FourWayFade unit.
- * <P>
- * Mix inputs 0-3 based on the value of two fade ports. You can think of the four inputs arranged
- * clockwise as follows.
- * <P>
- *
- * <PRE>
- * input[0] ---- input[1]
- * | |
- * | |
- * | |
- * input[3] ---- input[2]
- * </PRE>
- *
- * The "fade" port has two parts. Fade[0] fades between the pair of inputs (0,3) and the pair of
- * inputs (1,2). Fade[1] fades between the pair of inputs (0,1) and the pair of inputs (3,2).
- *
- * <PRE>
- * Fade[0] Fade[1] Output
- * -1 -1 Input[3]
- * -1 +1 Input[0]
- * +1 -1 Input[2]
- * +1 +1 Input[1]
- *
- *
- * -----Fade[0]-----&gt;
- *
- * A
- * |
- * |
- * Fade[1]
- * |
- * |
- * </PRE>
- * <P>
- *
- * @author (C) 1997-2009 Phil Burk, Mobileer Inc
- */
-public class FourWayFade extends UnitGenerator {
- public UnitInputPort input;
- public UnitInputPort fade;
- public UnitOutputPort output;
-
- /* Define Unit Ports used by connect() and set(). */
- public FourWayFade() {
- addPort(input = new UnitInputPort(4, "Input"));
- addPort(fade = new UnitInputPort(2, "Fade"));
- addPort(output = new UnitOutputPort());
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] inputAs = input.getValues(0);
- double[] inputBs = input.getValues(1);
- double[] inputCs = input.getValues(2);
- double[] inputDs = input.getValues(3);
- double[] fadeLRs = fade.getValues(0);
- double[] fadeFBs = fade.getValues(1);
- double[] outputs = output.getValues(0);
-
- for (int i = start; i < limit; i++) {
- // Scale and offset to 0.0 to 1.0 range.
- double gainLR = (fadeLRs[i] * 0.5) + 0.5;
- double temp = 1.0 - gainLR;
- double mixFront = (inputAs[i] * temp) + (inputBs[i] * gainLR);
- double mixBack = (inputDs[i] * temp) + (inputCs[i] * gainLR);
-
- double gainFB = (fadeFBs[i] * 0.5) + 0.5;
- outputs[i] = (mixBack * (1.0 - gainFB)) + (mixFront * gainFB);
- }
- }
-}
diff --git a/src/com/jsyn/unitgen/FunctionEvaluator.java b/src/com/jsyn/unitgen/FunctionEvaluator.java
deleted file mode 100644
index 0cc0c83..0000000
--- a/src/com/jsyn/unitgen/FunctionEvaluator.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright 2009 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.
- */
-/**
- * Aug 26, 2009
- * com.jsyn.engine.units.TunableFilter.java
- */
-
-package com.jsyn.unitgen;
-
-import com.jsyn.data.Function;
-import com.jsyn.ports.UnitFunctionPort;
-import com.jsyn.ports.UnitInputPort;
-
-/**
- * Convert an input value to an output value. The Function is typically implemented by looking up a
- * value in a DoubleTable. But other implementations of Function can be used. Input typically ranges
- * from -1.0 to +1.0.
- *
- * <pre>
- * <code>
- * // A unit that will lookup the function.
- * FunctionEvaluator shaper = new FunctionEvaluator();
- * synth.add( shaper );
- * shaper.start();
- * // Define a custom function.
- * Function cuber = new Function()
- * {
- * public double evaluate( double x )
- * {
- * return x * x * x;
- * }
- * };
- * shaper.function.set(cuber);
- *
- * shaper.input.set( 0.5 );
- * </code>
- * </pre>
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- * @see Function
- */
-public class FunctionEvaluator extends UnitFilter {
- public UnitInputPort amplitude;
- public UnitFunctionPort function;
-
- public FunctionEvaluator() {
- addPort(amplitude = new UnitInputPort("Amplitude", 1.0));
- addPort(function = new UnitFunctionPort("Function"));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] inputs = input.getValues();
- double[] amplitudes = amplitude.getValues();
- double[] outputs = output.getValues();
- Function functionObject = function.get();
-
- for (int i = start; i < limit; i++) {
- outputs[i] = functionObject.evaluate(inputs[i]) * amplitudes[i];
- }
-
- }
-}
diff --git a/src/com/jsyn/unitgen/FunctionOscillator.java b/src/com/jsyn/unitgen/FunctionOscillator.java
deleted file mode 100644
index 30d32d5..0000000
--- a/src/com/jsyn/unitgen/FunctionOscillator.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright 2009 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.data.Function;
-import com.jsyn.ports.UnitFunctionPort;
-
-/**
- * Oscillator that uses a Function object to define the waveform. Note that a DoubleTable can be
- * used as the Function.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public class FunctionOscillator extends UnitOscillator {
- public UnitFunctionPort function;
-
- public FunctionOscillator() {
- addPort(function = new UnitFunctionPort("Function"));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] frequencies = frequency.getValues();
- double[] amplitudes = amplitude.getValues();
- double[] outputs = output.getValues();
-
- Function functionObject = function.get();
-
- // Variables have a single value.
- double currentPhase = phase.getValue();
-
- for (int i = start; i < limit; i++) {
- // Generate sawtooth phasor to provide phase for function lookup.
- double phaseIncrement = convertFrequencyToPhaseIncrement(frequencies[i]);
- currentPhase = incrementWrapPhase(currentPhase, phaseIncrement);
- double value = functionObject.evaluate(currentPhase);
- outputs[i] = value * amplitudes[i];
- }
-
- // Value needs to be saved for next time.
- phase.setValue(currentPhase);
- }
-
-}
diff --git a/src/com/jsyn/unitgen/Grain.java b/src/com/jsyn/unitgen/Grain.java
deleted file mode 100644
index 812061c..0000000
--- a/src/com/jsyn/unitgen/Grain.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright 2011 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;
-
-/**
- * A single Grain that is normally created and controlled by a GrainFarm.
- *
- * @author Phil Burk (C) 2011 Mobileer Inc
- */
-public class Grain implements GrainEnvelope {
- private double frameRate;
- private double amplitude = 1.0;
-
- private GrainSource source;
- private GrainEnvelope envelope;
-
- public Grain(GrainSource source, GrainEnvelope envelope) {
- this.source = source;
- this.envelope = envelope;
- }
-
- @Override
- public double next() {
- if (envelope.hasMoreValues()) {
- double env = envelope.next();
- return source.next() * env * amplitude;
- } else {
- return 0.0;
- }
- }
-
- @Override
- public boolean hasMoreValues() {
- return envelope.hasMoreValues();
- }
-
- @Override
- public void reset() {
- source.reset();
- envelope.reset();
- }
-
- public void setRate(double rate) {
- source.setRate(rate);
- }
-
- @Override
- public void setDuration(double duration) {
- envelope.setDuration(duration);
- }
-
- @Override
- public double getFrameRate() {
- return frameRate;
- }
-
- @Override
- public void setFrameRate(double frameRate) {
- this.frameRate = frameRate;
- source.setFrameRate(frameRate);
- envelope.setFrameRate(frameRate);
- }
-
- public double getAmplitude() {
- return amplitude;
- }
-
- public void setAmplitude(double amplitude) {
- this.amplitude = amplitude;
- }
-
- public GrainSource getSource() {
- return source;
- }
-}
diff --git a/src/com/jsyn/unitgen/GrainCommon.java b/src/com/jsyn/unitgen/GrainCommon.java
deleted file mode 100644
index a7a04fc..0000000
--- a/src/com/jsyn/unitgen/GrainCommon.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2009 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;
-
-public class GrainCommon {
- protected double frameRate;
-
- public double getFrameRate() {
- return frameRate;
- }
-
- public void setFrameRate(double frameRate) {
- this.frameRate = frameRate;
- }
-
- public void reset() {
- }
-}
diff --git a/src/com/jsyn/unitgen/GrainEnvelope.java b/src/com/jsyn/unitgen/GrainEnvelope.java
deleted file mode 100644
index e6ff24c..0000000
--- a/src/com/jsyn/unitgen/GrainEnvelope.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2011 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;
-
-/**
- * This envelope should start at 0.0, go up to 1.0 and then return to 0.0 in duration time.
- *
- * @author Phil Burk (C) 2011 Mobileer Inc
- */
-public interface GrainEnvelope {
-
- double getFrameRate();
-
- void setFrameRate(double frameRate);
-
- /**
- * @return next amplitude value of envelope
- */
- double next();
-
- /**
- * Are there any more values to be generated in the envelope?
- *
- * @return true if more
- */
- boolean hasMoreValues();
-
- /**
- * Prepare to start a new envelope.
- */
- void reset();
-
- /**
- * @param duration in seconds.
- */
- void setDuration(double duration);
-
-}
diff --git a/src/com/jsyn/unitgen/GrainFarm.java b/src/com/jsyn/unitgen/GrainFarm.java
deleted file mode 100644
index 78179bc..0000000
--- a/src/com/jsyn/unitgen/GrainFarm.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright 2011 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;
-import com.jsyn.ports.UnitOutputPort;
-import com.jsyn.util.PseudoRandom;
-
-/**
- * A unit generator that generates a cloud of sound using multiple Grains. Special thanks to my
- * friend Ross Bencina for his excellent article on Granular Synthesis. Several of his ideas are
- * reflected in this architecture. "Implementing Real-Time Granular Synthesis" by Ross Bencina,
- * Audio Anecdotes III, 2001.
- *
- * <pre><code>
- synth.add( sampleGrainFarm = new GrainFarm() );
- grainFarm.allocate( NUM_GRAINS );
-</code></pre>
- *
- * @author Phil Burk (C) 2011 Mobileer Inc
- * @see Grain
- * @see GrainSourceSine
- * @see RaisedCosineEnvelope
- */
-public class GrainFarm extends UnitGenerator implements UnitSource {
- /** A scaler for playback rate. Nominally 1.0. */
- public UnitInputPort rate;
- public UnitInputPort rateRange;
- public UnitInputPort amplitude;
- public UnitInputPort amplitudeRange;
- public UnitInputPort density;
- public UnitInputPort duration;
- public UnitInputPort durationRange;
- public UnitOutputPort output;
-
- PseudoRandom randomizer;
- private GrainState[] states;
- private double countScaler = 1.0;
- private final GrainScheduler scheduler = new StochasticGrainScheduler();
-
- public GrainFarm() {
- randomizer = new PseudoRandom();
- addPort(rate = new UnitInputPort("Rate", 1.0));
- addPort(amplitude = new UnitInputPort("Amplitude", 1.0));
- addPort(duration = new UnitInputPort("Duration", 0.01));
- addPort(rateRange = new UnitInputPort("RateRange", 0.0));
- addPort(amplitudeRange = new UnitInputPort("AmplitudeRange", 0.0));
- addPort(durationRange = new UnitInputPort("DurationRange", 0.0));
- addPort(density = new UnitInputPort("Density", 0.1));
- addPort(output = new UnitOutputPort());
- }
-
- private class GrainState {
- Grain grain;
- int countdown;
- double lastDuration;
- final static int STATE_IDLE = 0;
- final static int STATE_GAP = 1;
- final static int STATE_RUNNING = 2;
- int state = STATE_IDLE;
- private double gapError;
-
- public double next(int i) {
- double output = 0.0;
- if (state == STATE_RUNNING) {
- if (grain.hasMoreValues()) {
- output = grain.next();
- } else {
- startGap(i);
- }
- } else if (state == STATE_GAP) {
- if (countdown > 0) {
- countdown -= 1;
- } else if (countdown == 0) {
- state = STATE_RUNNING;
- grain.reset();
-
- setupGrain(grain, i);
-
- double dur = nextDuration(i);
- grain.setDuration(dur);
- }
- } else if (state == STATE_IDLE) {
- nextDuration(i); // initialize lastDuration
- startGap(i);
- }
- return output;
- }
-
- private double nextDuration(int i) {
- double dur = duration.getValues()[i];
- dur = scheduler.nextDuration(dur);
- lastDuration = dur;
- return dur;
- }
-
- private void startGap(int i) {
- state = STATE_GAP;
- double dens = density.getValues()[i];
- double gap = scheduler.nextGap(lastDuration, dens) * getFrameRate();
- gap += gapError;
- countdown = (int) gap;
- gapError = gap - countdown;
- }
- }
-
- public void setGrainArray(Grain[] grains) {
- countScaler = 1.0 / grains.length;
- states = new GrainState[grains.length];
- for (int i = 0; i < states.length; i++) {
- states[i] = new GrainState();
- states[i].grain = grains[i];
- grains[i].setFrameRate(getSynthesisEngine().getFrameRate());
- }
- }
-
- public void setupGrain(Grain grain, int i) {
- double temp = rate.getValues()[i] * calculateOctaveScaler(rateRange.getValues()[i]);
- grain.setRate(temp);
-
- // Scale the amplitude range so that we never go above
- // original amplitude.
- double base = amplitude.getValues()[i];
- double offset = base * Math.random() * amplitudeRange.getValues()[i];
- grain.setAmplitude(base - offset);
- }
-
- public void allocate(int numGrains) {
- Grain[] grainArray = new Grain[numGrains];
- for (int i = 0; i < numGrains; i++) {
- Grain grain = new Grain(new GrainSourceSine(), new RaisedCosineEnvelope());
- grainArray[i] = grain;
- }
- setGrainArray(grainArray);
- }
-
- @Override
- public UnitOutputPort getOutput() {
- return output;
- }
-
- private double calculateOctaveScaler(double rangeValue) {
- double octaveRange = 0.5 * randomizer.nextRandomDouble() * rangeValue;
- return Math.pow(2.0, octaveRange);
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] outputs = output.getValues();
- double[] amplitudes = amplitude.getValues();
- // double frp = getSynthesisEngine().getFramePeriod();
- for (int i = start; i < limit; i++) {
- double result = 0.0;
-
- // Mix the grains together.
- for (GrainState grainState : states) {
- result += grainState.next(i);
- }
-
- outputs[i] = result * amplitudes[i] * countScaler;
- }
-
- }
-}
diff --git a/src/com/jsyn/unitgen/GrainScheduler.java b/src/com/jsyn/unitgen/GrainScheduler.java
deleted file mode 100644
index df9c25e..0000000
--- a/src/com/jsyn/unitgen/GrainScheduler.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2011 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;
-
-/**
- * Defines a class that can schedule the execution of Grains in a GrainFarm. This is mostly for
- * internal use.
- *
- * @author Phil Burk (C) 2011 Mobileer Inc
- */
-public interface GrainScheduler {
-
- /**
- * Calculate time in seconds for the next gap between grains.
- *
- * @param duration
- * @param density
- * @return seconds before next grain
- */
- double nextGap(double duration, double density);
-
- /**
- * Calculate duration in seconds for the next grains.
- *
- * @param suggestedDuration
- * @return duration of grain seconds
- */
- double nextDuration(double suggestedDuration);
-
-}
diff --git a/src/com/jsyn/unitgen/GrainSource.java b/src/com/jsyn/unitgen/GrainSource.java
deleted file mode 100644
index 1d5c522..0000000
--- a/src/com/jsyn/unitgen/GrainSource.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2011 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;
-
-/**
- * Defines classes that can provide the signal inside a Grain.
- *
- * @author Phil Burk (C) 2011 Mobileer Inc
- */
-public interface GrainSource {
- double getFrameRate();
-
- void setFrameRate(double frameRate);
-
- /** Generate one more value or the source signal. */
- double next();
-
- /** Reset the internal phase of the grain. */
- void reset();
-
- void setRate(double rate);
-}
diff --git a/src/com/jsyn/unitgen/GrainSourceSine.java b/src/com/jsyn/unitgen/GrainSourceSine.java
deleted file mode 100644
index 0af9cbd..0000000
--- a/src/com/jsyn/unitgen/GrainSourceSine.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 2011 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;
-
-/**
- * A simple sine wave generator for a Grain. This uses the same fast Taylor expansion that the
- * SineOscillator uses.
- *
- * @author Phil Burk (C) 2011 Mobileer Inc
- */
-public class GrainSourceSine extends GrainCommon implements GrainSource {
- protected double phase;
- protected double phaseIncrement;
-
- public GrainSourceSine() {
- setRate(1.0);
- }
-
- public void setPhaseIncrement(double phaseIncrement) {
- this.phaseIncrement = phaseIncrement;
- }
-
- @Override
- public double next() {
- phase += phaseIncrement;
- if (phase > 1.0) {
- phase -= 2.0;
- }
- return SineOscillator.fastSin(phase);
- }
-
- @Override
- public void setRate(double rate) {
- setPhaseIncrement(rate * 0.1 / Math.PI);
- }
-
-}
diff --git a/src/com/jsyn/unitgen/IFFT.java b/src/com/jsyn/unitgen/IFFT.java
deleted file mode 100644
index 307acd2..0000000
--- a/src/com/jsyn/unitgen/IFFT.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2013 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;
-
-/**
- * Periodically transform the complex input spectrum using an IFFT to a complex signal stream.
- *
- * @author Phil Burk (C) 2013 Mobileer Inc
- * @version 016
- * @see FFT
- */
-public class IFFT extends FFTBase {
-
- public IFFT() {
- super();
- }
-
- @Override
- protected int getSign() {
- return -1; // -1 for IFFT
- }
-}
diff --git a/src/com/jsyn/unitgen/ImpulseOscillator.java b/src/com/jsyn/unitgen/ImpulseOscillator.java
deleted file mode 100644
index 8c676f3..0000000
--- a/src/com/jsyn/unitgen/ImpulseOscillator.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2009 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;
-
-/**
- * Narrow impulse oscillator. An impulse is only one sample wide. It is useful for pinging filters
- * or generating an "impulse response".
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public class ImpulseOscillator extends UnitOscillator {
-
- @Override
- public void generate(int start, int limit) {
- double[] frequencies = frequency.getValues();
- double[] amplitudes = amplitude.getValues();
- double[] outputs = output.getValues();
-
- // Variables have a single value.
- double currentPhase = phase.getValue();
-
- double inverseNyquist = synthesisEngine.getInverseNyquist();
-
- for (int i = start; i < limit; i++) {
- /* Generate sawtooth phasor to provide phase for impulse generation. */
- double phaseIncrement = frequencies[i] * inverseNyquist;
- currentPhase += phaseIncrement;
-
- double ampl = amplitudes[i];
- double result = 0.0;
- if (currentPhase >= 1.0) {
- currentPhase -= 2.0;
- result = ampl;
- } else if (currentPhase < -1.0) {
- currentPhase += 2.0;
- result = ampl;
- }
- outputs[i] = result;
- }
-
- // Value needs to be saved for next time.
- phase.setValue(currentPhase);
- }
-
-}
diff --git a/src/com/jsyn/unitgen/ImpulseOscillatorBL.java b/src/com/jsyn/unitgen/ImpulseOscillatorBL.java
deleted file mode 100644
index 23686b8..0000000
--- a/src/com/jsyn/unitgen/ImpulseOscillatorBL.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2009 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.engine.MultiTable;
-
-/**
- * Impulse oscillator created by differentiating a sawtoothBL. A band limited impulse is very narrow
- * but is slightly wider than one sample.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public class ImpulseOscillatorBL extends SawtoothOscillatorBL {
- private double previous = 0.0;
-
- @Override
- protected double generateBL(MultiTable multiTable, double currentPhase,
- double positivePhaseIncrement, double flevel, int i) {
- double saw = multiTable.calculateSawtooth(currentPhase, positivePhaseIncrement, flevel);
- double result = previous - saw;
- previous = saw;
- return result;
- }
-
-}
diff --git a/src/com/jsyn/unitgen/Integrate.java b/src/com/jsyn/unitgen/Integrate.java
deleted file mode 100644
index b5beea9..0000000
--- a/src/com/jsyn/unitgen/Integrate.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * 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;
-import com.jsyn.ports.UnitOutputPort;
-
-/**
- * IntegrateUnit unit.
- * <P>
- * Output accumulated sum of the input signal. This can be used to transform one signal into
- * another, or to generate ramps between the limits by setting the input signal positive or
- * negative. For a "leaky integrator" use a FilterOnePoleOneZero.
- * <P>
- *
- * <pre>
- * output = output + input;
- * if (output &lt; lowerLimit)
- * output = lowerLimit;
- * else if (output &gt; upperLimit)
- * output = upperLimit;
- * </pre>
- *
- * @author (C) 1997-2011 Phil Burk, Mobileer Inc
- * @see FilterOnePoleOneZero
- */
-public class Integrate extends UnitGenerator {
- public UnitInputPort input;
- /**
- * Output will be stopped internally from going below this value. Default is -1.0.
- */
- public UnitInputPort lowerLimit;
- /**
- * Output will be stopped internally from going above this value. Default is +1.0.
- */
- public UnitInputPort upperLimit;
- public UnitOutputPort output;
-
- private double accum;
-
- /* Define Unit Ports used by connect() and set(). */
- public Integrate() {
- addPort(input = new UnitInputPort("Input"));
- addPort(lowerLimit = new UnitInputPort("LowerLimit", -1.0));
- addPort(upperLimit = new UnitInputPort("UpperLimit", 1.0));
- addPort(output = new UnitOutputPort("Output"));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] inputs = input.getValues();
- double[] lowerLimits = lowerLimit.getValues();
- double[] upperLimits = upperLimit.getValues();
- double[] outputs = output.getValues();
-
- for (int i = start; i < limit; i++) {
- accum += inputs[i]; // INTEGRATE
-
- // clip to limits
- if (accum > upperLimits[i])
- accum = upperLimits[i];
- else if (accum < lowerLimits[i])
- accum = lowerLimits[i];
-
- outputs[i] = accum;
- }
- }
-}
diff --git a/src/com/jsyn/unitgen/InterpolatingDelay.java b/src/com/jsyn/unitgen/InterpolatingDelay.java
deleted file mode 100644
index 24de4f9..0000000
--- a/src/com/jsyn/unitgen/InterpolatingDelay.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * 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;
- }
-
- }
-
-}
diff --git a/src/com/jsyn/unitgen/Latch.java b/src/com/jsyn/unitgen/Latch.java
deleted file mode 100644
index 0518f69..0000000
--- a/src/com/jsyn/unitgen/Latch.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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;
-
-/**
- * Latch or hold an input value.
- * <p>
- * Pass a value unchanged if gate true, otherwise output held value.
- * <p>
- * output = ( gate &gt; 0.0 ) ? input : previous_output;
- *
- * @author (C) 1997-2010 Phil Burk, Mobileer Inc
- * @see EdgeDetector
- */
-public class Latch extends UnitFilter {
- public UnitInputPort gate;
- private double held;
-
- /* Define Unit Ports used by connect() and set(). */
- public Latch() {
- addPort(gate = new UnitInputPort("Gate"));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] inputs = input.getValues();
- double[] gates = gate.getValues();
- double[] outputs = output.getValues();
-
- for (int i = start; i < limit; i++) {
- if (gates[i] > 0.0) {
- held = inputs[i];
- }
- outputs[i] = held;
- }
- }
-}
diff --git a/src/com/jsyn/unitgen/LatchZeroCrossing.java b/src/com/jsyn/unitgen/LatchZeroCrossing.java
deleted file mode 100644
index 9e6c011..0000000
--- a/src/com/jsyn/unitgen/LatchZeroCrossing.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright 2010 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;
-import com.jsyn.ports.UnitOutputPort;
-
-/**
- * Latches when input crosses zero.
- * <P>
- * Pass a value unchanged if gate true, otherwise pass input unchanged until input crosses zero then
- * output zero. This can be used to turn off a sound at a zero crossing so there is no pop.
- * <P>
- *
- * @author (C) 2010 Phil Burk, Mobileer Inc
- * @see Latch
- * @see Minimum
- */
-public class LatchZeroCrossing extends UnitGenerator {
- public UnitInputPort input;
- public UnitInputPort gate;
- public UnitOutputPort output;
- private double held;
- private boolean crossed;
-
- /* Define Unit Ports used by connect() and set(). */
- public LatchZeroCrossing() {
- addPort(input = new UnitInputPort("Input"));
- addPort(gate = new UnitInputPort("Gate", 1.0));
- addPort(output = new UnitOutputPort("Output"));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] inputs = input.getValues();
- double[] gates = gate.getValues();
- double[] outputs = output.getValues();
-
- for (int i = start; i < limit; i++) {
- double current = inputs[i];
- if (gates[i] > 0.0) {
- held = current;
- crossed = false;
- } else {
- // If we haven't already seen a zero crossing then look for one.
- if (!crossed) {
- if ((held * current) <= 0.0) {
- held = 0.0;
- crossed = true;
- } else {
- held = current;
- }
- }
- }
- outputs[i] = held;
- }
- }
-}
diff --git a/src/com/jsyn/unitgen/LineIn.java b/src/com/jsyn/unitgen/LineIn.java
deleted file mode 100644
index aeef965..0000000
--- a/src/com/jsyn/unitgen/LineIn.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 2009 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.Synthesizer;
-import com.jsyn.ports.UnitOutputPort;
-
-/**
- * External audio input is sent to the output of this unit. The LineIn provides a stereo signal
- * containing channels 0 and 1. For LineIn to work you must call the Synthesizer start() method with
- * numInputChannels &gt; 0.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- * @see Synthesizer
- * @see ChannelIn
- * @see LineOut
- */
-public class LineIn extends UnitGenerator {
- public UnitOutputPort output;
-
- public LineIn() {
- addPort(output = new UnitOutputPort(2, "Output"));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] outputs0 = output.getValues(0);
- double[] outputs1 = output.getValues(1);
- double[] buffer0 = synthesisEngine.getInputBuffer(0);
- double[] buffer1 = synthesisEngine.getInputBuffer(1);
- for (int i = start; i < limit; i++) {
- outputs0[i] = buffer0[i];
- outputs1[i] = buffer1[i];
- }
- }
-
-}
diff --git a/src/com/jsyn/unitgen/LineOut.java b/src/com/jsyn/unitgen/LineOut.java
deleted file mode 100644
index 29c8ce7..0000000
--- a/src/com/jsyn/unitgen/LineOut.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2009 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;
-
-/**
- * Input audio is sent to the external audio output device.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public class LineOut extends UnitGenerator implements UnitSink {
- public UnitInputPort input;
-
- public LineOut() {
- addPort(input = new UnitInputPort(2, "Input"));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] inputs0 = input.getValues(0);
- double[] inputs1 = input.getValues(1);
- double[] buffer0 = synthesisEngine.getOutputBuffer(0);
- double[] buffer1 = synthesisEngine.getOutputBuffer(1);
- for (int i = start; i < limit; i++) {
- buffer0[i] += inputs0[i];
- buffer1[i] += inputs1[i];
- }
- }
-
- /**
- * This unit won't do anything unless you start() it.
- */
- @Override
- public boolean isStartRequired() {
- return true;
- }
-
- @Override
- public UnitInputPort getInput() {
- return input;
- }
-}
diff --git a/src/com/jsyn/unitgen/LinearRamp.java b/src/com/jsyn/unitgen/LinearRamp.java
deleted file mode 100644
index cad53d5..0000000
--- a/src/com/jsyn/unitgen/LinearRamp.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * 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;
-import com.jsyn.ports.UnitVariablePort;
-
-/**
- * Output approaches Input linearly.
- * <P>
- * When you change the value of the input port, the ramp will start changing from its current output
- * value toward the value of input. An internal phase value will go from 0.0 to 1.0 at a rate
- * controlled by time. When the internal phase reaches 1.0, the output will equal input.
- * <P>
- *
- * @author (C) 1997 Phil Burk, SoftSynth.com
- * @see ExponentialRamp
- * @see AsymptoticRamp
- * @see ContinuousRamp
- */
-public class LinearRamp extends UnitFilter {
- /** Time in seconds to get to the input value. */
- public UnitInputPort time;
- public UnitVariablePort current;
-
- private double source;
- private double phase;
- private double target;
- private double timeHeld = 0.0;
- private double rate = 1.0;
-
- public LinearRamp() {
- addPort(time = new UnitInputPort("Time"));
- addPort(current = new UnitVariablePort("Current"));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] outputs = output.getValues();
- double currentInput = input.getValues()[0];
- double currentValue = current.getValue();
-
- // If input has changed, start new segment.
- // Equality check is OK because we set them exactly equal below.
- if (currentInput != target)
- {
- source = currentValue;
- phase = 0.0;
- target = currentInput;
- }
-
- if (currentValue == target) {
- // at end of ramp
- for (int i = start; i < limit; i++) {
- outputs[i] = currentValue;
- }
- } else {
- // in middle of ramp
- double currentTime = time.getValues()[0];
- // Has time changed?
- if (currentTime != timeHeld) {
- rate = convertTimeToRate(currentTime);
- timeHeld = currentTime;
- }
-
- for (int i = start; i < limit; i++) {
- if (phase < 1.0) {
- /* Interpolate current. */
- currentValue = source + (phase * (target - source));
- phase += rate;
- } else {
- currentValue = target;
- }
- outputs[i] = currentValue;
- }
- }
-
- current.setValue(currentValue);
- }
-}
diff --git a/src/com/jsyn/unitgen/Maximum.java b/src/com/jsyn/unitgen/Maximum.java
deleted file mode 100644
index 296e5da..0000000
--- a/src/com/jsyn/unitgen/Maximum.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2009 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;
-
-/**
- *
- Output largest of inputA or inputB.
- *
- * <pre>
- * output = (inputA &gt; InputB) ? inputA : InputB;
- * </pre>
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- * @version 016
- * @see Minimum
- */
-public class Maximum extends UnitBinaryOperator {
- @Override
- public void generate(int start, int limit) {
- double[] aValues = inputA.getValues();
- double[] bValues = inputB.getValues();
- double[] outputs = output.getValues();
-
- for (int i = start; i < limit; i++) {
- outputs[i] = (aValues[i] > bValues[i]) ? aValues[i] : bValues[i];
- }
- }
-}
diff --git a/src/com/jsyn/unitgen/Minimum.java b/src/com/jsyn/unitgen/Minimum.java
deleted file mode 100644
index 046387e..0000000
--- a/src/com/jsyn/unitgen/Minimum.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2009 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;
-
-/**
- *
- Output smallest of inputA or inputB.
- *
- * <pre>
- * output = (inputA &lt; InputB) ? inputA : InputB;
- * </pre>
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- * @version 016
- * @see Maximum
- */
-public class Minimum extends UnitBinaryOperator {
-
- @Override
- public void generate(int start, int limit) {
- double[] aValues = inputA.getValues();
- double[] bValues = inputB.getValues();
- double[] outputs = output.getValues();
-
- for (int i = start; i < limit; i++) {
- outputs[i] = (aValues[i] < bValues[i]) ? aValues[i] : bValues[i];
- }
- }
-}
diff --git a/src/com/jsyn/unitgen/MixerMono.java b/src/com/jsyn/unitgen/MixerMono.java
deleted file mode 100644
index f4c7d7d..0000000
--- a/src/com/jsyn/unitgen/MixerMono.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright 2014 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;
-import com.jsyn.ports.UnitOutputPort;
-
-/**
- * Multi-channel mixer with mono output and master amplitude.
- *
- * @author Phil Burk (C) 2014 Mobileer Inc
- * @see MixerMonoRamped
- * @see MixerStereo
- */
-public class MixerMono extends UnitGenerator implements UnitSink, UnitSource {
- public UnitInputPort input;
- /**
- * Linear gain for the corresponding input.
- */
- public UnitInputPort gain;
- /**
- * Master gain control.
- */
- public UnitInputPort amplitude;
- public UnitOutputPort output;
-
- public MixerMono(int numInputs) {
- addPort(input = new UnitInputPort(numInputs, "Input"));
- addPort(gain = new UnitInputPort(numInputs, "Gain", 1.0));
- addPort(amplitude = new UnitInputPort("Amplitude", 1.0));
- addPort(output = new UnitOutputPort(getNumOutputs(), "Output"));
- }
-
- public int getNumOutputs() {
- return 1;
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] amplitudes = amplitude.getValues(0);
- double[] outputs = output.getValues(0);
- for (int i = start; i < limit; i++) {
- double sum = 0;
- for (int n = 0; n < input.getNumParts(); n++) {
- double[] inputs = input.getValues(n);
- double[] gains = gain.getValues(n);
- sum += inputs[i] * gains[i];
- }
- outputs[i] = sum * amplitudes[i];
- }
- }
-
- @Override
- public UnitInputPort getInput() {
- return input;
- }
-
- @Override
- public UnitOutputPort getOutput() {
- return output;
- }
-
-}
diff --git a/src/com/jsyn/unitgen/MixerMonoRamped.java b/src/com/jsyn/unitgen/MixerMonoRamped.java
deleted file mode 100644
index 30f5342..0000000
--- a/src/com/jsyn/unitgen/MixerMonoRamped.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright 2014 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;
-
-/**
- * Similar to MixerMono but the gain and amplitude ports are smoothed using short linear ramps. So
- * you can control them with knobs and not hear any zipper noise.
- *
- * @author Phil Burk (C) 2014 Mobileer Inc
- */
-public class MixerMonoRamped extends MixerMono {
- private Unzipper[] unzippers;
- private Unzipper amplitudeUnzipper;
-
- public MixerMonoRamped(int numInputs) {
- super(numInputs);
- unzippers = new Unzipper[numInputs];
- for (int i = 0; i < numInputs; i++) {
- unzippers[i] = new Unzipper();
- }
- amplitudeUnzipper = new Unzipper();
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] amplitudes = amplitude.getValues(0);
- double[] outputs = output.getValues(0);
- for (int i = start; i < limit; i++) {
- double sum = 0;
- for (int n = 0; n < input.getNumParts(); n++) {
- double[] inputs = input.getValues(n);
- double[] gains = gain.getValues(n);
- double smoothGain = unzippers[n].smooth(gains[i]);
- sum += inputs[i] * smoothGain;
- }
- outputs[i] = sum * amplitudeUnzipper.smooth(amplitudes[i]);
- }
- }
-
-}
diff --git a/src/com/jsyn/unitgen/MixerStereo.java b/src/com/jsyn/unitgen/MixerStereo.java
deleted file mode 100644
index 218546e..0000000
--- a/src/com/jsyn/unitgen/MixerStereo.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright 2014 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;
-
-/**
- * Mixer with monophonic inputs and two channels of output. Each signal can be panned left or right
- * using an equal power curve. The "left" signal will be on output part zero. The "right" signal
- * will be on output part one.
- *
- * @author Phil Burk (C) 2014 Mobileer Inc
- * @see MixerMono
- * @see MixerStereoRamped
- */
-public class MixerStereo extends MixerMono {
- /**
- * Set to -1.0 for all left channel, 0.0 for center, or +1.0 for all right. Or anywhere in
- * between.
- */
- public UnitInputPort pan;
- protected PanTracker[] panTrackers;
-
- static class PanTracker {
- double previousPan = Double.MAX_VALUE; // so we update immediately
- double leftGain;
- double rightGain;
-
- public void update(double pan) {
- if (pan != previousPan) {
- // fastSine range is -1.0 to +1.0 for full cycle.
- // We want a quarter cycle. So map -1.0 to +1.0 into 0.0 to 0.5
- double phase = pan * 0.25 + 0.25;
- leftGain = SineOscillator.fastSin(0.5 - phase);
- rightGain = SineOscillator.fastSin(phase);
- previousPan = pan;
- }
- }
- }
-
- public MixerStereo(int numInputs) {
- super(numInputs);
- addPort(pan = new UnitInputPort(numInputs, "Pan"));
- pan.setup(-1.0, 0.0, 1.0);
- panTrackers = new PanTracker[numInputs];
- for (int i = 0; i < numInputs; i++) {
- panTrackers[i] = new PanTracker();
- }
- }
-
- @Override
- public int getNumOutputs() {
- return 2;
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] amplitudes = amplitude.getValues(0);
- double[] outputs0 = output.getValues(0);
- double[] outputs1 = output.getValues(1);
- for (int i = start; i < limit; i++) {
- double sum0 = 0.0;
- double sum1 = 0.0;
- for (int n = 0; n < input.getNumParts(); n++) {
- double[] inputs = input.getValues(n);
- double[] gains = gain.getValues(n);
- double[] pans = pan.getValues(n);
- PanTracker panTracker = panTrackers[n];
- panTracker.update(pans[i]);
- double scaledInput = inputs[i] * gains[i];
- sum0 += scaledInput * panTracker.leftGain;
- sum1 += scaledInput * panTracker.rightGain;
- }
- double amp = amplitudes[i];
- outputs0[i] = sum0 * amp;
- outputs1[i] = sum1 * amp;
- }
- }
-
-}
diff --git a/src/com/jsyn/unitgen/MixerStereoRamped.java b/src/com/jsyn/unitgen/MixerStereoRamped.java
deleted file mode 100644
index 6f3bfcc..0000000
--- a/src/com/jsyn/unitgen/MixerStereoRamped.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright 2014 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;
-
-/**
- * Similar to MixerStereo but the gain, pan and amplitude ports are smoothed using short linear
- * ramps. So you can control them with knobs and not hear any zipper noise.
- *
- * @author Phil Burk (C) 2014 Mobileer Inc
- */
-public class MixerStereoRamped extends MixerStereo {
- private Unzipper[] gainUnzippers;
- private Unzipper[] panUnzippers;
- private Unzipper amplitudeUnzipper;
-
- public MixerStereoRamped(int numInputs) {
- super(numInputs);
- gainUnzippers = new Unzipper[numInputs];
- for (int i = 0; i < numInputs; i++) {
- gainUnzippers[i] = new Unzipper();
- }
- panUnzippers = new Unzipper[numInputs];
- for (int i = 0; i < numInputs; i++) {
- panUnzippers[i] = new Unzipper();
- }
- amplitudeUnzipper = new Unzipper();
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] amplitudes = amplitude.getValues(0);
- double[] outputs0 = output.getValues(0);
- double[] outputs1 = output.getValues(1);
- for (int i = start; i < limit; i++) {
- double sum0 = 0;
- double sum1 = 0;
- for (int n = 0; n < input.getNumParts(); n++) {
- double[] inputs = input.getValues(n);
- double[] gains = gain.getValues(n);
- double[] pans = pan.getValues(n);
-
- PanTracker panTracker = panTrackers[n];
- double smoothPan = panUnzippers[n].smooth(pans[i]);
- panTracker.update(smoothPan);
-
- double smoothGain = gainUnzippers[n].smooth(gains[i]);
- double scaledInput = inputs[i] * smoothGain;
- sum0 += scaledInput * panTracker.leftGain;
- sum1 += scaledInput * panTracker.rightGain;
- }
- double amp = amplitudeUnzipper.smooth(amplitudes[i]);
- outputs0[i] = sum0 * amp;
- outputs1[i] = sum1 * amp;
- }
- }
-
-}
diff --git a/src/com/jsyn/unitgen/MonoStreamWriter.java b/src/com/jsyn/unitgen/MonoStreamWriter.java
deleted file mode 100644
index 283af81..0000000
--- a/src/com/jsyn/unitgen/MonoStreamWriter.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright 2009 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 java.io.IOException;
-
-import com.jsyn.io.AudioOutputStream;
-import com.jsyn.ports.UnitInputPort;
-
-/**
- * Write one sample per audio frame to an AudioOutputStream with no interpolation.
- *
- * Note that you must call start() on this unit because it does not have an output for pulling data.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public class MonoStreamWriter extends UnitStreamWriter {
- public MonoStreamWriter() {
- addPort(input = new UnitInputPort("Input"));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] inputs = input.getValues();
- AudioOutputStream output = outputStream;
- if (output != null) {
- int count = limit - start;
- try {
- output.write(inputs, start, count);
- } catch (IOException e) {
- }
- }
- }
-
-}
diff --git a/src/com/jsyn/unitgen/MorphingOscillatorBL.java b/src/com/jsyn/unitgen/MorphingOscillatorBL.java
deleted file mode 100644
index 7ca440d..0000000
--- a/src/com/jsyn/unitgen/MorphingOscillatorBL.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright 2009 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.engine.MultiTable;
-import com.jsyn.ports.UnitInputPort;
-
-/**
- * Oscillator that can change its shape from sine to sawtooth to pulse.
- *
- * @author Phil Burk (C) 2016 Mobileer Inc
- */
-public class MorphingOscillatorBL extends PulseOscillatorBL {
- /**
- * Controls the shape of the waveform.
- * The shape varies continuously from a sine wave at -1.0,
- * to a sawtooth at 0.0 to a pulse wave at 1.0.
- */
- public UnitInputPort shape;
-
- public MorphingOscillatorBL() {
- addPort(shape = new UnitInputPort("Shape"));
- shape.setMinimum(-1.0);
- shape.setMaximum(1.0);
- }
-
- @Override
- protected double generateBL(MultiTable multiTable, double currentPhase,
- double positivePhaseIncrement, double flevel, int i) {
- double[] shapes = shape.getValues();
- double shape = shapes[i];
-
- if (shape < 0.0) {
- // Squeeze flevel towards the pure sine table.
- flevel += flevel * shape;
- return multiTable.calculateSawtooth(currentPhase, positivePhaseIncrement, flevel);
- } else {
- double[] widths = width.getValues();
- double width = widths[i];
- width = (width > 0.999) ? 0.999 : ((width < -0.999) ? -0.999 : width);
-
- double val1 = multiTable.calculateSawtooth(currentPhase, positivePhaseIncrement, flevel);
- // Generate second sawtooth so we can add them together.
- double phase2 = currentPhase + 1.0 - width; // 180 degrees out of phase
- if (phase2 >= 1.0) {
- phase2 -= 2.0;
- }
- double val2 = multiTable.calculateSawtooth(phase2, positivePhaseIncrement, flevel);
-
- /*
- * Need to adjust amplitude based on positive phaseInc. little less than half at
- * Nyquist/2.0!
- */
- double scale = 1.0 - positivePhaseIncrement;
- return scale * (val1 - ((val2 + width) * shape)); // apply shape morphing
- }
- }
-}
diff --git a/src/com/jsyn/unitgen/MultiPassThrough.java b/src/com/jsyn/unitgen/MultiPassThrough.java
deleted file mode 100644
index 9125fc3..0000000
--- a/src/com/jsyn/unitgen/MultiPassThrough.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright 2011 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;
-import com.jsyn.ports.UnitOutputPort;
-
-/**
- * Pass the input through to the output unchanged. This is often used for distributing a signal to
- * multiple ports inside a circuit. It can also be used as a summing node, in other words, a mixer.
- *
- * This is just like PassThrough except the input and output ports have multiple parts.
- * The default is two parts, ie. stereo.
- *
- * @author Phil Burk (C) 2016 Mobileer Inc
- * @see Circuit
- * @see PassThrough
- */
-public class MultiPassThrough extends UnitGenerator implements UnitSink, UnitSource {
- public UnitInputPort input;
- public UnitOutputPort output;
- private final int mNumParts;
-
- /* Define Unit Ports used by connect() and set(). */
- public MultiPassThrough(int numParts) {
- mNumParts = numParts;
- addPort(input = new UnitInputPort(numParts, "Input"));
- addPort(output = new UnitOutputPort(numParts, "Output"));
- }
-
- public MultiPassThrough() {
- this(2); // stereo
- }
-
- @Override
- public UnitInputPort getInput() {
- return input;
- }
-
- @Override
- public UnitOutputPort getOutput() {
- return output;
- }
-
- @Override
- public void generate(int start, int limit) {
- for (int partIndex = 0; partIndex < mNumParts; partIndex++) {
- double[] inputs = input.getValues(partIndex);
- double[] outputs = output.getValues(partIndex);
-
- for (int i = start; i < limit; i++) {
- outputs[i] = inputs[i];
- }
- }
- }
-}
diff --git a/src/com/jsyn/unitgen/Multiply.java b/src/com/jsyn/unitgen/Multiply.java
deleted file mode 100644
index ded7646..0000000
--- a/src/com/jsyn/unitgen/Multiply.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright 2009 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;
-import com.jsyn.ports.UnitOutputPort;
-
-/**
- * This unit multiplies its two inputs. <br>
- *
- * <pre>
- * output = inputA * inputB
- * </pre>
- *
- * <br>
- * Note that some units have an amplitude port, which controls an internal multiply. So you may not
- * need this unit.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- * @version 016
- * @see MultiplyAdd
- * @see Subtract
- */
-public class Multiply extends UnitBinaryOperator {
- public Multiply() {
- }
-
- /** Connect a to inputA and b to inputB. */
- public Multiply(UnitOutputPort a, UnitOutputPort b) {
- a.connect(inputA);
- b.connect(inputB);
- }
-
- /** Connect a to inputA and b to inputB and connect output to c. */
- public Multiply(UnitOutputPort a, UnitOutputPort b, UnitInputPort c) {
- this(a, b);
- output.connect(c);
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] aValues = inputA.getValues();
- double[] bValues = inputB.getValues();
- double[] outputs = output.getValues();
- for (int i = start; i < limit; i++) {
- outputs[i] = aValues[i] * bValues[i];
- }
- }
-
-}
diff --git a/src/com/jsyn/unitgen/MultiplyAdd.java b/src/com/jsyn/unitgen/MultiplyAdd.java
deleted file mode 100644
index adbee6c..0000000
--- a/src/com/jsyn/unitgen/MultiplyAdd.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2009 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;
-import com.jsyn.ports.UnitOutputPort;
-
-/**
- * <pre>
- * output = (inputA * inputB) + inputC
- * </pre>
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- * @version 016
- * @see Multiply
- * @see Add
- */
-public class MultiplyAdd extends UnitGenerator {
- public UnitInputPort inputA;
- public UnitInputPort inputB;
- public UnitInputPort inputC;
- public UnitOutputPort output;
-
- /* Define Unit Ports used by connect() and set(). */
- public MultiplyAdd() {
- addPort(inputA = new UnitInputPort("InputA"));
- addPort(inputB = new UnitInputPort("InputB"));
- addPort(inputC = new UnitInputPort("InputC"));
- addPort(output = new UnitOutputPort("Output"));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] aValues = inputA.getValues();
- double[] bValues = inputB.getValues();
- double[] cValues = inputC.getValues();
- double[] outputs = output.getValues();
- for (int i = start; i < limit; i++) {
- outputs[i] = (aValues[i] * bValues[i]) + cValues[i];
- }
- }
-
-}
diff --git a/src/com/jsyn/unitgen/Pan.java b/src/com/jsyn/unitgen/Pan.java
deleted file mode 100644
index bc90984..0000000
--- a/src/com/jsyn/unitgen/Pan.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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;
-import com.jsyn.ports.UnitOutputPort;
-
-/**
- * Pan unit. The profile is constant amplitude and not constant energy.
- * <P>
- * Takes an input and pans it between two outputs based on value of pan. When pan is -1, output[0]
- * is input, and output[1] is zero. When pan is 0, output[0] and output[1] are both input/2. When
- * pan is +1, output[0] is zero, and output[1] is input.
- * <P>
- *
- * @author (C) 1997 Phil Burk, SoftSynth.com
- * @see Select
- */
-public class Pan extends UnitGenerator {
- public UnitInputPort input;
- /**
- * Pan control varies from -1.0 for full left to +1.0 for full right. Set to 0.0 for center.
- */
- public UnitInputPort pan;
- public UnitOutputPort output;
-
- public Pan() {
- addPort(input = new UnitInputPort("Input"));
- addPort(pan = new UnitInputPort("Pan"));
- addPort(output = new UnitOutputPort(2, "Output"));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] inputs = input.getValues();
- double[] panPtr = pan.getValues();
- double[] outputs_0 = output.getValues(0);
- double[] outputs_1 = output.getValues(1);
-
- for (int i = start; i < limit; i++) {
- double gainB = (panPtr[i] * 0.5) + 0.5; /*
- * Scale and offset to 0.0 to 1.0
- */
- double gainA = 1.0 - gainB;
- double inVal = inputs[i];
- outputs_0[i] = inVal * gainA;
- outputs_1[i] = inVal * gainB;
- }
- }
-}
diff --git a/src/com/jsyn/unitgen/PanControl.java b/src/com/jsyn/unitgen/PanControl.java
deleted file mode 100644
index 63bddd8..0000000
--- a/src/com/jsyn/unitgen/PanControl.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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;
-import com.jsyn.ports.UnitOutputPort;
-
-/**
- * PanControl unit.
- * <P>
- * Generates control signals that can be used to control a mixer or the amplitude ports of two
- * units.
- *
- * <PRE>
- * temp = (pan * 0.5) + 0.5;
- * output[0] = temp;
- * output[1] = 1.0 - temp;
- * </PRE>
- * <P>
- *
- * @author (C) 1997-2009 Phil Burk, SoftSynth.com
- */
-public class PanControl extends UnitGenerator {
- public UnitInputPort pan;
- public UnitOutputPort output;
-
- /* Define Unit Ports used by connect() and set(). */
- public PanControl() {
- addPort(pan = new UnitInputPort("Pan"));
- addPort(output = new UnitOutputPort(2, "Output", 0.0));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] panPtr = pan.getValues();
- double[] output0s = output.getValues(0);
- double[] output1s = output.getValues(1);
-
- for (int i = start; i < limit; i++) {
- double gainB = (panPtr[i] * 0.5) + 0.5; /*
- * Scale and offset to 0.0 to 1.0
- */
- output0s[i] = 1.0 - gainB;
- output1s[i] = gainB;
- }
- }
-}
diff --git a/src/com/jsyn/unitgen/ParabolicEnvelope.java b/src/com/jsyn/unitgen/ParabolicEnvelope.java
deleted file mode 100644
index 6de97d9..0000000
--- a/src/com/jsyn/unitgen/ParabolicEnvelope.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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;
-import com.jsyn.ports.UnitOutputPort;
-
-/**
- * ParabolicEnvelope unit. Output goes from zero to amplitude then back to zero in a parabolic arc.
- * <P>
- * Generate a short parabolic envelope that could be used for granular synthesis. The output starts
- * at zero, peaks at the value of amplitude then returns to zero. This unit has two states, IDLE and
- * RUNNING. If a trigger is received when IDLE, the envelope is started and another trigger is sent
- * out the triggerOutput port. This triggerOutput can be used to latch values for the synthesis of a
- * grain. If a trigger is received when RUNNING, then it is ignored and passed out the triggerPass
- * port. The triggerPass can be connected to the triggerInput of another ParabolicEnvelope. Thus you
- * can implement a simple grain allocation scheme by daisy chaining the triggers of
- * ParabolicEnvelopes.
- * <P>
- * The envelope is generated by a double integrator method so it uses relatively little CPU time.
- *
- * @author (C) 1997 Phil Burk, SoftSynth.com
- * @see EnvelopeDAHDSR
- */
-public class ParabolicEnvelope extends UnitGenerator {
-
- /** Fastest repeat rate of envelope if it were continually retriggered in Hertz. */
- public UnitInputPort frequency;
- /** True value triggers envelope when in resting state. */
- public UnitInputPort triggerInput;
- public UnitInputPort amplitude;
-
- /** Trigger output when envelope started. */
- public UnitOutputPort triggerOutput;
- /** Input trigger passed out if ignored for daisy chaining. */
- public UnitOutputPort triggerPass;
- public UnitOutputPort output;
-
- private double slope;
- private double curve;
- private double level;
- private boolean running;
-
- /* Define Unit Ports used by connect() and set(). */
- public ParabolicEnvelope() {
- addPort(triggerInput = new UnitInputPort("Input"));
- addPort(frequency = new UnitInputPort("Frequency", UnitOscillator.DEFAULT_FREQUENCY));
- addPort(amplitude = new UnitInputPort("Amplitude", UnitOscillator.DEFAULT_AMPLITUDE));
-
- addPort(output = new UnitOutputPort("Output"));
- addPort(triggerOutput = new UnitOutputPort("TriggerOutput"));
- addPort(triggerPass = new UnitOutputPort("TriggerPass"));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] frequencies = frequency.getValues();
- double[] amplitudes = amplitude.getValues();
- double[] triggerInputs = triggerInput.getValues();
- double[] outputs = output.getValues();
- double[] triggerPasses = triggerPass.getValues();
- double[] triggerOutputs = triggerOutput.getValues();
-
- for (int i = start; i < limit; i++) {
- if (!running) {
- if (triggerInputs[i] > 0) {
- double freq = frequencies[i] * synthesisEngine.getInverseNyquist();
- freq = (freq > 1.0) ? 1.0 : ((freq < -1.0) ? -1.0 : freq);
- double ampl = amplitudes[i];
- double freq2 = freq * freq; /* Square frequency. */
- slope = 4.0 * ampl * (freq - freq2);
- curve = -8.0 * ampl * freq2;
- level = 0.0;
- triggerOutputs[i] = UnitGenerator.TRUE;
- running = true;
- } else {
- triggerOutputs[i] = UnitGenerator.FALSE;
- }
- triggerPasses[i] = UnitGenerator.FALSE;
- } else /* RUNNING */
- {
- level += slope;
- slope += curve;
- if (level <= 0.0) {
- level = 0.0;
- running = false;
- /* Autostop? - FIXME */
- }
-
- triggerOutputs[i] = UnitGenerator.FALSE;
- triggerPasses[i] = triggerInputs[i];
- }
- outputs[i] = level;
- }
- }
-}
diff --git a/src/com/jsyn/unitgen/PassThrough.java b/src/com/jsyn/unitgen/PassThrough.java
deleted file mode 100644
index 8ac0b93..0000000
--- a/src/com/jsyn/unitgen/PassThrough.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2011 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;
-
-/**
- * Pass the input through to the output unchanged. This is often used for distributing a signal to
- * multiple ports inside a circuit. It can also be used as a summing node, in other words, a mixer.
- *
- * @author Phil Burk (C) 2011 Mobileer Inc
- * @see Circuit
- * @see MultiPassThrough
- */
-public class PassThrough extends UnitFilter {
- @Override
- public void generate(int start, int limit) {
- double[] inputs = input.getValues();
- double[] outputs = output.getValues();
-
- for (int i = start; i < limit; i++) {
- outputs[i] = inputs[i];
- }
-
- }
-}
diff --git a/src/com/jsyn/unitgen/PeakFollower.java b/src/com/jsyn/unitgen/PeakFollower.java
deleted file mode 100644
index 7bf0508..0000000
--- a/src/com/jsyn/unitgen/PeakFollower.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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;
-import com.jsyn.ports.UnitOutputPort;
-import com.jsyn.ports.UnitVariablePort;
-
-/**
- * Tracks the peaks of an input signal. This can be used to monitor the overall amplitude of a
- * signal. The output can be used to drive color organs, vocoders, VUmeters, etc. Output drops
- * exponentially when the input drops below the current output level. The output approaches zero
- * based on the value on the halfLife port.
- *
- * @author (C) 1997-2009 Phil Burk, SoftSynth.com
- */
-public class PeakFollower extends UnitGenerator {
- public UnitInputPort input;
- public UnitVariablePort current;
- public UnitInputPort halfLife;
- public UnitOutputPort output;
-
- private double previousHalfLife = -1.0;
- private double decayScalar = 0.99;
-
- /* Define Unit Ports used by connect() and set(). */
- public PeakFollower() {
- addPort(input = new UnitInputPort("Input"));
- addPort(halfLife = new UnitInputPort(1, "HalfLife", 0.1));
- addPort(current = new UnitVariablePort("Current"));
- addPort(output = new UnitOutputPort("Output"));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] inputs = input.getValues();
- double[] outputs = output.getValues();
- double currentHalfLife = halfLife.getValues()[0];
- double currentValue = current.getValue();
-
- if (currentHalfLife != previousHalfLife) {
- decayScalar = this.convertHalfLifeToMultiplier(currentHalfLife);
- previousHalfLife = currentHalfLife;
- }
-
- double scalar = 1.0 - decayScalar;
-
- for (int i = start; i < limit; i++) {
- double inputValue = inputs[i];
- if (inputValue < 0.0) {
- inputValue = -inputValue; // absolute value
- }
-
- if (inputValue >= currentValue) {
- currentValue = inputValue;
- } else {
- currentValue = currentValue * scalar;
- }
-
- outputs[i] = currentValue;
- }
-
- /*
- * When current gets close to zero, set current to zero to prevent FP underflow, which can
- * cause a severe performance degradation in 'C'.
- */
- if (currentValue < VERY_SMALL_FLOAT) {
- currentValue = 0.0;
- }
-
- current.setValue(currentValue);
- }
-}
diff --git a/src/com/jsyn/unitgen/PhaseShifter.java b/src/com/jsyn/unitgen/PhaseShifter.java
deleted file mode 100644
index 4b17245..0000000
--- a/src/com/jsyn/unitgen/PhaseShifter.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright 2014 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;
-
-/**
- * PhaseShifter effects processor. This unit emulates a common guitar pedal effect but without the
- * LFO modulation. You can use your own modulation source connected to the "offset" port. Different
- * frequencies are phase shifted varying amounts using a series of AllPass filters. By feeding the
- * output back to the input we can get varying phase cancellation. This implementation was based on
- * code posted to the music-dsp archive by Ross Bencina. http://www.musicdsp.org/files/phaser.cpp
- *
- * @author (C) 2014 Phil Burk, Mobileer Inc
- * @see FilterLowPass
- * @see FilterAllPass
- * @see RangeConverter
- */
-
-public class PhaseShifter extends UnitFilter {
- /**
- * Connect an oscillator to this port to sweep the phase. A range of 0.05 to 0.4 is a good
- * start.
- */
- public UnitInputPort offset;
- public UnitInputPort feedback;
- public UnitInputPort depth;
-
- private double zm1;
- private double[] xs;
- private double[] ys;
-
- public PhaseShifter() {
- this(6);
- }
-
- public PhaseShifter(int numStages) {
- addPort(offset = new UnitInputPort("Offset", 0.1));
- addPort(feedback = new UnitInputPort("Feedback", 0.7));
- addPort(depth = new UnitInputPort("Depth", 1.0));
-
- xs = new double[numStages];
- ys = new double[numStages];
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] inputs = input.getValues();
- double[] outputs = output.getValues();
- double[] feedbacks = feedback.getValues();
- double[] depths = depth.getValues();
- double[] offsets = offset.getValues();
- double gain;
-
- for (int i = start; i < limit; i++) {
- // Support audio rate modulation.
- double currentOffset = offsets[i];
-
- // Prevent gain from exceeding 1.0.
- gain = 1.0 - (currentOffset * currentOffset);
- if (gain < -1.0) {
- gain = -1.0;
- }
-
- double x = inputs[i] + (zm1 * feedbacks[i]);
- // Cascaded all-pass filters.
- for (int stage = 0; stage < xs.length; stage++) {
- double temp = ys[stage] = (gain * (ys[stage] - x)) + xs[stage];
- xs[stage] = x;
- x = temp;
- }
- zm1 = x;
- outputs[i] = inputs[i] + (x * depths[i]);
- }
- }
-}
diff --git a/src/com/jsyn/unitgen/PinkNoise.java b/src/com/jsyn/unitgen/PinkNoise.java
deleted file mode 100644
index 84aa2f2..0000000
--- a/src/com/jsyn/unitgen/PinkNoise.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright 2009 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;
-import com.jsyn.ports.UnitOutputPort;
-import com.jsyn.util.PseudoRandom;
-
-/**
- * Random output with 3dB per octave rolloff providing a soft natural noise sound. Generated using
- * Gardner method. Optimization suggested by James McCartney uses a tree to select which random
- * value to replace.
- *
- * <pre>
- * x x x x x x x x x x x x x x x x
- * x x x x x x x x
- * x x x x
- * x x
- * x
- * </pre>
- *
- * Tree is generated by counting trailing zeros in an increasing index. When the index is zero, no
- * random number is selected. Author: Phil Burk (C) 1996 SoftSynth.com.
- */
-
-public class PinkNoise extends UnitGenerator implements UnitSource {
-
- public UnitInputPort amplitude;
- public UnitOutputPort output;
-
- private final int NUM_ROWS = 16;
- private final int RANDOM_BITS = 24;
- private final int RANDOM_SHIFT = 32 - RANDOM_BITS;
-
- private PseudoRandom randomNum;
- protected double prevNoise, currNoise;
-
- private long[] rows = new long[NUM_ROWS]; // NEXT RANDOM UNSIGNED 32
- private double scalar; // used to scale within range of -1.0 to +1.0
- private int runningSum; // used to optimize summing of generators
- private int index; // incremented with each sample
- private int indexMask; // index wrapped and ANDing with this mask
-
- /* Define Unit Ports used by connect() and set(). */
- public PinkNoise() {
- addPort(amplitude = new UnitInputPort("Amplitude", UnitOscillator.DEFAULT_AMPLITUDE));
- addPort(output = new UnitOutputPort("Output"));
-
- randomNum = new PseudoRandom();
-
- // set up for N rows of generators
- index = 0;
- indexMask = (1 << NUM_ROWS) - 1;
-
- // Calculate maximum possible signed random value. Extra 1 for white
- // noise always added.
- int pmax = (NUM_ROWS + 1) * (1 << (RANDOM_BITS - 1));
- scalar = 1.0 / pmax;
-
- // initialize rows
- for (int i = 0; i < NUM_ROWS; i++) {
- rows[i] = 0;
- }
-
- runningSum = 0;
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] amplitudes = amplitude.getValues();
- double[] outputs = output.getValues();
-
- for (int i = start; i < limit; i++) {
- outputs[i] = generatePinkNoise() * amplitudes[i];
- }
- }
-
- public double generatePinkNoise() {
- index = (index + 1) & indexMask;
-
- // If index is zero, don't update any random values.
- if (index != 0) {
- // Determine how many trailing zeros in PinkIndex.
- // This algorithm will hang of n==0 so test first
- int numZeros = 0;
- int n = index;
-
- while ((n & 1) == 0) {
- n = n >> 1;
- numZeros++;
- }
-
- // Replace the indexed ROWS random value.
- // Subtract and add back to RunningSum instead of adding all the
- // random values together. Only one changes each time.
- runningSum -= rows[numZeros];
- int newRandom = randomNum.nextRandomInteger() >> RANDOM_SHIFT;
- runningSum += newRandom;
- rows[numZeros] = newRandom;
- }
-
- // Add extra white noise value.
- int newRandom = randomNum.nextRandomInteger() >> RANDOM_SHIFT;
- int sum = runningSum + newRandom;
-
- // Scale to range of -1.0 to 0.9999.
- return scalar * sum;
- }
-
- @Override
- public UnitOutputPort getOutput() {
- return output;
- }
-}
diff --git a/src/com/jsyn/unitgen/PitchDetector.java b/src/com/jsyn/unitgen/PitchDetector.java
deleted file mode 100644
index da6a0e3..0000000
--- a/src/com/jsyn/unitgen/PitchDetector.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright 2012 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;
-import com.jsyn.ports.UnitOutputPort;
-import com.jsyn.util.AutoCorrelator;
-import com.jsyn.util.SignalCorrelator;
-
-/**
- * Estimate the fundamental frequency of a monophonic signal. Analyzes an input signal and outputs
- * an estimated period in frames and a frequency in Hertz. The frequency is frameRate/period. The
- * confidence tells you how accurate the estimate is. When the confidence is low, you should ignore
- * the period. You can use a CompareUnit and a LatchUnit to hold values that you are confident of.
- * <P>
- * Note that a stable monophonic signal is required for accurate pitch tracking.
- *
- * @author (C) 2012 Phil Burk, Mobileer Inc
- */
-public class PitchDetector extends UnitGenerator {
- public UnitInputPort input;
-
- public UnitOutputPort period;
- public UnitOutputPort confidence;
- public UnitOutputPort frequency;
- public UnitOutputPort updated;
-
- protected SignalCorrelator signalCorrelator;
-
- private double lastFrequency = 440.0;
- private double lastPeriod = 44100.0 / lastFrequency; // result of analysis TODO update for 48000
- private double lastConfidence = 0.0; // Measure of confidence in the result.
-
- private static final int LOWEST_FREQUENCY = 40;
- private static final int HIGHEST_RATE = 48000;
- private static final int CYCLES_NEEDED = 2;
-
- public PitchDetector() {
- super();
- addPort(input = new UnitInputPort("Input"));
-
- addPort(period = new UnitOutputPort("Period"));
- addPort(confidence = new UnitOutputPort("Confidence"));
- addPort(frequency = new UnitOutputPort("Frequency"));
- addPort(updated = new UnitOutputPort("Updated"));
- signalCorrelator = createSignalCorrelator();
- }
-
- public SignalCorrelator createSignalCorrelator() {
- int framesNeeded = HIGHEST_RATE * CYCLES_NEEDED / LOWEST_FREQUENCY;
- return new AutoCorrelator(framesNeeded);
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] inputs = input.getValues();
- double[] periods = period.getValues();
- double[] confidences = confidence.getValues();
- double[] frequencies = frequency.getValues();
- double[] updateds = updated.getValues();
-
- for (int i = start; i < limit; i++) {
- double current = inputs[i];
- if (signalCorrelator.addSample(current)) {
- lastPeriod = signalCorrelator.getPeriod();
- if (lastPeriod < 0.1) {
- System.out.println("ILLEGAL PERIOD");
- }
- double currentFrequency = getFrameRate() / (lastPeriod + 0);
- double confidence = signalCorrelator.getConfidence();
- if (confidence > 0.1) {
- if (true) {
- double coefficient = confidence * 0.2;
- // Take weighted average with previous frequency.
- lastFrequency = ((lastFrequency * (1.0 - coefficient)) + (currentFrequency * coefficient));
- } else {
- lastFrequency = ((lastFrequency * lastConfidence) + (currentFrequency * confidence))
- / (lastConfidence + confidence);
- }
- }
- lastConfidence = confidence;
- updateds[i] = 1.0;
- } else {
- updateds[i] = 0.0;
- }
- periods[i] = lastPeriod;
- confidences[i] = lastConfidence;
- frequencies[i] = lastFrequency;
- }
- }
-
- /**
- * For debugging only.
- *
- * @return internal array of correlation results.
- */
- public float[] getDiffs() {
- return signalCorrelator.getDiffs();
- }
-
-}
diff --git a/src/com/jsyn/unitgen/PitchToFrequency.java b/src/com/jsyn/unitgen/PitchToFrequency.java
deleted file mode 100644
index 9086749..0000000
--- a/src/com/jsyn/unitgen/PitchToFrequency.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.jsyn.unitgen;
-
-import com.softsynth.math.AudioMath;
-
-public class PitchToFrequency extends PowerOfTwo {
-
- public PitchToFrequency() {
- input.setup(0.0, 60.0, 127.0);
- }
-
- /**
- * Convert from MIDI pitch to an octave offset from Concert A.
- */
- @Override
- public double adjustInput(double in) {
- return (in - AudioMath.CONCERT_A_PITCH) * (1.0/12.0);
- }
-
- /**
- * Convert scaler to a frequency relative to Concert A.
- */
- @Override
- public double adjustOutput(double out) {
- return out * AudioMath.getConcertAFrequency();
- }
-}
diff --git a/src/com/jsyn/unitgen/PowerOfTwo.java b/src/com/jsyn/unitgen/PowerOfTwo.java
deleted file mode 100644
index 5916860..0000000
--- a/src/com/jsyn/unitgen/PowerOfTwo.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright 2010 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;
-import com.jsyn.ports.UnitOutputPort;
-
-/**
- * output = (2.0^input) This is useful for converting a pitch modulation value into a frequency
- * scaler. An input value of +1.0 will output 2.0 for an octave increase. An input value of -1.0
- * will output 0.5 for an octave decrease.
- *
- * This implementation uses a table lookup to optimize for
- * speed. It is accurate enough for tuning. It also checks to see if the current input value is the
- * same as the previous input value. If so then it reuses the previous computed value.
- *
- * @author Phil Burk (C) 2010 Mobileer Inc
- */
-public class PowerOfTwo extends UnitGenerator {
- /**
- * Offset in octaves.
- */
- public UnitInputPort input;
- public UnitOutputPort output;
-
- private static double[] table;
- private static final int NUM_VALUES = 2048;
- // Cached computation.
- private double lastInput = 0.0;
- private double lastOutput = 1.0;
-
- static {
- // Add guard point for faster interpolation.
- // Add another point to handle inputs like -1.5308084989341915E-17,
- // which generate indices above range.
- table = new double[NUM_VALUES + 2];
- // Fill one octave of the table.
- for (int i = 0; i < table.length; i++) {
- double value = Math.pow(2.0, ((double) i) / NUM_VALUES);
- table[i] = value;
- }
- }
-
- public PowerOfTwo() {
- addPort(input = new UnitInputPort("Input"));
- input.setup(-8.0, 0.0, 8.0);
- addPort(output = new UnitOutputPort("Output"));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] inputs = input.getValues();
- double[] outputs = output.getValues();
-
- for (int i = start; i < limit; i++) {
- double in = inputs[i];
- // Can we reuse a previously computed value?
- if (in == lastInput) {
- outputs[i] = lastOutput;
- } else {
- lastInput = in;
- double adjustedInput = adjustInput(in);
- int octave = (int) Math.floor(adjustedInput);
- double normal = adjustedInput - octave;
- // Do table lookup.
- double findex = normal * NUM_VALUES;
- int index = (int) findex;
- double fraction = findex - index;
- double value = table[index] + (fraction * (table[index + 1] - table[index]));
-
- // Adjust for octave.
- while (octave > 0) {
- octave -= 1;
- value *= 2.0;
- }
- while (octave < 0) {
- octave += 1;
- value *= 0.5;
- }
- double adjustedOutput = adjustOutput(value);
- outputs[i] = adjustedOutput;
- lastOutput = adjustedOutput;
- }
- }
- }
-
- public double adjustInput(double in) {
- return in;
- }
-
- public double adjustOutput(double out) {
- return out;
- }
-}
diff --git a/src/com/jsyn/unitgen/PulseOscillator.java b/src/com/jsyn/unitgen/PulseOscillator.java
deleted file mode 100644
index 5ac7352..0000000
--- a/src/com/jsyn/unitgen/PulseOscillator.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2009 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;
-
-/**
- * Simple pulse wave oscillator.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public class PulseOscillator extends UnitOscillator {
- /**
- * Pulse width varies from -1.0 to +1.0. At 0.0 the pulse is actually a square wave.
- */
- public UnitInputPort width;
-
- public PulseOscillator() {
- addPort(width = new UnitInputPort("Width"));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] frequencies = frequency.getValues();
- double[] amplitudes = amplitude.getValues();
- double[] widths = width.getValues();
- double[] outputs = output.getValues();
-
- // Variables have a single value.
- double currentPhase = phase.getValue();
-
- for (int i = start; i < limit; i++) {
- // Generate sawtooth phaser to provide phase for pulse generation.
- double phaseIncrement = convertFrequencyToPhaseIncrement(frequencies[i]);
- currentPhase = incrementWrapPhase(currentPhase, phaseIncrement);
- double ampl = amplitudes[i];
- // Either full negative or positive amplitude.
- outputs[i] = (currentPhase < widths[i]) ? -ampl : ampl;
- }
-
- // Value needs to be saved for next time.
- phase.setValue(currentPhase);
- }
-
-}
diff --git a/src/com/jsyn/unitgen/PulseOscillatorBL.java b/src/com/jsyn/unitgen/PulseOscillatorBL.java
deleted file mode 100644
index c0e234c..0000000
--- a/src/com/jsyn/unitgen/PulseOscillatorBL.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright 2009 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.engine.MultiTable;
-import com.jsyn.ports.UnitInputPort;
-
-/**
- * Pulse oscillator that uses two band limited sawtooth waveforms.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public class PulseOscillatorBL extends SawtoothOscillatorBL {
- /** Controls the duty cycle of the pulse waveform.
- * The width varies from -1.0 to +1.0.
- * When width is zero the output is a square wave.
- */
- public UnitInputPort width;
-
- public PulseOscillatorBL() {
- addPort(width = new UnitInputPort("Width"));
- }
-
- @Override
- protected double generateBL(MultiTable multiTable, double currentPhase,
- double positivePhaseIncrement, double flevel, int i) {
- double[] widths = width.getValues();
- double width = widths[i];
- width = (width > 0.999) ? 0.999 : ((width < -0.999) ? -0.999 : width);
-
- double val1 = multiTable.calculateSawtooth(currentPhase, positivePhaseIncrement, flevel);
-
- // Generate second sawtooth so we can add them together.
- double phase2 = currentPhase + 1.0 - width; // 180 degrees out of phase
- if (phase2 >= 1.0) {
- phase2 -= 2.0;
- }
- double val2 = multiTable.calculateSawtooth(phase2, positivePhaseIncrement, flevel);
-
- /*
- * Need to adjust amplitude based on positive phaseInc and width. little less than half at
- * Nyquist/2.0!
- */
- double scale = 1.0 - positivePhaseIncrement;
- return scale * (val1 - val2 - width);
- }
-}
diff --git a/src/com/jsyn/unitgen/RaisedCosineEnvelope.java b/src/com/jsyn/unitgen/RaisedCosineEnvelope.java
deleted file mode 100644
index c32417c..0000000
--- a/src/com/jsyn/unitgen/RaisedCosineEnvelope.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright 2011 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;
-
-/**
- * An envelope that can be used in a GrainFarm to shape the amplitude of a Grain. The envelope
- * starts at 0.0, rises to 1.0, then returns to 0.0 following a cosine curve.
- *
- * <pre>
- * output = 0.5 - (0.5 * cos(phase))
- * </pre>
- *
- * @author Phil Burk (C) 2011 Mobileer Inc
- * @see GrainFarm
- */
-public class RaisedCosineEnvelope extends GrainCommon implements GrainEnvelope {
- protected double phase;
- protected double phaseIncrement;
-
- public RaisedCosineEnvelope() {
- setFrameRate(44100);
- setDuration(0.1);
- }
-
- /**
- * @return next value of the envelope.
- */
- @Override
- public double next() {
- phase += phaseIncrement;
- if (phase > (2.0 * Math.PI)) {
- return 0.0;
- } else {
- return 0.5 - (0.5 * Math.cos(phase)); // TODO optimize using Taylor expansion
- }
- }
-
- /**
- * @return true if there are more envelope values left.
- */
- @Override
- public boolean hasMoreValues() {
- return (phase < (2.0 * Math.PI));
- }
-
- /**
- * Reset the envelope back to the beginning.
- */
- @Override
- public void reset() {
- phase = 0.0;
- }
-
- @Override
- public void setDuration(double duration) {
- phaseIncrement = 2.0 * Math.PI / (getFrameRate() * duration);
- }
-
-}
diff --git a/src/com/jsyn/unitgen/RangeConverter.java b/src/com/jsyn/unitgen/RangeConverter.java
deleted file mode 100644
index ae94b0f..0000000
--- a/src/com/jsyn/unitgen/RangeConverter.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2014 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;
-
-/**
- * Convert an input signal between -1.0 and +1.0 to the range min to max. This is handy when using
- * an oscillator as a modulator.
- *
- * @author (C) 2014 Phil Burk, Mobileer Inc
- * @see EdgeDetector
- */
-public class RangeConverter extends UnitFilter {
- public UnitInputPort min;
- public UnitInputPort max;
-
- /* Define Unit Ports used by connect() and set(). */
- public RangeConverter() {
- addPort(min = new UnitInputPort("Min", 40.0));
- addPort(max = new UnitInputPort("Max", 2000.0));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] inputs = input.getValues();
- double[] mins = min.getValues();
- double[] maxs = max.getValues();
- double[] outputs = output.getValues();
-
- for (int i = start; i < limit; i++) {
- double low = mins[i];
- outputs[i] = low + ((maxs[i] - low) * (inputs[i] + 1) * 0.5);
- }
- }
-}
diff --git a/src/com/jsyn/unitgen/RectangularWindow.java b/src/com/jsyn/unitgen/RectangularWindow.java
deleted file mode 100644
index d61f763..0000000
--- a/src/com/jsyn/unitgen/RectangularWindow.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2013 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.data.SpectralWindow;
-
-/**
- * Window that is just 1.0. Flat like a rectangle.
- *
- * @author Phil Burk (C) 2013 Mobileer Inc
- * @see SpectralFFT
- */
-public class RectangularWindow implements SpectralWindow {
- static RectangularWindow instance = new RectangularWindow();
-
- @Override
- /** This always returns 1.0. Do not pass indices outside the window range. */
- public double get(int index) {
- return 1.0; // impressive, eh?
- }
-
- public static RectangularWindow getInstance() {
- return instance;
- }
-}
diff --git a/src/com/jsyn/unitgen/RedNoise.java b/src/com/jsyn/unitgen/RedNoise.java
deleted file mode 100644
index d3e4321..0000000
--- a/src/com/jsyn/unitgen/RedNoise.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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.util.PseudoRandom;
-
-/**
- * RedNoise unit. This unit interpolates straight line segments between pseudo-random numbers to
- * produce "red" noise. It is a grittier alternative to the white generator WhiteNoise. It is also
- * useful as a slowly changing random control generator for natural sounds. Frequency port controls
- * the number of times per second that a new random number is chosen.
- *
- * @author (C) 1997 Phil Burk, SoftSynth.com
- * @see WhiteNoise
- */
-public class RedNoise extends UnitOscillator {
- private PseudoRandom randomNum;
- protected double prevNoise, currNoise;
-
- /* Define Unit Ports used by connect() and set(). */
- public RedNoise() {
- super();
- randomNum = new PseudoRandom();
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] amplitudes = amplitude.getValues();
- double[] frequencies = frequency.getValues();
- double[] outputs = output.getValues();
- double currPhase = phase.getValue();
- double phaseIncrement, currOutput;
-
- double framePeriod = getFramePeriod();
-
- for (int i = start; i < limit; i++) {
- // compute phase
- phaseIncrement = frequencies[i] * framePeriod;
-
- // verify that phase is within minimums and is not negative
- if (phaseIncrement < 0.0) {
- phaseIncrement = 0.0 - phaseIncrement;
- }
- if (phaseIncrement > 1.0) {
- phaseIncrement = 1.0;
- }
-
- currPhase += phaseIncrement;
-
- // calculate new random whenever phase passes 1.0
- if (currPhase > 1.0) {
- prevNoise = currNoise;
- currNoise = randomNum.nextRandomDouble();
- // reset phase for interpolation
- currPhase -= 1.0;
- }
-
- // interpolate current
- currOutput = prevNoise + (currPhase * (currNoise - prevNoise));
- outputs[i] = currOutput * amplitudes[i];
- }
-
- // store new phase
- phase.setValue(currPhase);
- }
-}
diff --git a/src/com/jsyn/unitgen/SampleGrainFarm.java b/src/com/jsyn/unitgen/SampleGrainFarm.java
deleted file mode 100644
index 3f908d6..0000000
--- a/src/com/jsyn/unitgen/SampleGrainFarm.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright 2011 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.data.FloatSample;
-import com.jsyn.ports.UnitInputPort;
-
-/**
- * A GrainFarm that uses a FloatSample as source material. In this example we load a FloatSample for
- * use as a source material.
- *
- * <pre><code>
- synth.add(sampleGrainFarm = new SampleGrainFarm());
- // Load a sample that we want to "granulate" from a file.
- sample = SampleLoader.loadFloatSample(sampleFile);
- sampleGrainFarm.setSample(sample);
- // Use a ramp to move smoothly within the file.
- synth.add(ramp = new ContinuousRamp());
- ramp.output.connect(sampleGrainFarm.position);
-</code></pre>
- *
- * @author Phil Burk (C) 2011 Mobileer Inc
- */
-public class SampleGrainFarm extends GrainFarm {
- private FloatSample sample;
- public UnitInputPort position;
- public UnitInputPort positionRange;
-
- public SampleGrainFarm() {
- super();
- addPort(position = new UnitInputPort("Position", 0.0));
- addPort(positionRange = new UnitInputPort("PositionRange", 0.0));
- }
-
- @Override
- public void allocate(int numGrains) {
- Grain[] grainArray = new Grain[numGrains];
- for (int i = 0; i < numGrains; i++) {
- Grain grain = new Grain(new SampleGrainSource(), new RaisedCosineEnvelope());
- grainArray[i] = grain;
- }
- setGrainArray(grainArray);
- }
-
- @Override
- public void setupGrain(Grain grain, int i) {
- SampleGrainSource sampleGrainSource = (SampleGrainSource) grain.getSource();
- sampleGrainSource.setSample(sample);
- sampleGrainSource.setPosition(position.getValues()[i]);
- sampleGrainSource.setPositionRange(positionRange.getValues()[i]);
- super.setupGrain(grain, i);
- }
-
- public void setSample(FloatSample sample) {
- this.sample = sample;
- }
-}
diff --git a/src/com/jsyn/unitgen/SampleGrainSource.java b/src/com/jsyn/unitgen/SampleGrainSource.java
deleted file mode 100644
index f33817f..0000000
--- a/src/com/jsyn/unitgen/SampleGrainSource.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright 2009 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.data.FloatSample;
-
-public class SampleGrainSource extends GrainCommon implements GrainSource {
- private FloatSample sample;
- private double position; // ranges from -1.0 to 1.0
- private double positionRange;
- private double phase; // ranges from 0.0 to 1.0
- private double phaseIncrement;
- private int numFramesGuarded;
- private static final double MAX_PHASE = 0.9999999999;
-
- @Override
- public double next() {
- phase += phaseIncrement;
- if (phase > MAX_PHASE) {
- phase = MAX_PHASE;
- }
- double fractionalIndex = phase * numFramesGuarded;
- return sample.interpolate(fractionalIndex);
- }
-
- @Override
- public void setRate(double rate) {
- phaseIncrement = rate * sample.getFrameRate() / (getFrameRate() * numFramesGuarded);
- }
-
- public void setSample(FloatSample sample) {
- this.sample = sample;
- numFramesGuarded = sample.getNumFrames() - 1;
- }
-
- public void setPosition(double position) {
- this.position = position;
- }
-
- @Override
- public void reset() {
- double randomPosition = position + (positionRange * (Math.random() - 0.5));
- phase = (randomPosition * 0.5) + 0.5;
- if (phase < 0.0) {
- phase = 0.0;
- } else if (phase > MAX_PHASE) {
- phase = MAX_PHASE;
- }
- }
-
- public void setPositionRange(double positionRange) {
- this.positionRange = positionRange;
- }
-
-}
diff --git a/src/com/jsyn/unitgen/SawtoothOscillator.java b/src/com/jsyn/unitgen/SawtoothOscillator.java
deleted file mode 100644
index 1b3dead..0000000
--- a/src/com/jsyn/unitgen/SawtoothOscillator.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 2009 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;
-
-/**
- * Simple sawtooth oscillator.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public class SawtoothOscillator extends UnitOscillator {
-
- @Override
- public void generate(int start, int limit) {
-
- double[] frequencies = frequency.getValues();
- double[] amplitudes = amplitude.getValues();
- double[] outputs = output.getValues();
-
- // Variables have a single value.
- double currentPhase = phase.getValue();
-
- for (int i = start; i < limit; i++) {
- /* Generate sawtooth phasor to provide phase for sine generation. */
- double phaseIncrement = convertFrequencyToPhaseIncrement(frequencies[i]);
- currentPhase = incrementWrapPhase(currentPhase, phaseIncrement);
- outputs[i] = currentPhase * amplitudes[i];
- }
-
- // Value needs to be saved for next time.
- phase.setValue(currentPhase);
- }
-
-}
diff --git a/src/com/jsyn/unitgen/SawtoothOscillatorBL.java b/src/com/jsyn/unitgen/SawtoothOscillatorBL.java
deleted file mode 100644
index 8b58f6c..0000000
--- a/src/com/jsyn/unitgen/SawtoothOscillatorBL.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright 2009 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.engine.MultiTable;
-
-/**
- * Sawtooth oscillator that uses multiple wave tables for band limiting. This requires more CPU than
- * a plain SawtoothOscillator but has less aliasing at high frequencies.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public class SawtoothOscillatorBL extends UnitOscillator {
- @Override
- public void generate(int start, int limit) {
- MultiTable multiTable = MultiTable.getInstance();
-
- double[] frequencies = frequency.getValues();
- double[] amplitudes = amplitude.getValues();
- double[] outputs = output.getValues();
- // Variables have a single value.
- double currentPhase = phase.getValue();
-
- double phaseIncrement = convertFrequencyToPhaseIncrement(frequencies[0]);
- double positivePhaseIncrement = Math.abs(phaseIncrement);
- // This is very expensive so we moved it outside the loop.
- // Try to optimize it with a table lookup.
- double flevel = multiTable.convertPhaseIncrementToLevel(positivePhaseIncrement);
-
- for (int i = start; i < limit; i++) {
- /* Generate sawtooth phasor to provide phase for sine generation. */
- phaseIncrement = convertFrequencyToPhaseIncrement(frequencies[i]);
- currentPhase = incrementWrapPhase(currentPhase, phaseIncrement);
- positivePhaseIncrement = Math.abs(phaseIncrement);
-
- double val = generateBL(multiTable, currentPhase, positivePhaseIncrement, flevel, i);
-
- outputs[i] = val * amplitudes[i];
- }
-
- // Value needs to be saved for next time.
- phase.setValue(currentPhase);
- }
-
- protected double generateBL(MultiTable multiTable, double currentPhase,
- double positivePhaseIncrement, double flevel, int i) {
- /* Calculate table level then use it for lookup. */
- return multiTable.calculateSawtooth(currentPhase, positivePhaseIncrement, flevel);
- }
-
-}
diff --git a/src/com/jsyn/unitgen/SawtoothOscillatorDPW.java b/src/com/jsyn/unitgen/SawtoothOscillatorDPW.java
deleted file mode 100644
index 27d0c5a..0000000
--- a/src/com/jsyn/unitgen/SawtoothOscillatorDPW.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright 2009 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;
-
-/**
- * Sawtooth DPW oscillator (a sawtooth with reduced aliasing).
- * Based on a paper by Antti Huovilainen and Vesa Valimaki:
- * http://www.scribd.com/doc/33863143/New-Approaches-to-Digital-Subtractive-Synthesis
- *
- * @author Phil Burk and Lisa Tolentino (C) 2009 Mobileer Inc
- */
-public class SawtoothOscillatorDPW extends UnitOscillator {
- // At a very low frequency, switch from DPW to raw sawtooth.
- private static final double VERY_LOW_FREQUENCY = 2.0 * 0.1 / 44100.0;
- private double z1;
- private double z2;
-
- @Override
- public void generate(int start, int limit) {
- double[] frequencies = frequency.getValues();
- double[] amplitudes = amplitude.getValues();
- double[] outputs = output.getValues();
-
- // Variables have a single value.
- double currentPhase = phase.getValue();
-
- for (int i = start; i < limit; i++) {
- /* Generate raw sawtooth phaser. */
- double phaseIncrement = convertFrequencyToPhaseIncrement(frequencies[i]);
- currentPhase = incrementWrapPhase(currentPhase, phaseIncrement);
-
- /* Square the raw sawtooth. */
- double squared = currentPhase * currentPhase;
- // Differentiate using a delayed value.
- double diffed = squared - z2;
- z2 = z1;
- z1 = squared;
-
- /* Calculate scaling based on phaseIncrement */
- double pinc = phaseIncrement;
- // Absolute value.
- if (pinc < 0.0) {
- pinc = 0.0 - pinc;
- }
-
- double dpw;
- // If the frequency is very low then just use the raw sawtooth.
- // This avoids divide by zero problems and scaling problems.
- if (pinc < VERY_LOW_FREQUENCY) {
- dpw = currentPhase;
- } else {
- dpw = diffed * 0.25 / pinc;
- }
-
- outputs[i] = amplitudes[i] * dpw;
- }
-
- // Value needs to be saved for next time.
- phase.setValue(currentPhase);
- }
-
-}
diff --git a/src/com/jsyn/unitgen/SchmidtTrigger.java b/src/com/jsyn/unitgen/SchmidtTrigger.java
deleted file mode 100644
index 64129ff..0000000
--- a/src/com/jsyn/unitgen/SchmidtTrigger.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright 2009 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;
-import com.jsyn.ports.UnitOutputPort;
-
-/**
- * SchmidtTrigger unit.
- * <P>
- * Output logic level value with hysteresis. Transition high when input exceeds setLevel. Only go
- * low when input is below resetLevel. This can be used to reject low level noise on the input
- * signal. The default values for setLevel and resetLevel are both 0.0. Setting setLevel to 0.1 and
- * resetLevel to -0.1 will give some hysteresis. The outputPulse is a single sample wide pulse set
- * when the output transitions from low to high.
- *
- * <PRE>
- * if (output == 0.0)
- * output = (input &gt; setLevel) ? 1.0 : 0.0;
- * else if (output &gt; 0.0)
- * output = (input &lt;= resetLevel) ? 0.0 : 1.0;
- * else
- * output = previous_output;
- * </PRE>
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- * @see Compare
- */
-public class SchmidtTrigger extends UnitFilter {
- public UnitInputPort setLevel;
- public UnitInputPort resetLevel;
- public UnitOutputPort outputPulse;
-
- /* Define Unit Ports used by connect() and set(). */
- public SchmidtTrigger() {
- addPort(setLevel = new UnitInputPort("SetLevel"));
- addPort(resetLevel = new UnitInputPort("ResetLevel"));
- addPort(input = new UnitInputPort("Input"));
- addPort(outputPulse = new UnitOutputPort("OutputPulse"));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] inPtr = input.getValues();
- double[] pulsePtr = outputPulse.getValues();
- double[] outPtr = output.getValues();
- double[] setPtr = setLevel.getValues();
- double[] resetPtr = resetLevel.getValues();
-
- double outputValue = outPtr[0];
- boolean state = (outputValue > UnitGenerator.FALSE);
- for (int i = start; i < limit; i++) {
- pulsePtr[i] = UnitGenerator.FALSE;
- if (state) {
- if (inPtr[i] <= resetPtr[i]) {
- state = false;
- outputValue = UnitGenerator.FALSE;
- }
- } else {
- if (inPtr[i] > setPtr[i]) {
- state = true;
- outputValue = UnitGenerator.TRUE;
- pulsePtr[i] = UnitGenerator.TRUE; /* Single impulse. */
- }
- }
- outPtr[i] = outputValue;
- }
- }
-}
diff --git a/src/com/jsyn/unitgen/Select.java b/src/com/jsyn/unitgen/Select.java
deleted file mode 100644
index 6d8792e..0000000
--- a/src/com/jsyn/unitgen/Select.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright 2004 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;
-import com.jsyn.ports.UnitOutputPort;
-
-/**
- * SelectUnit unit. Select InputA or InputB based on value on Select port.
- *
- *<pre> <code>
- output = ( select &gt; 0.0 ) ? inputB : inputA;
-</code> </pre>
- *
- * @author (C) 2004-2009 Phil Burk, SoftSynth.com
- */
-
-public class Select extends UnitGenerator {
- public UnitInputPort inputA;
- public UnitInputPort inputB;
- public UnitInputPort select;
- public UnitOutputPort output;
-
- public Select() {
- addPort(inputA = new UnitInputPort("InputA"));
- addPort(inputB = new UnitInputPort("InputB"));
- addPort(select = new UnitInputPort("Select"));
- addPort(output = new UnitOutputPort("Output"));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] inputAs = inputA.getValues();
- double[] inputBs = inputB.getValues();
- double[] selects = select.getValues();
- double[] outputs = output.getValues();
-
- for (int i = start; i < limit; i++) {
- outputs[i] = (selects[i] > UnitGenerator.FALSE) ? inputBs[i] : inputAs[i];
- }
- }
-}
diff --git a/src/com/jsyn/unitgen/SequentialDataReader.java b/src/com/jsyn/unitgen/SequentialDataReader.java
deleted file mode 100644
index 901767b..0000000
--- a/src/com/jsyn/unitgen/SequentialDataReader.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2009 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.UnitDataQueuePort;
-import com.jsyn.ports.UnitInputPort;
-import com.jsyn.ports.UnitOutputPort;
-
-/**
- * Base class for reading a sample or envelope.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public abstract class SequentialDataReader extends UnitGenerator {
- public UnitDataQueuePort dataQueue;
- public UnitInputPort amplitude;
- public UnitOutputPort output;
-
- /* Define Unit Ports used by connect() and set(). */
- public SequentialDataReader() {
- addPort(dataQueue = new UnitDataQueuePort("Data"));
- addPort(amplitude = new UnitInputPort("Amplitude", UnitOscillator.DEFAULT_AMPLITUDE));
- }
-}
diff --git a/src/com/jsyn/unitgen/SequentialDataWriter.java b/src/com/jsyn/unitgen/SequentialDataWriter.java
deleted file mode 100644
index cb3bb11..0000000
--- a/src/com/jsyn/unitgen/SequentialDataWriter.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2009 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.UnitDataQueuePort;
-import com.jsyn.ports.UnitInputPort;
-
-/**
- * Base class for writing to a sample.
- *
- * Note that you must call start() on subclasses of this unit because it does not have an output for pulling data.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public abstract class SequentialDataWriter extends UnitGenerator {
- public UnitDataQueuePort dataQueue;
- public UnitInputPort input;
-
- public SequentialDataWriter() {
- addPort(dataQueue = new UnitDataQueuePort("Data"));
- }
-
- /**
- * This unit won't do anything unless you start() it.
- */
- @Override
- public boolean isStartRequired() {
- return true;
- }
-}
diff --git a/src/com/jsyn/unitgen/SineOscillator.java b/src/com/jsyn/unitgen/SineOscillator.java
deleted file mode 100644
index 8c49ead..0000000
--- a/src/com/jsyn/unitgen/SineOscillator.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright 2009 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;
-
-/**
- * Sine oscillator generates a frequency controlled sine wave. It is implemented using a fast Taylor
- * expansion.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public class SineOscillator extends UnitOscillator {
- public SineOscillator() {
- }
-
- public SineOscillator(double freq) {
- frequency.set(freq);
- }
-
- public SineOscillator(double freq, double amp) {
- frequency.set(freq);
- amplitude.set(amp);
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] frequencies = frequency.getValues();
- double[] amplitudes = amplitude.getValues();
- double[] outputs = output.getValues();
- double currentPhase = phase.getValue();
-
- for (int i = start; i < limit; i++) {
- /* Generate sawtooth phasor to provide phase for sine generation. */
- double phaseIncrement = convertFrequencyToPhaseIncrement(frequencies[i]);
- currentPhase = incrementWrapPhase(currentPhase, phaseIncrement);
- if (true) {
- double value = fastSin(currentPhase);
- outputs[i] = value * amplitudes[i];
- } else {
- // Slower but more accurate implementation.
- outputs[i] = Math.sin(currentPhase * Math.PI) * amplitudes[i];
- }
- }
-
- phase.setValue(currentPhase);
- }
-
- /**
- * Calculate sine using Taylor expansion. Do not use values outside the range.
- *
- * @param currentPhase in the range of -1.0 to +1.0 for one cycle
- */
- public static double fastSin(double currentPhase) {
- // Factorial constants so code is easier to read.
- final double IF3 = 1.0 / (2 * 3);
- final double IF5 = IF3 / (4 * 5);
- final double IF7 = IF5 / (6 * 7);
- final double IF9 = IF7 / (8 * 9);
- final double IF11 = IF9 / (10 * 11);
-
- /* Wrap phase back into region where results are more accurate. */
- double yp = (currentPhase > 0.5) ? 1.0 - currentPhase : ((currentPhase < (-0.5)) ? (-1.0)
- - currentPhase : currentPhase);
-
- double x = yp * Math.PI;
- double x2 = (x * x);
- /* Taylor expansion out to x**11/11! factored into multiply-adds */
- double fastsin = x
- * (x2 * (x2 * (x2 * (x2 * ((x2 * (-IF11)) + IF9) - IF7) + IF5) - IF3) + 1);
- return fastsin;
- }
-}
diff --git a/src/com/jsyn/unitgen/SineOscillatorPhaseModulated.java b/src/com/jsyn/unitgen/SineOscillatorPhaseModulated.java
deleted file mode 100644
index 7631dff..0000000
--- a/src/com/jsyn/unitgen/SineOscillatorPhaseModulated.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright 2009 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;
-
-/**
- * Sine oscillator with a phase modulation input. Phase modulation is similar to frequency
- * modulation but is easier to use in some ways.
- *
- * <pre>
- * output = sin(PI * (phase + modulation))
- * </pre>
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public class SineOscillatorPhaseModulated extends SineOscillator {
- public UnitInputPort modulation;
-
- /* Define Unit Ports used by connect() and set(). */
- public SineOscillatorPhaseModulated() {
- super();
- addPort(modulation = new UnitInputPort("Modulation"));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] frequencies = frequency.getValues();
- double[] amplitudes = amplitude.getValues();
- double[] outputs = output.getValues();
- double[] modulations = modulation.getValues();
- double currentPhase = phase.getValue();
-
- for (int i = start; i < limit; i++) {
- /* Generate sawtooth phaser to provide phase for sine generation. */
- double phaseIncrement = convertFrequencyToPhaseIncrement(frequencies[i]);
- currentPhase = incrementWrapPhase(currentPhase, phaseIncrement);
- double modulatedPhase = currentPhase + modulations[i];
- double value;
- if (false) {
- // TODO Compare benchmarks.
- while (modulatedPhase >= 1.0) {
- modulatedPhase -= 2.0;
- }
- while (modulatedPhase < -1.0) {
- modulatedPhase += 2.0;
- }
- value = fastSin(modulatedPhase);
- } else {
- value = Math.sin(modulatedPhase * Math.PI);
- }
- outputs[i] = value * amplitudes[i];
- // System.out.format("Sine: freq = %10.4f , amp = %8.5f, out = %8.5f, phase = %8.5f, frame = %8d\n",
- // frequencies[i], amplitudes[i],outputs[i],currentPhase,frame++ );
- }
-
- phase.setValue(currentPhase);
- }
-
-}
diff --git a/src/com/jsyn/unitgen/SpectralFFT.java b/src/com/jsyn/unitgen/SpectralFFT.java
deleted file mode 100644
index f3e881a..0000000
--- a/src/com/jsyn/unitgen/SpectralFFT.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright 2013 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 java.util.Arrays;
-
-import com.jsyn.data.SpectralWindow;
-import com.jsyn.data.Spectrum;
-import com.jsyn.ports.UnitInputPort;
-import com.jsyn.ports.UnitSpectralOutputPort;
-import com.softsynth.math.FourierMath;
-
-/**
- * Periodically transform the input signal using an FFT. Output complete spectra.
- *
- * @author Phil Burk (C) 2013 Mobileer Inc
- * @version 016
- * @see SpectralIFFT
- * @see Spectrum
- * @see SpectralFilter
- */
-public class SpectralFFT extends UnitGenerator {
- public UnitInputPort input;
- /**
- * Provides complete complex spectra when the FFT completes.
- */
- public UnitSpectralOutputPort output;
- private double[] buffer;
- private int cursor;
- private SpectralWindow window = RectangularWindow.getInstance();
- private int sizeLog2;
- private int offset;
- private boolean running;
-
- /* Define Unit Ports used by connect() and set(). */
- public SpectralFFT() {
- this(Spectrum.DEFAULT_SIZE_LOG_2);
- }
-
- /**
- * @param sizeLog2 for example, pass 10 to get a 1024 bin FFT
- */
- public SpectralFFT(int sizeLog2) {
- addPort(input = new UnitInputPort("Input"));
- addPort(output = new UnitSpectralOutputPort("Output", 1 << sizeLog2));
- setSizeLog2(sizeLog2);
- }
-
- /**
- * Please do not change the size of the FFT while JSyn is running.
- *
- * @param sizeLog2 for example, pass 9 to get a 512 bin FFT
- */
- public void setSizeLog2(int sizeLog2) {
- this.sizeLog2 = sizeLog2;
- output.setSize(1 << sizeLog2);
- buffer = output.getSpectrum().getReal();
- cursor = 0;
- }
-
- public int getSizeLog2() {
- return sizeLog2;
- }
-
- @Override
- public void generate(int start, int limit) {
- if (!running) {
- int mask = (1 << sizeLog2) - 1;
- if (((getSynthesisEngine().getFrameCount() - offset) & mask) == 0) {
- running = true;
- cursor = 0;
- }
- }
- // Don't use "else" because "running" may have changed in above block.
- if (running) {
- double[] inputs = input.getValues();
- for (int i = start; i < limit; i++) {
- buffer[cursor] = inputs[i] * window.get(cursor);
- ++cursor;
- // When it is full, do the FFT.
- if (cursor == buffer.length) {
- Spectrum spectrum = output.getSpectrum();
- Arrays.fill(spectrum.getImaginary(), 0.0);
- FourierMath.fft(buffer.length, spectrum.getReal(), spectrum.getImaginary());
- output.advance();
- cursor = 0;
- }
- }
- }
- }
-
- public SpectralWindow getWindow() {
- return window;
- }
-
- /**
- * Multiply input data by this window before doing the FFT. The default is a RectangularWindow.
- */
- public void setWindow(SpectralWindow window) {
- this.window = window;
- }
-
- /**
- * The FFT will be performed on a frame that is a multiple of the size plus this offset.
- *
- * @param offset
- */
- public void setOffset(int offset) {
- this.offset = offset;
- }
-
- public int getOffset() {
- return offset;
- }
-
-}
diff --git a/src/com/jsyn/unitgen/SpectralFilter.java b/src/com/jsyn/unitgen/SpectralFilter.java
deleted file mode 100644
index 758c8e7..0000000
--- a/src/com/jsyn/unitgen/SpectralFilter.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright 2014 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.data.SpectralWindow;
-import com.jsyn.data.SpectralWindowFactory;
-import com.jsyn.data.Spectrum;
-import com.jsyn.ports.UnitInputPort;
-import com.jsyn.ports.UnitOutputPort;
-import com.jsyn.ports.UnitSpectralInputPort;
-import com.jsyn.ports.UnitSpectralOutputPort;
-
-/**
- * Process a signal using multiple overlapping FFT and IFFT pairs. For passthrough, you can connect
- * the spectral outputs to the spectral inputs. Or you can connect one or more SpectralProcessors
- * between them.
- *
- * <pre>
- * for (int i = 0; i &lt; numFFTs; i++) {
- * filter.getSpectralOutput(i).connect(processors[i].input);
- * processors[i].output.connect(filter.getSpectralInput(i));
- * }
- * </pre>
- *
- * See the example program "HearSpectralFilter.java". Note that this spectral API is experimental
- * and may change at any time.
- *
- * @author Phil Burk (C) 2014 Mobileer Inc
- * @see SpectralProcessor
- */
-public class SpectralFilter extends Circuit implements UnitSink, UnitSource {
- public UnitInputPort input;
- public UnitOutputPort output;
-
- private SpectralFFT[] ffts;
- private SpectralIFFT[] iffts;
- private PassThrough inlet; // fan out to FFTs
- private PassThrough sum; // mix output of IFFTs
-
- /**
- * Create a default sized filter with 2 FFT/IFFT pairs and a sizeLog2 of
- * Spectrum.DEFAULT_SIZE_LOG_2.
- */
- public SpectralFilter() {
- this(2, Spectrum.DEFAULT_SIZE_LOG_2);
- }
-
- /**
- * @param numFFTs number of FFT/IFFT pairs for the overlap and add
- * @param sizeLog2 for example, use 10 to get a 1024 bin FFT, 12 for 4096
- */
- public SpectralFilter(int numFFTs, int sizeLog2) {
- add(inlet = new PassThrough());
- add(sum = new PassThrough());
- ffts = new SpectralFFT[numFFTs];
- iffts = new SpectralIFFT[numFFTs];
- int offset = (1 << sizeLog2) / numFFTs;
- for (int i = 0; i < numFFTs; i++) {
- add(ffts[i] = new SpectralFFT(sizeLog2));
- inlet.output.connect(ffts[i].input);
- ffts[i].setOffset(i * offset);
-
- add(iffts[i] = new SpectralIFFT());
- iffts[i].output.connect(sum.input);
- }
- setWindow(SpectralWindowFactory.getHammingWindow(sizeLog2));
-
- addPort(input = inlet.input);
- addPort(output = sum.output);
- }
-
- public SpectralWindow getWindow() {
- return ffts[0].getWindow();
- }
-
- /**
- * Specify one window to be used for all FFTs and IFFTs. The window should be the same size as
- * the FFTs.
- *
- * @param window default is HammingWindow
- * @see SpectralWindowFactory
- */
- public void setWindow(SpectralWindow window) {
- // Use the same window everywhere.
- for (int i = 0; i < ffts.length; i++) {
- ffts[i].setWindow(window); // TODO review, both sides or just one
- iffts[i].setWindow(window);
- }
- }
-
- @Override
- public UnitOutputPort getOutput() {
- return output;
- }
-
- @Override
- public UnitInputPort getInput() {
- return input;
- }
-
- /**
- * @param i
- * @return the output of the indexed FFT
- */
- public UnitSpectralOutputPort getSpectralOutput(int i) {
- return ffts[i].output;
- }
-
- /**
- * @param i
- * @return the input of the indexed IFFT
- */
- public UnitSpectralInputPort getSpectralInput(int i) {
- return iffts[i].input;
- }
-}
diff --git a/src/com/jsyn/unitgen/SpectralIFFT.java b/src/com/jsyn/unitgen/SpectralIFFT.java
deleted file mode 100644
index c040e52..0000000
--- a/src/com/jsyn/unitgen/SpectralIFFT.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright 2013 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.data.SpectralWindow;
-import com.jsyn.data.Spectrum;
-import com.jsyn.ports.UnitOutputPort;
-import com.jsyn.ports.UnitSpectralInputPort;
-import com.softsynth.math.FourierMath;
-
-/**
- * Periodically transform the input signal using an Inverse FFT.
- *
- * @author Phil Burk (C) 2013 Mobileer Inc
- * @version 016
- * @see SpectralFFT
- */
-public class SpectralIFFT extends UnitGenerator {
- public UnitSpectralInputPort input;
- public UnitOutputPort output;
- private Spectrum localSpectrum;
- private double[] buffer;
- private int cursor;
- private SpectralWindow window = RectangularWindow.getInstance();
-
- /* Define Unit Ports used by connect() and set(). */
- public SpectralIFFT() {
- addPort(output = new UnitOutputPort());
- addPort(input = new UnitSpectralInputPort("Input"));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] outputs = output.getValues();
-
- if (buffer == null) {
- if (input.isAvailable()) {
- Spectrum spectrum = input.getSpectrum();
- int size = spectrum.size();
- localSpectrum = new Spectrum(size);
- buffer = localSpectrum.getReal();
- cursor = 0;
- } else {
- for (int i = start; i < limit; i++) {
- outputs[i] = 0.0;
- }
- }
- }
-
- if (buffer != null) {
- for (int i = start; i < limit; i++) {
- if (cursor == 0) {
- Spectrum spectrum = input.getSpectrum();
- spectrum.copyTo(localSpectrum);
- FourierMath.ifft(buffer.length, localSpectrum.getReal(),
- localSpectrum.getImaginary());
- }
-
- outputs[i] = buffer[cursor] * window.get(cursor);
- cursor += 1;
- if (cursor == buffer.length) {
- cursor = 0;
- }
- }
- }
- }
-
- public SpectralWindow getWindow() {
- return window;
- }
-
- /**
- * Multiply output data by this window after doing the FFT. The default is a RectangularWindow.
- */
- public void setWindow(SpectralWindow window) {
- this.window = window;
- }
-}
diff --git a/src/com/jsyn/unitgen/SpectralProcessor.java b/src/com/jsyn/unitgen/SpectralProcessor.java
deleted file mode 100644
index de96877..0000000
--- a/src/com/jsyn/unitgen/SpectralProcessor.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright 2014 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.data.Spectrum;
-import com.jsyn.ports.UnitSpectralInputPort;
-import com.jsyn.ports.UnitSpectralOutputPort;
-
-/**
- * This is a base class for implementing your own spectral processing units. You need to implement
- * the processSpectrum() method.
- *
- * @author Phil Burk (C) 2014 Mobileer Inc
- * @see Spectrum
- */
-public abstract class SpectralProcessor extends UnitGenerator {
- public UnitSpectralInputPort input;
- public UnitSpectralOutputPort output;
- private int counter;
-
- /* Define Unit Ports used by connect() and set(). */
- public SpectralProcessor() {
- addPort(output = new UnitSpectralOutputPort());
- addPort(input = new UnitSpectralInputPort());
- }
-
- /* Define Unit Ports used by connect() and set(). */
- public SpectralProcessor(int size) {
- addPort(output = new UnitSpectralOutputPort(size));
- addPort(input = new UnitSpectralInputPort());
- }
-
- @Override
- public void generate(int start, int limit) {
- for (int i = start; i < limit; i++) {
- if (counter == 0) {
- if (input.isAvailable()) {
- Spectrum inputSpectrum = input.getSpectrum();
- Spectrum outputSpectrum = output.getSpectrum();
- processSpectrum(inputSpectrum, outputSpectrum);
-
- output.advance();
- counter = inputSpectrum.size() - 1;
- }
- } else {
- counter--;
- }
- }
- }
-
- /**
- * Define this method to implement your own processor.
- *
- * @param inputSpectrum
- * @param outputSpectrum
- */
- public abstract void processSpectrum(Spectrum inputSpectrum, Spectrum outputSpectrum);
-
-}
diff --git a/src/com/jsyn/unitgen/SquareOscillator.java b/src/com/jsyn/unitgen/SquareOscillator.java
deleted file mode 100644
index aaca2d0..0000000
--- a/src/com/jsyn/unitgen/SquareOscillator.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright 2009 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;
-
-/**
- * Simple square wave oscillator.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public class SquareOscillator extends UnitOscillator {
-
- @Override
- public void generate(int start, int limit) {
- double[] frequencies = frequency.getValues();
- double[] amplitudes = amplitude.getValues();
- double[] outputs = output.getValues();
-
- // Variables have a single value.
- double currentPhase = phase.getValue();
-
- for (int i = start; i < limit; i++) {
- /* Generate sawtooth phasor to provide phase for square generation. */
- double phaseIncrement = convertFrequencyToPhaseIncrement(frequencies[i]);
- currentPhase = incrementWrapPhase(currentPhase, phaseIncrement);
-
- double ampl = amplitudes[i];
- // Either full negative or positive amplitude.
- outputs[i] = (currentPhase < 0.0) ? -ampl : ampl;
- }
-
- // Value needs to be saved for next time.
- phase.setValue(currentPhase);
- }
-
-}
diff --git a/src/com/jsyn/unitgen/SquareOscillatorBL.java b/src/com/jsyn/unitgen/SquareOscillatorBL.java
deleted file mode 100644
index cb9e141..0000000
--- a/src/com/jsyn/unitgen/SquareOscillatorBL.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2009 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.engine.MultiTable;
-
-/**
- * Band-limited square wave oscillator. This requires more CPU than a SquareOscillator but is less
- * noisy at high frequencies.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public class SquareOscillatorBL extends SawtoothOscillatorBL {
- @Override
- protected double generateBL(MultiTable multiTable, double currentPhase,
- double positivePhaseIncrement, double flevel, int i) {
- double val1 = multiTable.calculateSawtooth(currentPhase, positivePhaseIncrement, flevel);
-
- /* Generate second sawtooth so we can add them together. */
- double phase2 = currentPhase + 1.0; /* 180 degrees out of phase. */
- if (phase2 >= 1.0) {
- phase2 -= 2.0;
- }
- double val2 = multiTable.calculateSawtooth(phase2, positivePhaseIncrement, flevel);
-
- /*
- * Need to adjust amplitude based on positive phaseInc. little less than half at
- * Nyquist/2.0!
- */
- final double STARTAMP = 0.92; /* Derived by viewing waveforms with TJ_SEEOSC */
- double scale = STARTAMP - positivePhaseIncrement;
- return scale * (val1 - val2);
- }
-}
diff --git a/src/com/jsyn/unitgen/StereoStreamWriter.java b/src/com/jsyn/unitgen/StereoStreamWriter.java
deleted file mode 100644
index b387836..0000000
--- a/src/com/jsyn/unitgen/StereoStreamWriter.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2009 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 java.io.IOException;
-
-import com.jsyn.io.AudioOutputStream;
-import com.jsyn.ports.UnitInputPort;
-
-/**
- * Write two samples per audio frame to an AudioOutputStream as interleaved samples.
- *
- * Note that you must call start() on this unit because it does not have an output for pulling data.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public class StereoStreamWriter extends UnitStreamWriter {
- public StereoStreamWriter() {
- addPort(input = new UnitInputPort(2, "Input"));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] leftInputs = input.getValues(0);
- double[] rightInputs = input.getValues(1);
- AudioOutputStream output = outputStream;
- if (output != null) {
- try {
- for (int i = start; i < limit; i++) {
- output.write(leftInputs[i]);
- output.write(rightInputs[i]);
- }
- } catch (IOException e) {
- e.printStackTrace();
- output = null;
- }
- }
- }
-}
diff --git a/src/com/jsyn/unitgen/StochasticGrainScheduler.java b/src/com/jsyn/unitgen/StochasticGrainScheduler.java
deleted file mode 100644
index 1f79877..0000000
--- a/src/com/jsyn/unitgen/StochasticGrainScheduler.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2011 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.util.PseudoRandom;
-
-/**
- * Use a random function to schedule grains.
- *
- * @author Phil Burk (C) 2011 Mobileer Inc
- */
-public class StochasticGrainScheduler implements GrainScheduler {
- PseudoRandom pseudoRandom = new PseudoRandom();
-
- @Override
- public double nextDuration(double duration) {
- return duration;
- }
-
- @Override
- public double nextGap(double duration, double density) {
- if (density < 0.00000001) {
- density = 0.00000001;
- }
- double gapRange = duration * (1.0 - density) / density;
- return pseudoRandom.random() * gapRange;
- }
-
-}
diff --git a/src/com/jsyn/unitgen/Subtract.java b/src/com/jsyn/unitgen/Subtract.java
deleted file mode 100644
index d9ca035..0000000
--- a/src/com/jsyn/unitgen/Subtract.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2009 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;
-
-/**
- * This unit performs a signed subtraction on its two inputs.
- *
- * <pre>
- * output = inputA - inputB
- * </pre>
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- * @version 016
- * @see MultiplyAdd
- * @see Subtract
- */
-public class Subtract extends UnitBinaryOperator {
- @Override
- public void generate(int start, int limit) {
- double[] aValues = inputA.getValues();
- double[] bValues = inputB.getValues();
- double[] outputs = output.getValues();
-
- for (int i = start; i < limit; i++) {
- outputs[i] = aValues[i] - bValues[i];
- }
- }
-}
diff --git a/src/com/jsyn/unitgen/TriangleOscillator.java b/src/com/jsyn/unitgen/TriangleOscillator.java
deleted file mode 100644
index ada2d6e..0000000
--- a/src/com/jsyn/unitgen/TriangleOscillator.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2009 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;
-
-/**
- * Simple triangle wave oscillator.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public class TriangleOscillator extends UnitOscillator {
- int frame;
-
- public TriangleOscillator() {
- super();
- phase.setValue(-0.5);
- }
-
- @Override
- public void generate(int start, int limit) {
-
- double[] frequencies = frequency.getValues();
- double[] amplitudes = amplitude.getValues();
- double[] outputs = output.getValues();
-
- // Variables have a single value.
- double currentPhase = phase.getValue();
-
- for (int i = start; i < limit; i++) {
- /* Generate sawtooth phasor to provide phase for triangle generation. */
- double phaseIncrement = convertFrequencyToPhaseIncrement(frequencies[i]);
- currentPhase = incrementWrapPhase(currentPhase, phaseIncrement);
-
- /* Map phase to triangle waveform. */
- /* 0 - 0.999 => 0.5-p => +0.5 - -0.5 */
- /* -1.0 - 0.0 => 0.5+p => -0.5 - +0.5 */
- double triangle = (currentPhase >= 0.0) ? (0.5 - currentPhase) : (0.5 + currentPhase);
-
- outputs[i] = triangle * 2.0 * amplitudes[i];
- }
-
- // Value needs to be saved for next time.
- phase.setValue(currentPhase);
- }
-
-}
diff --git a/src/com/jsyn/unitgen/TunableFilter.java b/src/com/jsyn/unitgen/TunableFilter.java
deleted file mode 100644
index d2c9f66..0000000
--- a/src/com/jsyn/unitgen/TunableFilter.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2009 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.
- */
-/**
- * Aug 26, 2009
- * com.jsyn.engine.units.TunableFilter.java
- */
-
-package com.jsyn.unitgen;
-
-import com.jsyn.ports.UnitInputPort;
-
-/**
- * A UnitFilter with a frequency port.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc Translated from 'C' to Java by Lisa
- * Tolentino.
- */
-public abstract class TunableFilter extends UnitFilter {
-
- static final double DEFAULT_FREQUENCY = 400;
- public UnitInputPort frequency;
-
- public TunableFilter() {
- addPort(frequency = new UnitInputPort("Frequency"));
- frequency.setup(40.0, DEFAULT_FREQUENCY, 6000.0);
- }
-
-}
diff --git a/src/com/jsyn/unitgen/TwoInDualOut.java b/src/com/jsyn/unitgen/TwoInDualOut.java
deleted file mode 100644
index a8fea48..0000000
--- a/src/com/jsyn/unitgen/TwoInDualOut.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright 2004 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;
-import com.jsyn.ports.UnitOutputPort;
-
-/**
- * This unit combines two discrete inputs into a dual (stereo) output.
- *
- * <pre>
- * output[0] = inputA
- * output[1] = inputB
- * </pre>
- *
- * @author (C) 2004-2009 Phil Burk, SoftSynth.com
- */
-
-public class TwoInDualOut extends UnitGenerator {
- public UnitInputPort inputA;
- public UnitInputPort inputB;
- public UnitOutputPort output;
-
- public TwoInDualOut() {
- addPort(inputA = new UnitInputPort("InputA"));
- addPort(inputB = new UnitInputPort("InputB"));
- addPort(output = new UnitOutputPort(2, "OutputB"));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] inputAs = inputA.getValues();
- double[] inputBs = inputB.getValues();
- double[] output0s = output.getValues(0);
- double[] output1s = output.getValues(1);
-
- for (int i = start; i < limit; i++) {
- output0s[i] = inputAs[i];
- output1s[i] = inputBs[i];
- }
- }
-}
diff --git a/src/com/jsyn/unitgen/UnitBinaryOperator.java b/src/com/jsyn/unitgen/UnitBinaryOperator.java
deleted file mode 100644
index c5675ff..0000000
--- a/src/com/jsyn/unitgen/UnitBinaryOperator.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2010 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;
-import com.jsyn.ports.UnitOutputPort;
-
-/**
- * Base class for binary arithmetic operators like Add and Compare.
- *
- * @author Phil Burk (C) 2010 Mobileer Inc
- */
-public abstract class UnitBinaryOperator extends UnitGenerator {
- public UnitInputPort inputA;
- public UnitInputPort inputB;
- public UnitOutputPort output;
-
- /* Define Unit Ports used by connect() and set(). */
- public UnitBinaryOperator() {
- addPort(inputA = new UnitInputPort("InputA"));
- addPort(inputB = new UnitInputPort("InputB"));
- addPort(output = new UnitOutputPort("Output"));
- }
-
- @Override
- public abstract void generate(int start, int limit);
-}
diff --git a/src/com/jsyn/unitgen/UnitFilter.java b/src/com/jsyn/unitgen/UnitFilter.java
deleted file mode 100644
index 49976ba..0000000
--- a/src/com/jsyn/unitgen/UnitFilter.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 2009 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;
-import com.jsyn.ports.UnitOutputPort;
-
-/**
- * Base class for all filters.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public abstract class UnitFilter extends UnitGenerator implements UnitSink, UnitSource {
- public UnitInputPort input;
- public UnitOutputPort output;
-
- /* Define Unit Ports used by connect() and set(). */
- public UnitFilter() {
- addPort(input = new UnitInputPort("Input"));
- addPort(output = new UnitOutputPort("Output"));
- }
-
- @Override
- public UnitInputPort getInput() {
- return input;
- }
-
- @Override
- public UnitOutputPort getOutput() {
- return output;
- }
-
-}
diff --git a/src/com/jsyn/unitgen/UnitGate.java b/src/com/jsyn/unitgen/UnitGate.java
deleted file mode 100644
index 59144c2..0000000
--- a/src/com/jsyn/unitgen/UnitGate.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright 2012 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.UnitGatePort;
-import com.jsyn.ports.UnitOutputPort;
-
-/**
- * Base class for other envelopes.
- *
- * @author Phil Burk (C) 2012 Mobileer Inc
- */
-public abstract class UnitGate extends UnitGenerator implements UnitSource {
- /**
- * Input that triggers the envelope. Use amplitude port if you want to connect a signal to be
- * modulated by the envelope.
- */
- public UnitGatePort input;
- public UnitOutputPort output;
-
- public UnitGate() {
- addPort(input = new UnitGatePort("Input"));
- addPort(output = new UnitOutputPort("Output"));
- }
-
- @Override
- public UnitOutputPort getOutput() {
- return output;
- }
-
- /**
- * Specify a unit to be disabled when the envelope finishes.
- *
- * @param unit
- */
- public void setupAutoDisable(UnitGenerator unit) {
- input.setupAutoDisable(unit);
- }
-
-}
diff --git a/src/com/jsyn/unitgen/UnitGenerator.java b/src/com/jsyn/unitgen/UnitGenerator.java
deleted file mode 100644
index 1e87ae6..0000000
--- a/src/com/jsyn/unitgen/UnitGenerator.java
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * Copyright 2009 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 java.io.PrintStream;
-import java.util.Collection;
-import java.util.LinkedHashMap;
-import java.util.logging.Logger;
-
-import com.jsyn.Synthesizer;
-import com.jsyn.engine.SynthesisEngine;
-import com.jsyn.ports.ConnectableInput;
-import com.jsyn.ports.UnitInputPort;
-import com.jsyn.ports.UnitOutputPort;
-import com.jsyn.ports.UnitPort;
-import com.softsynth.shared.time.TimeStamp;
-
-/**
- * Base class for all unit generators.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public abstract class UnitGenerator {
- protected static final double VERY_SMALL_FLOAT = 1.0e-26;
-
- // Some common port names.
- public static final String PORT_NAME_INPUT = "Input";
- public static final String PORT_NAME_OUTPUT = "Output";
- public static final String PORT_NAME_PHASE = "Phase";
- public static final String PORT_NAME_FREQUENCY = "Frequency";
- public static final String PORT_NAME_FREQUENCY_SCALER = "FreqScaler";
- public static final String PORT_NAME_AMPLITUDE = "Amplitude";
- public static final String PORT_NAME_PAN = "Pan";
- public static final String PORT_NAME_TIME = "Time";
- public static final String PORT_NAME_CUTOFF = "Cutoff";
- public static final String PORT_NAME_PRESSURE = "Pressure";
- public static final String PORT_NAME_TIMBRE = "Timbre";
-
- public static final double FALSE = 0.0;
- public static final double TRUE = 1.0;
- protected SynthesisEngine synthesisEngine;
- private final LinkedHashMap<String, UnitPort> ports = new LinkedHashMap<String, UnitPort>();
- private Circuit circuit;
- private long lastFrameCount;
- private boolean enabled = true;
- private static int nextId;
- private final int id = nextId++;
-
- static Logger logger = Logger.getLogger(UnitGenerator.class.getName());
-
- public int getId() {
- return id;
- }
-
- public int getFrameRate() {
- // return frameRate;
- return synthesisEngine.getFrameRate();
- }
-
- public double getFramePeriod() {
- // return framePeriod; // TODO - Why does OldJSynTestSuite fail if I use this!
- return synthesisEngine.getFramePeriod();
- }
-
- public void addPort(UnitPort port) {
- port.setUnitGenerator(this);
- // Store in a hash table by name.
- ports.put(port.getName().toLowerCase(), port);
- }
-
- public void addPort(UnitPort port, String name) {
- port.setName(name);
- addPort(port);
- }
-
- /**
- * Case-insensitive search for a port by name.
- * @param portName
- * @return matching port or null
- */
- public UnitPort getPortByName(String portName) {
- return ports.get(portName.toLowerCase());
- }
-
- public Collection<UnitPort> getPorts() {
- return ports.values();
- }
-
- /**
- * Perform essential synthesis function.
- *
- * @param start offset into port buffers
- * @param limit limit offset into port buffers for loop
- */
- public abstract void generate(int start, int limit);
-
- /**
- * Generate a full block.
- */
- public void generate() {
- generate(0, Synthesizer.FRAMES_PER_BLOCK);
- }
-
- /**
- * @return the synthesisEngine
- */
- public SynthesisEngine getSynthesisEngine() {
- return synthesisEngine;
- }
-
- /**
- * @return the Synthesizer
- */
- public Synthesizer getSynthesizer() {
- return synthesisEngine;
- }
-
- /**
- * @param synthesisEngine the synthesisEngine to set
- */
- public void setSynthesisEngine(SynthesisEngine synthesisEngine) {
- if ((this.synthesisEngine != null) && (this.synthesisEngine != synthesisEngine)) {
- throw new RuntimeException("Unit synthesisEngine already set.");
- }
- this.synthesisEngine = synthesisEngine;
- }
-
- public UnitGenerator getTopUnit() {
- UnitGenerator unit = this;
- // Climb to top of circuit hierarchy.
- while (unit.circuit != null) {
- unit = unit.circuit;
- }
- logger.fine("getTopUnit " + this + " => " + unit);
- return unit;
- }
-
- protected void autoStop() {
- synthesisEngine.autoStopUnit(getTopUnit());
- }
-
- /** Calculate signal based on halflife of an exponential decay. */
- public double convertHalfLifeToMultiplier(double halfLife) {
- if (halfLife < (2.0 * getFramePeriod())) {
- return 1.0;
- } else {
- // Oddly enough, this code is valid for both PeakFollower and AsymptoticRamp.
- return 1.0 - Math.pow(0.5, 1.0 / (halfLife * getSynthesisEngine().getFrameRate()));
- }
- }
-
- protected double incrementWrapPhase(double currentPhase, double phaseIncrement) {
- currentPhase += phaseIncrement;
-
- if (currentPhase >= 1.0) {
- currentPhase -= 2.0;
- } else if (currentPhase < -1.0) {
- currentPhase += 2.0;
- }
- return currentPhase;
- }
-
- /** Calculate rate based on phase going from 0.0 to 1.0 in time. */
- protected double convertTimeToRate(double time) {
- double period2X = synthesisEngine.getInverseNyquist();
- if (time < period2X) {
- return 1.0;
- } else {
- return getFramePeriod() / time;
- }
- }
-
- /** Flatten output ports so we don't output a changing signal when stopped. */
- public void flattenOutputs() {
- for (UnitPort port : ports.values()) {
- if (port instanceof UnitOutputPort) {
- ((UnitOutputPort) port).flatten();
- }
- }
- }
-
- public void setCircuit(Circuit circuit) {
- if ((this.circuit != null) && (circuit != null)) {
- throw new RuntimeException("Unit is already in a circuit.");
- }
- // logger.info( "setCircuit in unit " + this + " with circuit " + circuit );
- this.circuit = circuit;
- }
-
- public Circuit getCircuit() {
- return circuit;
- }
-
- public void pullData(long frameCount, int start, int limit) {
- // Don't generate twice in case the paths merge.
- if (enabled && (frameCount > lastFrameCount)) {
- // Do this first to block recursion when there is a feedback loop.
- lastFrameCount = frameCount;
- // Then pull from all the units that are upstream.
- for (UnitPort port : ports.values()) {
- if (port instanceof ConnectableInput) {
- ((ConnectableInput) port).pullData(frameCount, start, limit);
- }
- }
- // Finally generate using outputs of the upstream units.
- generate(start, limit);
- }
- }
-
- public boolean isEnabled() {
- return enabled;
- }
-
- /**
- * If enabled, then a unit will execute if its output is connected to another unit that is
- * executed. If not enabled then it will not execute and will not pull data from units that are
- * connected to its inputs. Disabling a unit at the output of a tree of units can be used to
- * turn off the entire tree, thus saving CPU cycles.
- *
- * @param enabled
- * @see UnitGate#setupAutoDisable(UnitGenerator)
- * @see start
- */
- public void setEnabled(boolean enabled) {
- this.enabled = enabled;
- if (!enabled) {
- flattenOutputs();
- }
- }
-
- /**
- * Some units, for example LineOut and FixedRateMonoWriter, will only work if
- * started explicitly. Other units will run when downstream units are started.
- *
- * @return true if you should call start() for this unit
- */
- public boolean isStartRequired() {
- return false;
- }
-
- /**
- * Start executing this unit directly by adding it to a "run list" of units in the synthesis
- * engine. This method is normally only called for the final unit in a chain, for example a
- * LineOut. When that final unit executes it will "pull" data from any units connected to its
- * inputs. Those units will then pull data their inputs until the entire chain is executed. If
- * units are connected in a circle then this will be detected and the infinite recursion will be
- * blocked.
- *
- * @see setEnabled
- */
- public void start() {
- if (getSynthesisEngine() == null) {
- throw new RuntimeException("This " + this.getClass().getName()
- + " was not add()ed to a Synthesizer.");
- }
- getSynthesisEngine().startUnit(this);
- }
-
- /**
- * Start a unit at the specified time.
- *
- * @param time
- * @see start
- */
- public void start(double time) {
- start(new TimeStamp(time));
- }
-
- /**
- * Start a unit at the specified time.
- *
- * @param timeStamp
- * @see start
- */
- public void start(TimeStamp timeStamp) {
- if (getSynthesisEngine() == null) {
- throw new RuntimeException("This " + this.getClass().getName()
- + " was not add()ed to a Synthesizer.");
- }
- getSynthesisEngine().startUnit(this, timeStamp);
- }
-
- /**
- * Stop a unit at the specified time.
- *
- * @param time
- * @see start
- */
- public void stop(double time) {
- stop(new TimeStamp(time));
- }
-
- public void stop() {
- getSynthesisEngine().stopUnit(this);
- }
-
- public void stop(TimeStamp timeStamp) {
- getSynthesisEngine().stopUnit(this, timeStamp);
- }
-
- /**
- * @deprecated ignored, frameRate comes from the SynthesisEngine
- * @param rate
- */
- @Deprecated
- public void setFrameRate(int rate) {
- }
-
- /** Needed by UnitSink */
- public UnitGenerator getUnitGenerator() {
- return this;
- }
-
- /** Needed by UnitVoice */
- public void setPort(String portName, double value, TimeStamp timeStamp) {
- UnitInputPort port = (UnitInputPort) getPortByName(portName);
- // System.out.println("setPort " + port );
- if (port == null) {
- logger.warning("port was null for name " + portName + ", " + this.getClass().getName());
- } else {
- port.set(value, timeStamp);
- }
- }
-
- public void printConnections() {
- printConnections(System.out);
- }
-
- public void printConnections(PrintStream out) {
- printConnections(out, 0);
- }
-
- public void printConnections(PrintStream out, int level) {
- for (UnitPort port : getPorts()) {
- if (port instanceof UnitInputPort) {
- ((UnitInputPort) port).printConnections(out, level);
- }
- }
- }
-
-}
diff --git a/src/com/jsyn/unitgen/UnitOscillator.java b/src/com/jsyn/unitgen/UnitOscillator.java
deleted file mode 100644
index 5d4c6fa..0000000
--- a/src/com/jsyn/unitgen/UnitOscillator.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright 2009 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;
-import com.jsyn.ports.UnitOutputPort;
-import com.jsyn.ports.UnitVariablePort;
-import com.softsynth.shared.time.TimeStamp;
-
-/**
- * Base class for all oscillators.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public abstract class UnitOscillator extends UnitGenerator implements UnitVoice {
- /** Frequency in Hertz. */
- public UnitInputPort frequency;
- public UnitInputPort amplitude;
- public UnitVariablePort phase;
- public UnitOutputPort output;
-
- public static final double DEFAULT_FREQUENCY = 440.0;
- public static final double DEFAULT_AMPLITUDE = 1.0;
-
- /* Define Unit Ports used by connect() and set(). */
- public UnitOscillator() {
- addPort(frequency = new UnitInputPort(PORT_NAME_FREQUENCY));
- frequency.setup(40.0, DEFAULT_FREQUENCY, 8000.0);
- addPort(amplitude = new UnitInputPort(PORT_NAME_AMPLITUDE, DEFAULT_AMPLITUDE));
- addPort(phase = new UnitVariablePort(PORT_NAME_PHASE));
- addPort(output = new UnitOutputPort(PORT_NAME_OUTPUT));
- }
-
- /**
- * Convert a frequency in Hertz to a phaseIncrement in the range -1.0 to +1.0
- */
- public double convertFrequencyToPhaseIncrement(double freq) {
- double phaseIncrement;
- try {
- phaseIncrement = freq * synthesisEngine.getInverseNyquist();
- } catch (NullPointerException e) {
- throw new NullPointerException(
- "Null Synth! You probably forgot to add this unit to the Synthesizer!");
- }
- // Clip to range.
- phaseIncrement = (phaseIncrement > 1.0) ? 1.0 : ((phaseIncrement < -1.0) ? -1.0
- : phaseIncrement);
- return phaseIncrement;
- }
-
- @Override
- public UnitOutputPort getOutput() {
- return output;
- }
-
- public void noteOn(double freq, double ampl) {
- frequency.set(freq);
- amplitude.set(ampl);
- }
-
- public void noteOff() {
- amplitude.set(0.0);
- }
-
- @Override
- public void noteOff(TimeStamp timeStamp) {
- amplitude.set(0.0, timeStamp);
- }
-
- @Override
- public void noteOn(double freq, double ampl, TimeStamp timeStamp) {
- frequency.set(freq, timeStamp);
- amplitude.set(ampl, timeStamp);
- }
-
- @Override
- public void usePreset(int presetIndex) {
- }
-}
diff --git a/src/com/jsyn/unitgen/UnitSink.java b/src/com/jsyn/unitgen/UnitSink.java
deleted file mode 100644
index 3e0f55e..0000000
--- a/src/com/jsyn/unitgen/UnitSink.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2009 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;
-import com.softsynth.shared.time.TimeStamp;
-
-/**
- * Interface for unit generators that have an input.
- *
- * @author Phil Burk, (C) 2009 Mobileer Inc
- */
-public interface UnitSink {
- public UnitInputPort getInput();
-
- /**
- * Begin execution of this unit by the Synthesizer. The input will pull data from any output
- * port that is connected from it.
- */
- public void start();
-
- public void start(TimeStamp timeStamp);
-
- public void stop();
-
- public void stop(TimeStamp timeStamp);
-
- public UnitGenerator getUnitGenerator();
-}
diff --git a/src/com/jsyn/unitgen/UnitSource.java b/src/com/jsyn/unitgen/UnitSource.java
deleted file mode 100644
index 5ee8134..0000000
--- a/src/com/jsyn/unitgen/UnitSource.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright 2009 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.UnitOutputPort;
-
-/**
- * Interface for things that have that have an output and an associated UnitGenerator.
- *
- * @author Phil Burk, (C) 2009 Mobileer Inc
- */
-public interface UnitSource {
- public UnitOutputPort getOutput();
-
- public UnitGenerator getUnitGenerator();
-}
diff --git a/src/com/jsyn/unitgen/UnitStreamWriter.java b/src/com/jsyn/unitgen/UnitStreamWriter.java
deleted file mode 100644
index 0c5bd8b..0000000
--- a/src/com/jsyn/unitgen/UnitStreamWriter.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2009 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.io.AudioOutputStream;
-import com.jsyn.ports.UnitInputPort;
-
-/**
- * Base class for writing to an AudioOutputStream.
- *
- * Note that you must call start() on subclasses of this unit because it does not have an output for pulling data.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public abstract class UnitStreamWriter extends UnitGenerator implements UnitSink {
- protected AudioOutputStream outputStream;
- public UnitInputPort input;
-
- public AudioOutputStream getOutputStream() {
- return outputStream;
- }
-
- public void setOutputStream(AudioOutputStream outputStream) {
- this.outputStream = outputStream;
- }
-
- /**
- * This unit won't do anything unless you start() it.
- */
- @Override
- public boolean isStartRequired() {
- return true;
- }
-
- @Override
- public UnitInputPort getInput() {
- return input;
- }
-}
diff --git a/src/com/jsyn/unitgen/UnitVoice.java b/src/com/jsyn/unitgen/UnitVoice.java
deleted file mode 100644
index 3f5e6ef..0000000
--- a/src/com/jsyn/unitgen/UnitVoice.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2011 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.util.Instrument;
-import com.jsyn.util.VoiceDescription;
-import com.softsynth.shared.time.TimeStamp;
-
-/**
- * A voice that can be allocated and played by the VoiceAllocator.
- *
- * @author Phil Burk (C) 2011 Mobileer Inc
- * @see VoiceDescription
- * @see Instrument
- */
-public interface UnitVoice extends UnitSource {
- /**
- * Play whatever you consider to be a note on this voice. Do not be constrained by traditional
- * definitions of notes or music.
- *
- * @param frequency in Hz related to the perceived pitch of the note.
- * @param amplitude generally between 0.0 and 1.0
- * @param timeStamp when to play the note
- */
- void noteOn(double frequency, double amplitude, TimeStamp timeStamp);
-
- void noteOff(TimeStamp timeStamp);
-
- /**
- * Typically a UnitVoice will be a subclass of UnitGenerator, which just returns "this".
- */
- @Override
- public UnitGenerator getUnitGenerator();
-
- /**
- * Looks up a port using its name and sets the value.
- *
- * @param portName
- * @param value
- * @param timeStamp
- */
- void setPort(String portName, double value, TimeStamp timeStamp);
-
- void usePreset(int presetIndex);
-}
diff --git a/src/com/jsyn/unitgen/Unzipper.java b/src/com/jsyn/unitgen/Unzipper.java
deleted file mode 100644
index c776ffb..0000000
--- a/src/com/jsyn/unitgen/Unzipper.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 2014 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;
-
-/**
- * Used inside UnitGenerators for fast smoothing of inputs.
- *
- * @author Phil Burk (C) 2014 Mobileer Inc
- */
-public class Unzipper {
- private double target;
- private double delta;
- private double current;
- private int counter;
- // About 30 msec. Power of 2 so divide should be faster.
- private static final int NUM_STEPS = 1024;
-
- public double smooth(double input) {
- if (input != target) {
- target = input;
- delta = (target - current) / NUM_STEPS;
- counter = NUM_STEPS;
- }
- if (counter > 0) {
- if (--counter == 0) {
- current = target;
- } else {
- current += delta;
- }
- }
- return current;
- }
-}
diff --git a/src/com/jsyn/unitgen/VariableRateDataReader.java b/src/com/jsyn/unitgen/VariableRateDataReader.java
deleted file mode 100644
index 2ef163c..0000000
--- a/src/com/jsyn/unitgen/VariableRateDataReader.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright 2009 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;
-
-public abstract class VariableRateDataReader extends SequentialDataReader {
- /** A scaler for playback rate. Nominally 1.0. */
- public UnitInputPort rate;
-
- public VariableRateDataReader() {
- super();
- addPort(rate = new UnitInputPort("Rate", 1.0));
- }
-}
diff --git a/src/com/jsyn/unitgen/VariableRateMonoReader.java b/src/com/jsyn/unitgen/VariableRateMonoReader.java
deleted file mode 100644
index 52b7f1e..0000000
--- a/src/com/jsyn/unitgen/VariableRateMonoReader.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright 2009 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.data.FloatSample;
-import com.jsyn.data.SegmentedEnvelope;
-import com.jsyn.data.ShortSample;
-import com.jsyn.ports.UnitOutputPort;
-
-/**
- * This reader can play any SequentialData and will interpolate between adjacent values. It can play
- * both {@link SegmentedEnvelope envelopes} and {@link FloatSample samples}.
- *
- * <pre><code>
- // Queue an envelope to the dataQueue port.
- ampEnv.dataQueue.queue(ampEnvelope);
-</code></pre>
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- * @see FloatSample
- * @see ShortSample
- * @see SegmentedEnvelope
- */
-public class VariableRateMonoReader extends VariableRateDataReader {
- private double phase; // ranges from 0.0 to 1.0
- private double baseIncrement;
- private double source;
- private double current;
- private double target;
- private boolean starved;
- private boolean ranout;
-
- public VariableRateMonoReader() {
- super();
- addPort(output = new UnitOutputPort("Output"));
- starved = true;
- baseIncrement = 1.0;
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] amplitudes = amplitude.getValues();
- double[] rates = rate.getValues();
- double[] outputs = output.getValues();
-
- for (int i = start; i < limit; i++) {
- // Decrement phase and advance through queued data until phase back
- // in range.
- if (phase >= 1.0) {
- while (phase >= 1.0) {
- source = target;
- phase -= 1.0;
- baseIncrement = advanceToNextFrame();
- }
- } else if ((i == 0) && (starved || !dataQueue.isTargetValid())) {
- // A starved condition can only be cured at the beginning of a
- // block.
- source = target = current;
- phase = 0.0;
- baseIncrement = advanceToNextFrame();
- }
-
- // Interpolate along line segment.
- current = ((target - source) * phase) + source;
- outputs[i] = current * amplitudes[i];
-
- double phaseIncrement = baseIncrement * rates[i];
- phase += limitPhaseIncrement(phaseIncrement);
- }
-
- if (ranout) {
- ranout = false;
- if (dataQueue.testAndClearAutoStop()) {
- autoStop();
- }
- }
- }
-
- public double limitPhaseIncrement(double phaseIncrement) {
- return phaseIncrement;
- }
-
- private double advanceToNextFrame() {
- // Fire callbacks before getting next value because we already got the
- // target value previously.
- dataQueue.firePendingCallbacks();
- if (dataQueue.hasMore()) {
- starved = false;
- target = dataQueue.readNextMonoDouble(getFramePeriod());
-
- // calculate phase increment;
- return getFramePeriod() * dataQueue.getNormalizedRate();
- } else {
- starved = true;
- ranout = true;
- phase = 0.0;
- return 0.0;
- }
- }
-
-}
diff --git a/src/com/jsyn/unitgen/VariableRateStereoReader.java b/src/com/jsyn/unitgen/VariableRateStereoReader.java
deleted file mode 100644
index 0f9fce8..0000000
--- a/src/com/jsyn/unitgen/VariableRateStereoReader.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright 2009 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.UnitOutputPort;
-
-/**
- * This reader can play any SequentialData and will interpolate between adjacent values. It can play
- * both envelopes and samples.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc
- */
-public class VariableRateStereoReader extends VariableRateDataReader {
- private double phase;
- private double baseIncrement;
- private double source0;
- private double current0;
- private double target0;
- private double source1;
- private double current1;
- private double target1;
- private boolean starved;
- private boolean ranout;
-
- public VariableRateStereoReader() {
- dataQueue.setNumChannels(2);
- addPort(output = new UnitOutputPort(2, "Output"));
- starved = true;
- baseIncrement = 1.0;
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] amplitudes = amplitude.getValues();
- double[] rates = rate.getValues();
- double[] output0s = output.getValues(0);
- double[] output1s = output.getValues(1);
-
- for (int i = start; i < limit; i++) {
- // Decrement phase and advance through queued data until phase back
- // in range.
- if (phase >= 1.0) {
- while (phase >= 1.0) {
- source0 = target0;
- source1 = target1;
- phase -= 1.0;
- baseIncrement = advanceToNextFrame();
- }
- } else if ((i == 0) && (starved || !dataQueue.isTargetValid())) {
- // A starved condition can only be cured at the beginning of a block.
- source0 = target0 = current0;
- source1 = target1 = current1;
- phase = 0.0;
- baseIncrement = advanceToNextFrame();
- }
-
- // Interpolate along line segment.
- current0 = ((target0 - source0) * phase) + source0;
- output0s[i] = current0 * amplitudes[i];
- current1 = ((target1 - source1) * phase) + source1;
- output1s[i] = current1 * amplitudes[i];
-
- double phaseIncrement = baseIncrement * rates[i];
- phase += limitPhaseIncrement(phaseIncrement);
- }
-
- if (ranout) {
- ranout = false;
- if (dataQueue.testAndClearAutoStop()) {
- autoStop();
- }
- }
- }
-
- public double limitPhaseIncrement(double phaseIncrement) {
- return phaseIncrement;
- }
-
- private double advanceToNextFrame() {
- dataQueue.firePendingCallbacks();
- if (dataQueue.hasMore()) {
- starved = false;
-
- dataQueue.beginFrame(getFramePeriod());
- target0 = dataQueue.readCurrentChannelDouble(0);
- target1 = dataQueue.readCurrentChannelDouble(1);
- dataQueue.endFrame();
-
- // calculate phase increment;
- return synthesisEngine.getFramePeriod() * dataQueue.getNormalizedRate();
- } else {
- starved = true;
- ranout = true;
- phase = 0.0;
- return 0.0;
- }
- }
-
-}
diff --git a/src/com/jsyn/unitgen/WhiteNoise.java b/src/com/jsyn/unitgen/WhiteNoise.java
deleted file mode 100644
index b708e92..0000000
--- a/src/com/jsyn/unitgen/WhiteNoise.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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;
-import com.jsyn.ports.UnitOutputPort;
-import com.jsyn.util.PseudoRandom;
-
-/**
- * WhiteNoise unit. This unit uses a pseudo-random number generator to produce white noise. The
- * energy in a white noise signal is distributed evenly across the spectrum. A new random number is
- * generated every frame.
- *
- * @author (C) 1997-2011 Phil Burk, Mobileer Inc
- * @see RedNoise
- */
-public class WhiteNoise extends UnitGenerator implements UnitSource {
- private PseudoRandom randomNum;
- public UnitInputPort amplitude;
- public UnitOutputPort output;
-
- public WhiteNoise() {
- randomNum = new PseudoRandom();
- addPort(amplitude = new UnitInputPort("Amplitude", UnitOscillator.DEFAULT_AMPLITUDE));
- addPort(output = new UnitOutputPort("Output"));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] amplitudes = amplitude.getValues();
- double[] outputs = output.getValues();
-
- for (int i = start; i < limit; i++) {
- outputs[i] = randomNum.nextRandomDouble() * amplitudes[i];
- }
- }
-
- @Override
- public UnitOutputPort getOutput() {
- return output;
- }
-}
diff --git a/src/com/jsyn/unitgen/ZeroCrossingCounter.java b/src/com/jsyn/unitgen/ZeroCrossingCounter.java
deleted file mode 100644
index 6cd36ea..0000000
--- a/src/com/jsyn/unitgen/ZeroCrossingCounter.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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;
-import com.jsyn.ports.UnitOutputPort;
-
-/**
- * Count zero crossings. Handy for unit tests.
- *
- * @author (C) 1997-2011 Phil Burk, Mobileer Inc
- */
-public class ZeroCrossingCounter extends UnitGenerator {
- private static final double THRESHOLD = 0.0001;
- public UnitInputPort input;
- public UnitOutputPort output;
-
- private long count;
- private boolean armed;
-
- /* Define Unit Ports used by connect() and set(). */
- public ZeroCrossingCounter() {
- addPort(input = new UnitInputPort("Input"));
- addPort(output = new UnitOutputPort("Output"));
- }
-
- @Override
- public void generate(int start, int limit) {
- double[] inputs = input.getValues();
- double[] outputs = output.getValues();
-
- for (int i = start; i < limit; i++) {
- double value = inputs[i];
- if (value < -THRESHOLD) {
- armed = true;
- } else if (armed & (value > THRESHOLD)) {
- ++count;
- armed = false;
- }
- outputs[i] = value;
- }
- }
-
- public long getCount() {
- return count;
- }
-}
diff --git a/src/com/jsyn/util/AudioSampleLoader.java b/src/com/jsyn/util/AudioSampleLoader.java
deleted file mode 100644
index b665933..0000000
--- a/src/com/jsyn/util/AudioSampleLoader.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2009 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.util;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-
-import com.jsyn.data.FloatSample;
-
-public interface AudioSampleLoader {
- /**
- * Load a FloatSample from a File object.
- */
- public FloatSample loadFloatSample(File fileIn) throws IOException;
-
- /**
- * Load a FloatSample from an InputStream. This is handy when loading Resources from a JAR file.
- */
- public FloatSample loadFloatSample(InputStream inputStream) throws IOException;
-
- /**
- * Load a FloatSample from a URL.. This is handy when loading Resources from a website.
- */
- public FloatSample loadFloatSample(URL url) throws IOException;
-
-}
diff --git a/src/com/jsyn/util/AudioStreamReader.java b/src/com/jsyn/util/AudioStreamReader.java
deleted file mode 100644
index 5a725c3..0000000
--- a/src/com/jsyn/util/AudioStreamReader.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright 2010 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.util;
-
-import com.jsyn.Synthesizer;
-import com.jsyn.io.AudioFifo;
-import com.jsyn.io.AudioInputStream;
-import com.jsyn.ports.UnitInputPort;
-import com.jsyn.unitgen.MonoStreamWriter;
-import com.jsyn.unitgen.StereoStreamWriter;
-import com.jsyn.unitgen.UnitStreamWriter;
-
-/**
- * Reads audio signals from the background engine to a foreground application through an AudioFifo.
- * Connect to the input port returned by getInput().
- *
- * @author Phil Burk (C) 2010 Mobileer Inc
- */
-public class AudioStreamReader implements AudioInputStream {
- private UnitStreamWriter streamWriter;
- private AudioFifo fifo;
-
- public AudioStreamReader(Synthesizer synth, int samplesPerFrame) {
- if (samplesPerFrame == 1) {
- streamWriter = new MonoStreamWriter();
- } else if (samplesPerFrame == 2) {
- streamWriter = new StereoStreamWriter();
- } else {
- throw new IllegalArgumentException("Only 1 or 2 samplesPerFrame supported.");
- }
- synth.add(streamWriter);
-
- fifo = new AudioFifo();
- fifo.setWriteWaitEnabled(!synth.isRealTime());
- fifo.setReadWaitEnabled(true);
- fifo.allocate(32 * 1024);
- streamWriter.setOutputStream(fifo);
- streamWriter.start();
- }
-
- public UnitInputPort getInput() {
- return streamWriter.input;
- }
-
- /** How many values are available to read without blocking? */
- @Override
- public int available() {
- return fifo.available();
- }
-
- @Override
- public void close() {
- fifo.close();
- }
-
- @Override
- public double read() {
- return fifo.read();
- }
-
- @Override
- public int read(double[] buffer) {
- return fifo.read(buffer);
- }
-
- @Override
- public int read(double[] buffer, int start, int count) {
- return fifo.read(buffer, start, count);
- }
-
-}
diff --git a/src/com/jsyn/util/AutoCorrelator.java b/src/com/jsyn/util/AutoCorrelator.java
deleted file mode 100644
index 2996036..0000000
--- a/src/com/jsyn/util/AutoCorrelator.java
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Copyright 2004 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.util;
-
-/**
- * Calculate period of a repeated waveform in an array. This algorithm is based on a normalized
- * auto-correlation function as dewscribed in: "A Smarter Way to Find Pitch" by Philip McLeod and
- * Geoff Wyvill
- *
- * @author (C) 2004 Mobileer, PROPRIETARY and CONFIDENTIAL
- */
-public class AutoCorrelator implements SignalCorrelator {
- // A higher number will reject suboctaves more.
- private static final float SUB_OCTAVE_REJECTION_FACTOR = 0.0005f;
- // We can focus our analysis on the maxima
- private static final int STATE_SEEKING_NEGATIVE = 0;
- private static final int STATE_SEEKING_POSITIVE = 1;
- private static final int STATE_SEEKING_MAXIMUM = 2;
- private static final int[] tauAdvanceByState = {
- 4, 2, 1
- };
- private int state;
-
- private float[] buffer;
- // double buffer the diffs so we can view them
- private float[] diffs;
- private float[] diffs1;
- private float[] diffs2;
- private int cursor = -1;
- private int tau;
-
- private float sumProducts;
- private float sumSquares;
- private float localMaximum;
- private int localPosition;
- private float bestMaximum;
- private int bestPosition;
- private int peakCounter;
- // This factor was found empirically to reduce a systematic offset in the pitch.
- private float pitchCorrectionFactor = 0.99988f;
-
- // Results of analysis.
- private double period;
- private double confidence;
- private int minPeriod = 2;
- private boolean bufferValid;
- private double previousSample = 0.0;
- private int maxWindowSize;
- private float noiseThreshold = 0.001f;
-
- public AutoCorrelator(int numFrames) {
- buffer = new float[numFrames];
- maxWindowSize = buffer.length / 2;
- diffs1 = new float[2 + numFrames / 2];
- diffs2 = new float[diffs1.length];
- diffs = diffs1;
- period = minPeriod;
- reset();
- }
-
- // Scan assuming we will not wrap around the buffer.
- private void rawDeltaScan(int last1, int last2, int count, int stride) {
- for (int k = 0; k < count; k += stride) {
- float d1 = buffer[last1 - k];
- float d2 = buffer[last2 - k];
- sumProducts += d1 * d2;
- sumSquares += ((d1 * d1) + (d2 * d2));
- }
- }
-
- // Do correlation when we know the splitLast will wrap around.
- private void splitDeltaScan(int last1, int splitLast, int count, int stride) {
- int c1 = splitLast;
- rawDeltaScan(last1, splitLast, c1, stride);
- rawDeltaScan(last1 - c1, buffer.length - 1, count - c1, stride);
- }
-
- private void checkDeltaScan(int last1, int last2, int count, int stride) {
- if (count > last2) {
- int c1 = last2;
- // Use recursion with reverse indexes to handle a double split.
- checkDeltaScan(last2, last1, c1, stride);
- checkDeltaScan(buffer.length - 1, last1 - c1, count - c1, stride);
- } else if (count > last1) {
- splitDeltaScan(last2, last1, count, stride);
- } else {
- rawDeltaScan(last1, last2, count, stride);
- }
- }
-
- // Perform correlation. Handle circular buffer wrap around.
- // Normalized square difference function between -1.0 and +1.0.
- private float topScan(int last1, int tau, int count, int stride) {
- final float minimumResult = 0.00000001f;
-
- int last2 = last1 - tau;
- if (last2 < 0) {
- last2 += buffer.length;
- }
- sumProducts = 0.0f;
- sumSquares = 0.0f;
- checkDeltaScan(last1, last2, count, stride);
- // Prevent divide by zero.
- if (sumSquares < minimumResult) {
- return minimumResult;
- }
- float correction = (float) Math.pow(pitchCorrectionFactor, tau);
- float result = (float) (2.0 * sumProducts / sumSquares) * correction;
-
- return result;
- }
-
- // Prepare for a new calculation.
- private void reset() {
- switchDiffs();
- int i = 0;
- for (; i < minPeriod; i++) {
- diffs[i] = 1.0f;
- }
- for (; i < diffs.length; i++) {
- diffs[i] = 0.0f;
- }
- tau = minPeriod;
- state = STATE_SEEKING_NEGATIVE;
- peakCounter = 0;
- bestMaximum = -1.0f;
- bestPosition = -1;
- }
-
- // Analyze new diff result. Incremental peak detection.
- private void nextPeakAnalysis(int index) {
- // Scale low frequency correlation down to reduce suboctave matching.
- // Note that this has a side effect of reducing confidence value for low frequency sounds.
- float value = diffs[index] * (1.0f - (index * SUB_OCTAVE_REJECTION_FACTOR));
- switch (state) {
- case STATE_SEEKING_NEGATIVE:
- if (value < -0.01f) {
- state = STATE_SEEKING_POSITIVE;
- }
- break;
- case STATE_SEEKING_POSITIVE:
- if (value > 0.2f) {
- state = STATE_SEEKING_MAXIMUM;
- localMaximum = value;
- localPosition = index;
- }
- break;
- case STATE_SEEKING_MAXIMUM:
- if (value > localMaximum) {
- localMaximum = value;
- localPosition = index;
- } else if (value < -0.1f) {
- peakCounter += 1;
- if (localMaximum > bestMaximum) {
- bestMaximum = localMaximum;
- bestPosition = localPosition;
- }
- state = STATE_SEEKING_POSITIVE;
- }
- break;
- }
- }
-
- /**
- * Generate interpolated maximum from index of absolute maximum using three point analysis.
- */
- private double findPreciseMaximum(int indexMax) {
- if (indexMax < 3) {
- return 3.0;
- }
- if (indexMax == (diffs.length - 1)) {
- return indexMax;
- }
- // Get 3 adjacent values.
- double d1 = diffs[indexMax - 1];
- double d2 = diffs[indexMax];
- double d3 = diffs[indexMax + 1];
-
- return interpolatePeak(d1, d2, d3) + indexMax;
- }
-
- // Use quadratic fit to return offset between -0.5 and +0.5 from center.
- protected static double interpolatePeak(double d1, double d2, double d3) {
- return 0.5 * (d1 - d3) / (d1 - (2.0 * d2) + d3);
- }
-
- // Calculate a little more for each sample.
- // This spreads the CPU load out more evenly.
- private boolean incrementalAnalysis() {
- boolean updated = false;
- if (bufferValid) {
- // int windowSize = maxWindowSize;
- // Interpolate between tau and maxWindowsSize based on confidence.
- // If confidence is low then use bigger window.
- int windowSize = (int) ((tau * confidence) + (maxWindowSize * (1.0 - confidence)));
-
- int stride = 1;
- // int stride = (windowSize / 32) + 1;
-
- diffs[tau] = topScan(cursor, tau, windowSize, stride);
-
- // Check to see if the signal is strong enough to analyze.
- // Look at sumPeriods on first correlation.
- if ((tau == minPeriod) && (sumProducts < noiseThreshold)) {
- // Update if we are dropping to zero confidence.
- boolean result = (confidence > 0.0);
- confidence = 0.0;
- return result;
- }
-
- nextPeakAnalysis(tau);
-
- // Reuse calculated values if we are not near a peak.
- tau += 1;
- int advance = tauAdvanceByState[state] - 1;
- while ((advance > 0) && (tau < diffs.length)) {
- diffs[tau] = diffs[tau - 1];
- tau++;
- advance--;
- }
-
- if ((peakCounter >= 4) || (tau >= maxWindowSize)) {
- if (bestMaximum > 0.0) {
- period = findPreciseMaximum(bestPosition);
- // clip into range 0.0 to 1.0, low values are really bogus
- confidence = (bestMaximum < 0.0) ? 0.0 : bestMaximum;
- } else {
- confidence = 0.0;
- }
- updated = true;
- reset();
- }
- }
- return updated;
- }
-
- @Override
- public float[] getDiffs() {
- // Return diffs that are not currently being used
- return (diffs == diffs1) ? diffs2 : diffs1;
- }
-
- private void switchDiffs() {
- diffs = (diffs == diffs1) ? diffs2 : diffs1;
- }
-
- @Override
- public boolean addSample(double value) {
- double average = (value + previousSample) * 0.5;
- previousSample = value;
-
- cursor += 1;
- if (cursor == buffer.length) {
- cursor = 0;
- bufferValid = true;
- }
- buffer[cursor] = (float) average;
-
- return incrementalAnalysis();
- }
-
- @Override
- public double getPeriod() {
- return period;
- }
-
- @Override
- public double getConfidence() {
- return confidence;
- }
-
- public float getPitchCorrectionFactor() {
- return pitchCorrectionFactor;
- }
-
- public void setPitchCorrectionFactor(float pitchCorrectionFactor) {
- this.pitchCorrectionFactor = pitchCorrectionFactor;
- }
-}
diff --git a/src/com/jsyn/util/Instrument.java b/src/com/jsyn/util/Instrument.java
deleted file mode 100644
index 8a53304..0000000
--- a/src/com/jsyn/util/Instrument.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2011 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.util;
-
-import com.softsynth.shared.time.TimeStamp;
-
-/**
- * A note player that references one or more voices by a noteNumber. This is similar to the MIDI
- * protocol that references voices by an integer pitch or keyIndex.
- *
- * @author Phil Burk (C) 2011 Mobileer Inc
- */
-public interface Instrument {
- // This will be applied to the voice when noteOn is called.
- void usePreset(int presetIndex, TimeStamp timeStamp);
-
- public void noteOn(int tag, double frequency, double amplitude, TimeStamp timeStamp);
-
- public void noteOff(int tag, TimeStamp timeStamp);
-
- public void setPort(int tag, String portName, double value, TimeStamp timeStamp);
-
- public void allNotesOff(TimeStamp timeStamp);
-}
diff --git a/src/com/jsyn/util/InstrumentLibrary.java b/src/com/jsyn/util/InstrumentLibrary.java
deleted file mode 100644
index 65113dc..0000000
--- a/src/com/jsyn/util/InstrumentLibrary.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2011 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.util;
-
-import com.jsyn.swing.InstrumentBrowser;
-
-/**
- * A library of instruments that can be used to play notes.
- *
- * @author Phil Burk (C) 2011 Mobileer Inc
- * @see InstrumentBrowser
- */
-
-public interface InstrumentLibrary {
- public String getName();
-
- public VoiceDescription[] getVoiceDescriptions();
-}
diff --git a/src/com/jsyn/util/JavaSoundSampleLoader.java b/src/com/jsyn/util/JavaSoundSampleLoader.java
deleted file mode 100644
index 56a654e..0000000
--- a/src/com/jsyn/util/JavaSoundSampleLoader.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright 2011 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.util;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-
-import javax.sound.sampled.AudioFormat;
-import javax.sound.sampled.AudioInputStream;
-import javax.sound.sampled.AudioSystem;
-import javax.sound.sampled.UnsupportedAudioFileException;
-
-import com.jsyn.data.FloatSample;
-
-/**
- * Internal class for loading audio samples. Use SampleLoader instead.
- *
- * @author Phil Burk (C) 2011 Mobileer Inc
- */
-class JavaSoundSampleLoader implements AudioSampleLoader {
- /**
- * Load a FloatSample from a File object.
- */
- @Override
- public FloatSample loadFloatSample(File fileIn) throws IOException {
- try {
- return loadFloatSample(AudioSystem.getAudioInputStream(fileIn));
- } catch (UnsupportedAudioFileException e) {
- throw new IOException(e);
- }
- }
-
- /**
- * Load a FloatSample from an InputStream. This is handy when loading Resources from a JAR file.
- */
- @Override
- public FloatSample loadFloatSample(InputStream inputStream) throws IOException {
- try {
- return loadFloatSample(AudioSystem.getAudioInputStream(inputStream));
- } catch (UnsupportedAudioFileException e) {
- throw new IOException(e);
- }
- }
-
- /**
- * Load a FloatSample from a URL.. This is handy when loading Resources from a website.
- */
- @Override
- public FloatSample loadFloatSample(URL url) throws IOException {
- try {
- return loadFloatSample(AudioSystem.getAudioInputStream(url));
- } catch (UnsupportedAudioFileException e) {
- throw new IOException(e);
- }
- }
-
- private FloatSample loadFloatSample(javax.sound.sampled.AudioInputStream audioInputStream)
- throws IOException, UnsupportedAudioFileException {
- float[] floatData = null;
- FloatSample sample = null;
- int bytesPerFrame = audioInputStream.getFormat().getFrameSize();
- if (bytesPerFrame == AudioSystem.NOT_SPECIFIED) {
- // some audio formats may have unspecified frame size
- // in that case we may read any amount of bytes
- bytesPerFrame = 1;
- }
- AudioFormat format = audioInputStream.getFormat();
- if (format.getEncoding() == AudioFormat.Encoding.PCM_SIGNED) {
- floatData = loadSignedPCM(audioInputStream);
- }
- sample = new FloatSample(floatData, format.getChannels());
- sample.setFrameRate(format.getFrameRate());
- return sample;
- }
-
- private float[] loadSignedPCM(AudioInputStream audioInputStream) throws IOException,
- UnsupportedAudioFileException {
- int totalSamplesRead = 0;
- AudioFormat format = audioInputStream.getFormat();
- int numFrames = (int) audioInputStream.getFrameLength();
- int numSamples = format.getChannels() * numFrames;
- float[] data = new float[numSamples];
- final int bytesPerFrame = format.getFrameSize();
- // Set an arbitrary buffer size of 1024 frames.
- int numBytes = 1024 * bytesPerFrame;
- byte[] audioBytes = new byte[numBytes];
- int numBytesRead = 0;
- int numFramesRead = 0;
- // Try to read numBytes bytes from the file.
- while ((numBytesRead = audioInputStream.read(audioBytes)) != -1) {
- int bytesRemainder = numBytesRead % bytesPerFrame;
- if (bytesRemainder != 0) {
- // TODO Read until you get enough data.
- throw new IOException("Read partial block of sample data!");
- }
-
- if (audioInputStream.getFormat().getSampleSizeInBits() == 16) {
- if (format.isBigEndian()) {
- SampleLoader.decodeBigI16ToF32(audioBytes, 0, numBytesRead, data,
- totalSamplesRead);
- } else {
- SampleLoader.decodeLittleI16ToF32(audioBytes, 0, numBytesRead, data,
- totalSamplesRead);
- }
- } else if (audioInputStream.getFormat().getSampleSizeInBits() == 24) {
- if (format.isBigEndian()) {
- SampleLoader.decodeBigI24ToF32(audioBytes, 0, numBytesRead, data,
- totalSamplesRead);
- } else {
- SampleLoader.decodeLittleI24ToF32(audioBytes, 0, numBytesRead, data,
- totalSamplesRead);
- }
- } else if (audioInputStream.getFormat().getSampleSizeInBits() == 32) {
- if (format.isBigEndian()) {
- SampleLoader.decodeBigI32ToF32(audioBytes, 0, numBytesRead, data,
- totalSamplesRead);
- } else {
- SampleLoader.decodeLittleI32ToF32(audioBytes, 0, numBytesRead, data,
- totalSamplesRead);
- }
- } else {
- throw new UnsupportedAudioFileException(
- "Only 16, 24 or 32 bit PCM samples supported.");
- }
-
- // Calculate the number of frames actually read.
- numFramesRead = numBytesRead / bytesPerFrame;
- totalSamplesRead += numFramesRead * format.getChannels();
- }
- return data;
- }
-
-}
diff --git a/src/com/jsyn/util/JavaTools.java b/src/com/jsyn/util/JavaTools.java
deleted file mode 100644
index 65e3dd1..0000000
--- a/src/com/jsyn/util/JavaTools.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2009 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.util;
-
-public class JavaTools {
-
- @SuppressWarnings("rawtypes")
- public static Class loadClass(String className, boolean verbose) {
- Class newClass = null;
- try {
- newClass = Class.forName(className);
- } catch (Throwable e) {
- if (verbose)
- System.out.println("Caught " + e);
- }
- if (newClass == null) {
- try {
- ClassLoader systemLoader = ClassLoader.getSystemClassLoader();
- newClass = Class.forName(className, true, systemLoader);
- } catch (Throwable e) {
- if (verbose)
- System.out.println("Caught " + e);
- }
- }
- return newClass;
- }
-
- /**
- * First try Class.forName(). If this fails, try Class.forName() using
- * ClassLoader.getSystemClassLoader().
- *
- * @return Class or null
- */
- @SuppressWarnings("rawtypes")
- public static Class loadClass(String className) {
- /**
- * First try Class.forName(). If this fails, try Class.forName() using
- * ClassLoader.getSystemClassLoader().
- *
- * @return Class or null
- */
- return loadClass(className, true);
- }
-
-}
diff --git a/src/com/jsyn/util/MultiChannelSynthesizer.java b/src/com/jsyn/util/MultiChannelSynthesizer.java
deleted file mode 100644
index b84d753..0000000
--- a/src/com/jsyn/util/MultiChannelSynthesizer.java
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- * Copyright 2016 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.util;
-
-import com.jsyn.Synthesizer;
-import com.jsyn.engine.SynthesisEngine;
-import com.jsyn.midi.MidiConstants;
-import com.jsyn.ports.UnitInputPort;
-import com.jsyn.ports.UnitOutputPort;
-import com.jsyn.unitgen.ExponentialRamp;
-import com.jsyn.unitgen.LinearRamp;
-import com.jsyn.unitgen.Multiply;
-import com.jsyn.unitgen.Pan;
-import com.jsyn.unitgen.PowerOfTwo;
-import com.jsyn.unitgen.SineOscillator;
-import com.jsyn.unitgen.TwoInDualOut;
-import com.jsyn.unitgen.UnitGenerator;
-import com.jsyn.unitgen.UnitOscillator;
-import com.jsyn.unitgen.UnitVoice;
-import com.softsynth.math.AudioMath;
-import com.softsynth.shared.time.TimeStamp;
-
-/**
- * General purpose synthesizer with "channels"
- * that could be used to implement a MIDI synthesizer.
- *
- * Each channel has:
- * <pre><code>
- * lfo -&gt; pitchToLinear -&gt; [VOICES] -&gt; volume* -&gt; panner
- * bend --/
- * </code></pre>
- *
- * Note: this class is experimental and subject to change.
- *
- * @author Phil Burk (C) 2016 Mobileer Inc
- */
-public class MultiChannelSynthesizer {
- private Synthesizer synth;
- private TwoInDualOut outputUnit;
- private ChannelContext[] channels;
- private final static int MAX_VELOCITY = 127;
- private double mMasterAmplitude = 0.25;
-
- private class ChannelGroupContext {
- private VoiceDescription voiceDescription;
- private UnitVoice[] voices;
- private VoiceAllocator allocator;
-
- ChannelGroupContext(int numVoices, VoiceDescription voiceDescription) {
- this.voiceDescription = voiceDescription;
-
- voices = new UnitVoice[numVoices];
- for (int i = 0; i < numVoices; i++) {
- UnitVoice voice = voiceDescription.createUnitVoice();
- UnitGenerator ugen = voice.getUnitGenerator();
- synth.add(ugen);
- voices[i] = voice;
-
- }
- allocator = new VoiceAllocator(voices);
- }
- }
-
- private class ChannelContext {
- private UnitOscillator lfo;
- private PowerOfTwo pitchToLinear;
- private LinearRamp timbreRamp;
- private LinearRamp pressureRamp;
- private ExponentialRamp volumeRamp;
- private Multiply volumeMultiplier;
- private Pan panner;
- private double vibratoRate = 5.0;
- private double bendRangeOctaves = 2.0 / 12.0;
- private int presetIndex;
- private ChannelGroupContext groupContext;
- VoiceOperation voiceOperation = new VoiceOperation() {
- @Override
- public void operate (UnitVoice voice) {
- voice.usePreset(presetIndex);
- connectVoice(voice);
- }
- };
-
- void setup(ChannelGroupContext groupContext) {
- this.groupContext = groupContext;
- synth.add(pitchToLinear = new PowerOfTwo());
- synth.add(lfo = new SineOscillator()); // TODO use a MorphingOscillator or switch
- // between S&H etc.
- // Use a ramp to smooth out the timbre changes.
- // This helps reduce pops from changing filter cutoff too abruptly.
- synth.add(timbreRamp = new LinearRamp());
- timbreRamp.time.set(0.02);
- synth.add(pressureRamp = new LinearRamp());
- pressureRamp.time.set(0.02);
- synth.add(volumeRamp = new ExponentialRamp());
- volumeRamp.input.set(1.0);
- volumeRamp.time.set(0.02);
- synth.add(volumeMultiplier = new Multiply());
- synth.add(panner = new Pan());
-
- pitchToLinear.input.setValueAdded(true); // so we can sum pitch bend
- lfo.output.connect(pitchToLinear.input);
- lfo.amplitude.set(0.0);
- lfo.frequency.set(vibratoRate);
-
- volumeRamp.output.connect(volumeMultiplier.inputB);
- volumeMultiplier.output.connect(panner.input);
- panner.output.connect(0, outputUnit.inputA, 0); // Use MultiPassthrough
- panner.output.connect(1, outputUnit.inputB, 0);
- }
-
- private void connectVoice(UnitVoice voice) {
- UnitGenerator ugen = voice.getUnitGenerator();
- // Hook up some channel controllers to standard ports on the voice.
- UnitInputPort freqMod = (UnitInputPort) ugen
- .getPortByName(UnitGenerator.PORT_NAME_FREQUENCY_SCALER);
- if (freqMod != null) {
- freqMod.disconnectAll();
- pitchToLinear.output.connect(freqMod);
- }
- UnitInputPort timbrePort = (UnitInputPort) ugen
- .getPortByName(UnitGenerator.PORT_NAME_TIMBRE);
- if (timbrePort != null) {
- timbrePort.disconnectAll();
- timbreRamp.output.connect(timbrePort);
- timbreRamp.input.setup(timbrePort);
- }
- UnitInputPort pressurePort = (UnitInputPort) ugen
- .getPortByName(UnitGenerator.PORT_NAME_PRESSURE);
- if (pressurePort != null) {
- pressurePort.disconnectAll();
- pressureRamp.output.connect(pressurePort);
- pressureRamp.input.setup(pressurePort);
- }
- voice.getOutput().disconnectAll();
- voice.getOutput().connect(volumeMultiplier.inputA); // mono mix all the voices
- }
-
- void programChange(int program) {
- int programWrapped = program % groupContext.voiceDescription.getPresetCount();
- String name = groupContext.voiceDescription.getPresetNames()[programWrapped];
- //System.out.println("Preset[" + program + "] = " + name);
- presetIndex = programWrapped;
- }
-
- void noteOff(int noteNumber, double amplitude) {
- groupContext.allocator.noteOff(noteNumber, synth.createTimeStamp());
- }
-
- void noteOff(int noteNumber, double amplitude, TimeStamp timeStamp) {
- groupContext.allocator.noteOff(noteNumber, timeStamp);
- }
-
- void noteOn(int noteNumber, double amplitude) {
- noteOn(noteNumber, amplitude, synth.createTimeStamp());
- }
-
- void noteOn(int noteNumber, double amplitude, TimeStamp timeStamp) {
- double frequency = AudioMath.pitchToFrequency(noteNumber);
- //System.out.println("noteOn(noteNumber) -> " + frequency + " Hz");
- groupContext.allocator.noteOn(noteNumber, frequency, amplitude, voiceOperation, timeStamp);
- }
-
- public void setPitchBend(double offset) {
- pitchToLinear.input.set(bendRangeOctaves * offset);
- }
-
- public void setBendRange(double semitones) {
- bendRangeOctaves = semitones / 12.0;
- }
-
- public void setVibratoDepth(double semitones) {
- lfo.amplitude.set(semitones);
- }
-
- public void setVolume(double volume) {
- double min = SynthesisEngine.DB96;
- double max = 1.0;
- double ratio = max / min;
- double value = min * Math.pow(ratio, volume);
- volumeRamp.input.set(value);
- }
-
- public void setPan(double pan) {
- panner.pan.set(pan);
- }
-
- /*
- * @param timbre normalized 0 to 1
- */
- public void setTimbre(double timbre) {
- double min = timbreRamp.input.getMinimum();
- double max = timbreRamp.input.getMaximum();
- double value = min + (timbre * (max - min));
- timbreRamp.input.set(value);
- }
-
- /*
- * @param pressure normalized 0 to 1
- */
- public void setPressure(double pressure) {
- double min = pressureRamp.input.getMinimum();
- double max = pressureRamp.input.getMaximum();
- double ratio = max / min;
- double value = min * Math.pow(ratio, pressure);
- pressureRamp.input.set(value);
- }
- }
-
- /**
- * Construct a synthesizer with a maximum of 16 channels like MIDI.
- */
- public MultiChannelSynthesizer() {
- this(MidiConstants.MAX_CHANNELS);
- }
-
-
- public MultiChannelSynthesizer(int maxChannels) {
- channels = new ChannelContext[maxChannels];
- for (int i = 0; i < channels.length; i++) {
- channels[i] = new ChannelContext();
- }
- }
-
- /**
- * Specify a VoiceDescription to use with multiple channels.
- *
- * @param synth
- * @param startChannel channel index is zero based
- * @param numChannels
- * @param voicesPerChannel
- * @param voiceDescription
- */
- public void setup(Synthesizer synth, int startChannel, int numChannels, int voicesPerChannel,
- VoiceDescription voiceDescription) {
- this.synth = synth;
- if (outputUnit == null) {
- synth.add(outputUnit = new TwoInDualOut());
- }
- ChannelGroupContext groupContext = new ChannelGroupContext(voicesPerChannel,
- voiceDescription);
- for (int i = 0; i < numChannels; i++) {
- channels[startChannel + i].setup(groupContext);
- }
- }
-
- public void programChange(int channel, int program) {
- ChannelContext channelContext = channels[channel];
- channelContext.programChange(program);
- }
-
-
- /**
- * Turn off a note.
- * @param channel
- * @param noteNumber
- * @param velocity between 0 and 127, will be scaled by masterAmplitude
- */
- public void noteOff(int channel, int noteNumber, int velocity) {
- double amplitude = velocity * (1.0 / MAX_VELOCITY);
- noteOff(channel, noteNumber, amplitude);
- }
-
- /**
- * Turn off a note.
- * @param channel
- * @param noteNumber
- * @param amplitude between 0 and 1.0, will be scaled by masterAmplitude
- */
- public void noteOff(int channel, int noteNumber, double amplitude) {
- ChannelContext channelContext = channels[channel];
- channelContext.noteOff(noteNumber, amplitude * mMasterAmplitude);
- }
-
- /**
- * Turn off a note.
- * @param channel
- * @param noteNumber
- * @param amplitude between 0 and 1.0, will be scaled by masterAmplitude
- */
- public void noteOff(int channel, int noteNumber, double amplitude, TimeStamp timeStamp) {
- ChannelContext channelContext = channels[channel];
- channelContext.noteOff(noteNumber, amplitude * mMasterAmplitude, timeStamp);
- }
-
- /**
- * Turn on a note.
- * @param channel
- * @param noteNumber
- * @param velocity between 0 and 127, will be scaled by masterAmplitude
- */
- public void noteOn(int channel, int noteNumber, int velocity) {
- double amplitude = velocity * (1.0 / MAX_VELOCITY);
- noteOn(channel, noteNumber, amplitude);
- }
-
- /**
- * Turn on a note.
- * @param channel
- * @param noteNumber
- * @param amplitude between 0 and 1.0, will be scaled by masterAmplitude
- */
- public void noteOn(int channel, int noteNumber, double amplitude, TimeStamp timeStamp) {
- ChannelContext channelContext = channels[channel];
- channelContext.noteOn(noteNumber, amplitude * mMasterAmplitude, timeStamp);
- }
-
- /**
- * Turn on a note.
- * @param channel
- * @param noteNumber
- * @param amplitude between 0 and 1.0, will be scaled by masterAmplitude
- */
- public void noteOn(int channel, int noteNumber, double amplitude) {
- ChannelContext channelContext = channels[channel];
- channelContext.noteOn(noteNumber, amplitude * mMasterAmplitude);
- }
-
- /**
- * Set a pitch offset that will be scaled by the range for the channel.
- *
- * @param channel
- * @param offset ranges from -1.0 to +1.0
- */
- public void setPitchBend(int channel, double offset) {
- //System.out.println("setPitchBend[" + channel + "] = " + offset);
- ChannelContext channelContext = channels[channel];
- channelContext.setPitchBend(offset);
- }
-
- public void setBendRange(int channel, double semitones) {
- ChannelContext channelContext = channels[channel];
- channelContext.setBendRange(semitones);
- }
-
- public void setPressure(int channel, double pressure) {
- ChannelContext channelContext = channels[channel];
- channelContext.setPressure(pressure);
- }
-
- public void setVibratoDepth(int channel, double semitones) {
- ChannelContext channelContext = channels[channel];
- channelContext.setVibratoDepth(semitones);
- }
-
- public void setTimbre(int channel, double timbre) {
- ChannelContext channelContext = channels[channel];
- channelContext.setTimbre(timbre);
- }
-
- /**
- * Set volume for entire channel.
- *
- * @param channel
- * @param volume normalized between 0.0 and 1.0
- */
- public void setVolume(int channel, double volume) {
- ChannelContext channelContext = channels[channel];
- channelContext.setVolume(volume);
- }
-
- /**
- * Pan from left to right.
- *
- * @param channel
- * @param pan ranges from -1.0 to +1.0
- */
- public void setPan(int channel, double pan) {
- ChannelContext channelContext = channels[channel];
- channelContext.setPan(pan);
- }
-
- /**
- * @return stereo output port
- */
- public UnitOutputPort getOutput() {
- return outputUnit.output;
- }
-
- /**
- * Set amplitude for a single voice when the velocity is 127.
- * @param masterAmplitude
- */
- public void setMasterAmplitude(double masterAmplitude) {
- mMasterAmplitude = masterAmplitude;
- }
- public double getMasterAmplitude() {
- return mMasterAmplitude;
- }
-}
diff --git a/src/com/jsyn/util/NumericOutput.java b/src/com/jsyn/util/NumericOutput.java
deleted file mode 100644
index 79afaf1..0000000
--- a/src/com/jsyn/util/NumericOutput.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright 1999 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.util;
-
-/**
- * Formatted numeric output. Convert integers and floats to strings based on field widths and
- * desired decimal places.
- *
- * @author Phil Burk (C) 1999 SoftSynth.com
- */
-
-public class NumericOutput {
- static char digitToChar(int digit) {
- if (digit > 9) {
- return (char) ('A' + digit - 10);
- } else {
- return (char) ('0' + digit);
- }
- }
-
- public static String integerToString(int n, int width, boolean leadingZeros) {
- return integerToString(n, width, leadingZeros, 10);
- }
-
- public static String integerToString(int n, int width) {
- return integerToString(n, width, false, 10);
- }
-
- public static String integerToString(int n, int width, boolean leadingZeros, int radix) {
- if (width > 32)
- width = 32;
- StringBuffer buf = new StringBuffer();
- long ln = n;
- boolean ifNeg = false;
- // only do sign if decimal
- if (radix != 10) {
- // System.out.println("MASK before : ln = " + ln );
- ln = ln & 0x00000000FFFFFFFFL;
- // System.out.println("MASK after : ln = " + ln );
- } else if (ln < 0) {
- ifNeg = true;
- ln = -ln;
- }
- if (ln == 0) {
- buf.append('0');
- } else {
- // System.out.println(" ln = " + ln );
- while (ln > 0) {
- int rem = (int) (ln % radix);
- buf.append(digitToChar(rem));
- ln = ln / radix;
- }
- }
- if (leadingZeros) {
- int pl = width;
- if (ifNeg)
- pl -= 1;
- for (int i = buf.length(); i < pl; i++)
- buf.append('0');
- }
- if (ifNeg)
- buf.append('-');
- // leading spaces
- for (int i = buf.length(); i < width; i++)
- buf.append(' ');
- // reverse buffer to put characters in correct order
- buf.reverse();
-
- return buf.toString();
- }
-
- /**
- * Convert double to string.
- *
- * @param width = minimum width of formatted string
- * @param places = number of digits displayed after decimal point
- */
- public static String doubleToString(double value, int width, int places) {
- return doubleToString(value, width, places, false);
- }
-
- /**
- * Convert double to string.
- *
- * @param width = minimum width of formatted string
- * @param places = number of digits displayed after decimal point
- */
- public static String doubleToString(double value, int width, int places, boolean leadingZeros) {
- if (width > 32)
- width = 32;
- if (places > 16)
- places = 16;
-
- boolean ifNeg = false;
- if (value < 0.0) {
- ifNeg = true;
- value = -value;
- }
- // round at relevant decimal place
- value += 0.5 * Math.pow(10.0, 0 - places);
- int ival = (int) Math.floor(value);
- // get portion after decimal point as an integer
- int fval = (int) ((value - Math.floor(value)) * Math.pow(10.0, places));
- String result = "";
-
- result += integerToString(ival, 0, false, 10);
- result += ".";
- result += integerToString(fval, places, true, 10);
-
- if (leadingZeros) {
- // prepend leading zeros and {-}
- int zw = width;
- if (ifNeg)
- zw -= 1;
- while (result.length() < zw)
- result = "0" + result;
- if (ifNeg)
- result = "-" + result;
- } else {
- // prepend {-} and leading spaces
- if (ifNeg)
- result = "-" + result;
- while (result.length() < width)
- result = " " + result;
- }
- return result;
- }
-
- static void testInteger(int n) {
- System.out.println("Test " + n + ", 0x" + Integer.toHexString(n) + ", %"
- + Integer.toBinaryString(n));
- System.out.println(" +,8,t,10 = " + integerToString(n, 8, true, 10));
- System.out.println(" +,8,f,10 = " + integerToString(n, 8, false, 10));
- System.out.println(" -,8,t,10 = " + integerToString(-n, 8, true, 10));
- System.out.println(" -,8,f,10 = " + integerToString(-n, 8, false, 10));
- System.out.println(" +,8,t,16 = " + integerToString(n, 8, true, 16));
- System.out.println(" +,8,f,16 = " + integerToString(n, 8, false, 16));
- System.out.println(" -,8,t,16 = " + integerToString(-n, 8, true, 16));
- System.out.println(" -,8,f,16 = " + integerToString(-n, 8, false, 16));
- System.out.println(" +,8,t, 2 = " + integerToString(n, 8, true, 2));
- System.out.println(" +,8,f, 2 = " + integerToString(n, 8, false, 2));
- }
-
- static void testDouble(double value) {
- System.out.println("Test " + value);
- System.out.println(" +,5,1 = " + doubleToString(value, 5, 1));
- System.out.println(" -,5,1 = " + doubleToString(-value, 5, 1));
-
- System.out.println(" +,14,3 = " + doubleToString(value, 14, 3));
- System.out.println(" -,14,3 = " + doubleToString(-value, 14, 3));
-
- System.out.println(" +,6,2,true = " + doubleToString(value, 6, 2, true));
- System.out.println(" -,6,2,true = " + doubleToString(-value, 6, 2, true));
- }
-
- public static void main(String argv[]) {
- System.out.println("Test NumericOutput");
- testInteger(0);
- testInteger(1);
- testInteger(16);
- testInteger(23456);
- testInteger(0x23456);
- testInteger(0x89ABC);
- testDouble(0.0);
- testDouble(0.0678);
- testDouble(0.1234567);
- testDouble(1.234567);
- testDouble(12.34567);
- testDouble(123.4567);
- testDouble(1234.5678);
-
- }
-}
diff --git a/src/com/jsyn/util/PolyphonicInstrument.java b/src/com/jsyn/util/PolyphonicInstrument.java
deleted file mode 100644
index 08460d0..0000000
--- a/src/com/jsyn/util/PolyphonicInstrument.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright 2011 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.util;
-
-import com.jsyn.ports.UnitInputPort;
-import com.jsyn.ports.UnitOutputPort;
-import com.jsyn.ports.UnitPort;
-import com.jsyn.unitgen.Circuit;
-import com.jsyn.unitgen.Multiply;
-import com.jsyn.unitgen.PassThrough;
-import com.jsyn.unitgen.UnitGenerator;
-import com.jsyn.unitgen.UnitSource;
-import com.jsyn.unitgen.UnitVoice;
-import com.softsynth.shared.time.TimeStamp;
-
-/**
- * The API for this class is likely to change. Please comment on its usefulness.
- *
- * @author Phil Burk (C) 2011 Mobileer Inc
- */
-
-public class PolyphonicInstrument extends Circuit implements UnitSource, Instrument {
- private Multiply mixer;
- private UnitVoice[] voices;
- private VoiceAllocator voiceAllocator;
- public UnitInputPort amplitude;
-
- public PolyphonicInstrument(UnitVoice[] voices) {
- this.voices = voices;
- voiceAllocator = new VoiceAllocator(voices);
- add(mixer = new Multiply());
- // Mix all the voices to one output.
- for (UnitVoice voice : voices) {
- UnitGenerator unit = voice.getUnitGenerator();
- boolean wasEnabled = unit.isEnabled();
- // This overrides the enabled property of the voice.
- add(unit);
- voice.getOutput().connect(mixer.inputA);
- // restore
- unit.setEnabled(wasEnabled);
- }
-
- addPort(amplitude = mixer.inputB, "Amplitude");
- amplitude.setup(0.0001, 0.4, 2.0);
- exportAllInputPorts();
- }
-
- /**
- * Connect a PassThrough unit to the input ports of the voices so that they can be controlled
- * together using a single port. Note that this will prevent their individual use. So the
- * "Frequency" and "Amplitude" ports are excluded. Note that this method is a bit funky and is
- * likely to change.
- */
- public void exportAllInputPorts() {
- // Iterate through the ports.
- for (UnitPort port : voices[0].getUnitGenerator().getPorts()) {
- if (port instanceof UnitInputPort) {
- UnitInputPort inputPort = (UnitInputPort) port;
- String voicePortName = inputPort.getName();
- // FIXME Need better way to identify ports that are per note.
- if (!voicePortName.equals("Frequency") && !voicePortName.equals("Amplitude")) {
- exportNamedInputPort(voicePortName);
- }
- }
- }
- }
-
- /**
- * Create a UnitInputPort for the circuit that is connected to the named port on each voice
- * through a PassThrough unit. This allows you to control all of the voices at once.
- *
- * @param portName
- * @see exportAllInputPorts
- */
- public void exportNamedInputPort(String portName) {
- UnitInputPort voicePort = null;
- PassThrough fanout = new PassThrough();
- for (UnitVoice voice : voices) {
- voicePort = (UnitInputPort) voice.getUnitGenerator().getPortByName(portName);
- fanout.output.connect(voicePort);
- }
- if (voicePort != null) {
- addPort(fanout.input, portName);
- fanout.input.setup(voicePort);
- }
- }
-
- @Override
- public UnitOutputPort getOutput() {
- return mixer.output;
- }
-
- @Override
- public void usePreset(int presetIndex) {
- usePreset(presetIndex, getSynthesisEngine().createTimeStamp());
- }
-
- // FIXME - no timestamp on UnitVoice
- @Override
- public void usePreset(int presetIndex, TimeStamp timeStamp) {
- // Apply preset to all voices.
- for (UnitVoice voice : voices) {
- voice.usePreset(presetIndex);
- }
- // Then copy values from first voice to instrument.
- for (UnitPort port : voices[0].getUnitGenerator().getPorts()) {
- if (port instanceof UnitInputPort) {
- UnitInputPort inputPort = (UnitInputPort) port;
- // FIXME Need better way to identify ports that are per note.
- UnitInputPort fanPort = (UnitInputPort) getPortByName(inputPort.getName());
- if ((fanPort != null) && (fanPort != amplitude)) {
- fanPort.set(inputPort.get());
- }
- }
- }
- }
-
- @Override
- public void noteOn(int tag, double frequency, double amplitude, TimeStamp timeStamp) {
- voiceAllocator.noteOn(tag, frequency, amplitude, timeStamp);
- }
-
- @Override
- public void noteOff(int tag, TimeStamp timeStamp) {
- voiceAllocator.noteOff(tag, timeStamp);
- }
-
- @Override
- public void setPort(int tag, String portName, double value, TimeStamp timeStamp) {
- voiceAllocator.setPort(tag, portName, value, timeStamp);
- }
-
- @Override
- public void allNotesOff(TimeStamp timeStamp) {
- voiceAllocator.allNotesOff(timeStamp);
- }
-
- public synchronized boolean isOn(int tag) {
- return voiceAllocator.isOn(tag);
- }
-}
diff --git a/src/com/jsyn/util/PseudoRandom.java b/src/com/jsyn/util/PseudoRandom.java
deleted file mode 100644
index e92b669..0000000
--- a/src/com/jsyn/util/PseudoRandom.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright 2009 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.
- */
-/**
- * Sep 9, 2009
- * com.jsyn.engine.units.SynthRandom.java
- */
-
-package com.jsyn.util;
-
-import java.util.Random;
-
-/**
- * Pseudo-random numbers using predictable and fast linear-congruential method.
- *
- * @author Phil Burk (C) 2009 Mobileer Inc Translated from 'C' to Java by Lisa
- * Tolentino.
- */
-public class PseudoRandom {
- // We must shift 1L or else we get a negative number!
- private static final double INT_TO_DOUBLE = (1.0 / (1L << 31));
- private long seed = 99887766;
-
- /**
- * Create an instance of SynthRandom.
- */
- public PseudoRandom() {
- this(new Random().nextInt());
- }
-
- /**
- * Create an instance of PseudoRandom.
- */
- public PseudoRandom(int seed) {
- setSeed(seed);
- }
-
- public void setSeed(int seed) {
- this.seed = (long) seed;
- }
-
- public int getSeed() {
- return (int) seed;
- }
-
- /**
- * Returns the next random double from 0.0 to 1.0
- *
- * @return value from 0.0 to 1.0
- */
- public double random() {
- int positiveInt = nextRandomInteger() & 0x7FFFFFFF;
- return positiveInt * INT_TO_DOUBLE;
- }
-
- /**
- * Returns the next random double from -1.0 to 1.0
- *
- * @return value from -1.0 to 1.0
- */
- public double nextRandomDouble() {
- return nextRandomInteger() * INT_TO_DOUBLE;
- }
-
- /** Calculate random 32 bit number using linear-congruential method. */
- public int nextRandomInteger() {
- // Use values for 64-bit sequence from MMIX by Donald Knuth.
- seed = (seed * 6364136223846793005L) + 1442695040888963407L;
- return (int) (seed >> 32); // The higher bits have a longer sequence.
- }
-
- public int choose(int range) {
- long positiveInt = nextRandomInteger() & 0x7FFFFFFF;
- long temp = positiveInt * range;
- return (int) (temp >> 31);
- }
-}
diff --git a/src/com/jsyn/util/RecursiveSequenceGenerator.java b/src/com/jsyn/util/RecursiveSequenceGenerator.java
deleted file mode 100644
index 53dbdf9..0000000
--- a/src/com/jsyn/util/RecursiveSequenceGenerator.java
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * 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.util;
-
-import java.util.Random;
-
-/**
- * Generate a sequence of integers based on a recursive mining of previous material. Notes are
- * generated by one of the following formula:
- *
- * <pre>
- * <code>
- * value[n] = value[n-delay] + offset;
- * </code>
- * </pre>
- *
- * The parameters delay and offset are randomly generated. This algorithm was first developed in
- * 1977 for a class project in FORTRAN. It was ported to Forth for HMSL in the late 80's. It was
- * then ported to Java for JSyn in 1997.
- *
- * @author Phil Burk (C) 1997,2011 Mobileer Inc
- */
-public class RecursiveSequenceGenerator {
- private int delay = 1;
- private int maxValue;
- private int maxInterval;
- private double desiredDensity = 0.5;
-
- private int offset;
- private int values[];
- private boolean enables[];
- private int cursor;
- private int countdown = -1;
- private double actualDensity;
- private int beatsPerMeasure = 8;
- private Random random;
-
- public RecursiveSequenceGenerator() {
- this(25, 7, 64);
- }
-
- public RecursiveSequenceGenerator(int maxValue, int maxInterval, int arraySize) {
- values = new int[arraySize];
- enables = new boolean[arraySize];
- this.maxValue = maxValue;
- this.maxInterval = maxInterval;
- for (int i = 0; i < values.length; i++) {
- values[i] = maxValue / 2;
- enables[i] = isNextEnabled(false);
- }
- }
-
- /** Set density of notes. 0.0 to 1.0 */
- public void setDensity(double density) {
- desiredDensity = density;
- }
-
- public double getDensity() {
- return desiredDensity;
- }
-
- /** Set maximum for generated value. */
- public void setMaxValue(int maxValue) {
- this.maxValue = maxValue;
- }
-
- public int getMaxValue() {
- return maxValue;
- }
-
- /** Set maximum for generated value. */
- public void setMaxInterval(int maxInterval) {
- this.maxInterval = maxInterval;
- }
-
- public int getMaxInterval() {
- return maxInterval;
- }
-
- /* Determine whether next in sequence should occur. */
- public boolean isNextEnabled(boolean preferance) {
- /* Calculate note density using low pass IIR filter. */
- double newDensity = (actualDensity * 0.9) + (preferance ? 0.1 : 0.0);
- /* Invert enable to push density towards desired level, with hysteresis. */
- if (preferance && (newDensity > ((desiredDensity * 0.7) + 0.3)))
- preferance = false;
- else if (!preferance && (newDensity < (desiredDensity * 0.7)))
- preferance = true;
- actualDensity = (actualDensity * 0.9) + (preferance ? 0.1 : 0.0);
- return preferance;
- }
-
- public int randomPowerOf2(int maxExp) {
- return (1 << (int) (random.nextDouble() * (maxExp + 1)));
- }
-
- /** Random number evenly distributed from -maxInterval to +maxInterval */
- public int randomEvenInterval() {
- return (int) (random.nextDouble() * ((maxInterval * 2) + 1)) - maxInterval;
- }
-
- void calcNewOffset() {
- offset = randomEvenInterval();
- }
-
- public void randomize() {
-
- delay = randomPowerOf2(4);
- calcNewOffset();
- // System.out.println("NewSeq: delay = " + delay + ", offset = " +
- // offset );
- }
-
- /** Change parameters based on random countdown. */
- public int next() {
- // If this sequence is finished, start a new one.
- if (countdown-- < 0) {
- randomize();
- countdown = randomPowerOf2(3);
- }
- return nextValue();
- }
-
- /** Change parameters using a probability based on beatIndex. */
- public int next(int beatIndex) {
- int beatMod = beatIndex % beatsPerMeasure;
- switch (beatMod) {
- case 0:
- if (Math.random() < 0.90)
- randomize();
- break;
- case 2:
- case 6:
- if (Math.random() < 0.15)
- randomize();
- break;
- case 4:
- if (Math.random() < 0.30)
- randomize();
- break;
- default:
- if (Math.random() < 0.07)
- randomize();
- break;
- }
- return nextValue();
- }
-
- /** Generate nextValue based on current delay and offset */
- public int nextValue() {
- // Generate index into circular value buffer.
- int idx = (cursor - delay);
- if (idx < 0)
- idx += values.length;
-
- // Generate new value. Calculate new offset if too high or low.
- int nextVal = 0;
- int timeout = 100;
- while (timeout > 0) {
- nextVal = values[idx] + offset;
- if ((nextVal >= 0) && (nextVal < maxValue))
- break;
- // Prevent endless loops when maxValue changes.
- if (nextVal > (maxValue + maxInterval - 1)) {
- nextVal = maxValue;
- break;
- }
- calcNewOffset();
- timeout--;
- // System.out.println("NextVal = " + nextVal + ", offset = " +
- // offset );
- }
- if (timeout <= 0) {
- System.err.println("RecursiveSequence: nextValue timed out. offset = " + offset);
- nextVal = maxValue / 2;
- offset = 0;
- }
-
- // Save new value in circular buffer.
- values[cursor] = nextVal;
-
- boolean playIt = enables[cursor] = isNextEnabled(enables[idx]);
- cursor++;
- if (cursor >= values.length)
- cursor = 0;
-
- // System.out.println("nextVal = " + nextVal );
-
- return playIt ? nextVal : -1;
- }
-
- public Random getRandom() {
- return random;
- }
-
- public void setRandom(Random random) {
- this.random = random;
- }
-
-}
diff --git a/src/com/jsyn/util/SampleLoader.java b/src/com/jsyn/util/SampleLoader.java
deleted file mode 100644
index 170b4cb..0000000
--- a/src/com/jsyn/util/SampleLoader.java
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright 2011 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.util;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-
-import com.jsyn.data.FloatSample;
-import com.jsyn.util.soundfile.CustomSampleLoader;
-
-/**
- * Load a FloatSample from various sources. The default loader uses custom code to load WAV or AIF
- * files. Supported data formats are 16, 24 and 32 bit PCM, and 32-bit float. Compressed formats
- * such as unsigned 8-bit, uLaw, A-Law and MP3 are not support. If you need to load one of those
- * files try setJavaSoundPreferred(true). Or convert it to a supported format using Audacity or Sox
- * or some other sample file tool. Here is an example of loading a sample from a file.
- *
- * <pre>
- * <code>
- * File sampleFile = new File("guitar.wav");
- * FloatSample sample = SampleLoader.loadFloatSample( sampleFile );
- * </code>
- * </pre>
- *
- * @author Phil Burk (C) 2011 Mobileer Inc
- */
-public class SampleLoader {
- private static boolean javaSoundPreferred = false;
- private static final String JS_LOADER_NAME = "com.jsyn.util.JavaSoundSampleLoader";
-
- /**
- * Try to create an implementation of AudioSampleLoader.
- *
- * @return A device supported on this platform.
- */
- private static AudioSampleLoader createLoader() {
- AudioSampleLoader loader = null;
- try {
- if (javaSoundPreferred) {
- loader = (AudioSampleLoader) JavaTools.loadClass(JS_LOADER_NAME).newInstance();
- } else {
- loader = new CustomSampleLoader();
- }
- } catch (InstantiationException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- }
- return loader;
- }
-
- /**
- * Load a FloatSample from a File object.
- */
- public static FloatSample loadFloatSample(File fileIn) throws IOException {
- AudioSampleLoader loader = SampleLoader.createLoader();
- return loader.loadFloatSample(fileIn);
- }
-
- /**
- * Load a FloatSample from an InputStream. This is handy when loading Resources from a JAR file.
- */
- public static FloatSample loadFloatSample(InputStream inputStream) throws IOException {
- AudioSampleLoader loader = SampleLoader.createLoader();
- return loader.loadFloatSample(inputStream);
- }
-
- /**
- * Load a FloatSample from a URL.. This is handy when loading Resources from a website.
- */
- public static FloatSample loadFloatSample(URL url) throws IOException {
- AudioSampleLoader loader = SampleLoader.createLoader();
- return loader.loadFloatSample(url);
- }
-
- public static boolean isJavaSoundPreferred() {
- return javaSoundPreferred;
- }
-
- /**
- * If set true then the audio file parser from JavaSound will be used. Note that JavaSound
- * cannot load audio files containing floating point data. But it may be able to load some
- * compressed data formats such as uLaw.
- *
- * Note: JavaSound is not supported on Android.
- *
- * @param javaSoundPreferred
- */
- public static void setJavaSoundPreferred(boolean javaSoundPreferred) {
- SampleLoader.javaSoundPreferred = javaSoundPreferred;
- }
-
- /**
- * Decode 24 bit samples from a BigEndian byte array into a float array. The samples will be
- * normalized into the range -1.0 to +1.0.
- *
- * @param audioBytes raw data from an audio file
- * @param offset first element of byte array
- * @param numBytes number of bytes to process
- * @param data array to be filled with floats
- * @param outputOffset first element of float array to be filled
- */
- public static void decodeBigI24ToF32(byte[] audioBytes, int offset, int numBytes, float[] data,
- int outputOffset) {
- int lastByte = offset + numBytes;
- int byteCursor = offset;
- int floatCursor = outputOffset;
- while (byteCursor < lastByte) {
- int hi = ((audioBytes[byteCursor++]) & 0x00FF);
- int mid = ((audioBytes[byteCursor++]) & 0x00FF);
- int lo = ((audioBytes[byteCursor++]) & 0x00FF);
- int value = (hi << 24) | (mid << 16) | (lo << 8);
- data[floatCursor++] = value * (1.0f / Integer.MAX_VALUE);
- }
- }
-
- public static void decodeBigI16ToF32(byte[] audioBytes, int offset, int numBytes, float[] data,
- int outputOffset) {
- int lastByte = offset + numBytes;
- int byteCursor = offset;
- int floatCursor = outputOffset;
- while (byteCursor < lastByte) {
- int hi = ((audioBytes[byteCursor++]) & 0x00FF);
- int lo = ((audioBytes[byteCursor++]) & 0x00FF);
- short value = (short) ((hi << 8) | lo);
- data[floatCursor++] = value * (1.0f / 32768);
- }
- }
-
- public static void decodeBigF32ToF32(byte[] audioBytes, int offset, int numBytes, float[] data,
- int outputOffset) {
- int lastByte = offset + numBytes;
- int byteCursor = offset;
- int floatCursor = outputOffset;
- while (byteCursor < lastByte) {
- int bits = audioBytes[byteCursor++];
- bits = (bits << 8) | ((audioBytes[byteCursor++]) & 0x00FF);
- bits = (bits << 8) | ((audioBytes[byteCursor++]) & 0x00FF);
- bits = (bits << 8) | ((audioBytes[byteCursor++]) & 0x00FF);
- data[floatCursor++] = Float.intBitsToFloat(bits);
- }
- }
-
- public static void decodeBigI32ToF32(byte[] audioBytes, int offset, int numBytes, float[] data,
- int outputOffset) {
- int lastByte = offset + numBytes;
- int byteCursor = offset;
- int floatCursor = outputOffset;
- while (byteCursor < lastByte) {
- int value = audioBytes[byteCursor++]; // MSB
- value = (value << 8) | ((audioBytes[byteCursor++]) & 0x00FF);
- value = (value << 8) | ((audioBytes[byteCursor++]) & 0x00FF);
- value = (value << 8) | ((audioBytes[byteCursor++]) & 0x00FF);
- data[floatCursor++] = value * (1.0f / Integer.MAX_VALUE);
- }
- }
-
- public static void decodeLittleF32ToF32(byte[] audioBytes, int offset, int numBytes,
- float[] data, int outputOffset) {
- int lastByte = offset + numBytes;
- int byteCursor = offset;
- int floatCursor = outputOffset;
- while (byteCursor < lastByte) {
- int bits = ((audioBytes[byteCursor++]) & 0x00FF); // LSB
- bits += ((audioBytes[byteCursor++]) & 0x00FF) << 8;
- bits += ((audioBytes[byteCursor++]) & 0x00FF) << 16;
- bits += (audioBytes[byteCursor++]) << 24;
- data[floatCursor++] = Float.intBitsToFloat(bits);
- }
- }
-
- public static void decodeLittleI32ToF32(byte[] audioBytes, int offset, int numBytes,
- float[] data, int outputOffset) {
- int lastByte = offset + numBytes;
- int byteCursor = offset;
- int floatCursor = outputOffset;
- while (byteCursor < lastByte) {
- int value = ((audioBytes[byteCursor++]) & 0x00FF);
- value += ((audioBytes[byteCursor++]) & 0x00FF) << 8;
- value += ((audioBytes[byteCursor++]) & 0x00FF) << 16;
- value += (audioBytes[byteCursor++]) << 24;
- data[floatCursor++] = value * (1.0f / Integer.MAX_VALUE);
- }
- }
-
- public static void decodeLittleI24ToF32(byte[] audioBytes, int offset, int numBytes,
- float[] data, int outputOffset) {
- int lastByte = offset + numBytes;
- int byteCursor = offset;
- int floatCursor = outputOffset;
- while (byteCursor < lastByte) {
- int lo = ((audioBytes[byteCursor++]) & 0x00FF);
- int mid = ((audioBytes[byteCursor++]) & 0x00FF);
- int hi = ((audioBytes[byteCursor++]) & 0x00FF);
- int value = (hi << 24) | (mid << 16) | (lo << 8);
- data[floatCursor++] = value * (1.0f / Integer.MAX_VALUE);
- }
- }
-
- public static void decodeLittleI16ToF32(byte[] audioBytes, int offset, int numBytes,
- float[] data, int outputOffset) {
- int lastByte = offset + numBytes;
- int byteCursor = offset;
- int floatCursor = outputOffset;
- while (byteCursor < lastByte) {
- int lo = ((audioBytes[byteCursor++]) & 0x00FF);
- int hi = ((audioBytes[byteCursor++]) & 0x00FF);
- short value = (short) ((hi << 8) | lo);
- float sample = value * (1.0f / 32768);
- data[floatCursor++] = sample;
- }
- }
-
-}
diff --git a/src/com/jsyn/util/SignalCorrelator.java b/src/com/jsyn/util/SignalCorrelator.java
deleted file mode 100644
index ebdd46b..0000000
--- a/src/com/jsyn/util/SignalCorrelator.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2011 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.util;
-
-/**
- * Interface used to evaluate various algorithms for pitch detection.
- *
- * @author Phil Burk (C) 2011 Mobileer Inc
- */
-public interface SignalCorrelator {
- /**
- * Add a sample to be analyzed. The samples will generally be held in a circular buffer.
- *
- * @param value
- * @return true if a new period value has been generated
- */
- public boolean addSample(double value);
-
- /**
- * @return the estimated period of the waveform in samples
- */
- public double getPeriod();
-
- /**
- * Measure of how confident the analyzer is of the last result.
- *
- * @return quality of the estimate between 0.0 and 1.0
- */
- public double getConfidence();
-
- /** For internal debugging. */
- public float[] getDiffs();
-
-}
diff --git a/src/com/jsyn/util/StreamingThread.java b/src/com/jsyn/util/StreamingThread.java
deleted file mode 100644
index 682f476..0000000
--- a/src/com/jsyn/util/StreamingThread.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright 2011 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.util;
-
-import java.io.IOException;
-
-import com.jsyn.io.AudioInputStream;
-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 {
- private AudioInputStream inputStream;
- private AudioOutputStream outputStream;
- private int framesPerBuffer = 1024;
- private volatile boolean go = true;
- private TransportModel transportModel;
- private long framePosition;
- private long maxFrames;
- private int samplesPerFrame = 1;
-
- public StreamingThread(AudioInputStream inputStream, AudioOutputStream outputStream) {
- this.inputStream = inputStream;
- this.outputStream = outputStream;
- }
-
- @Override
- public void run() {
- double[] buffer = new double[framesPerBuffer * samplesPerFrame];
- try {
- transportModel.firePositionChanged(framePosition);
- transportModel.fireStateChanged(TransportModel.STATE_RUNNING);
- int framesToRead = geteFramesToRead(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;
- }
- framePosition += framesToRead;
- transportModel.firePositionChanged(framePosition);
- framesToRead = geteFramesToRead(buffer);
- }
- transportModel.fireStateChanged(TransportModel.STATE_STOPPED);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- private int geteFramesToRead(double[] buffer) {
- if (maxFrames > 0) {
- long numToRead = maxFrames - framePosition;
- if (numToRead < 0) {
- return 0;
- } else if (numToRead > framesPerBuffer) {
- numToRead = framesPerBuffer;
- }
- return (int) numToRead;
- } else {
- return framesPerBuffer;
- }
- }
-
- public int getFramesPerBuffer() {
- return framesPerBuffer;
- }
-
- /**
- * Only call this before the thread has started.
- *
- * @param framesPerBuffer
- */
- public void setFramesPerBuffer(int framesPerBuffer) {
- this.framesPerBuffer = framesPerBuffer;
- }
-
- public void requestStop() {
- go = false;
- }
-
- public TransportModel getTransportModel() {
- return transportModel;
- }
-
- public void setTransportModel(TransportModel transportModel) {
- this.transportModel = transportModel;
- }
-
- /**
- * @param maxFrames
- */
- public void setMaxFrames(long maxFrames) {
- this.maxFrames = maxFrames;
- }
-
- public int getSamplesPerFrame() {
- return samplesPerFrame;
- }
-
- public void setSamplesPerFrame(int samplesPerFrame) {
- this.samplesPerFrame = samplesPerFrame;
- }
-}
diff --git a/src/com/jsyn/util/TransportListener.java b/src/com/jsyn/util/TransportListener.java
deleted file mode 100644
index 3c8b048..0000000
--- a/src/com/jsyn/util/TransportListener.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2009 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.util;
-
-public interface TransportListener {
- /**
- * @param transportModel
- * @param framePosition position in frames
- */
- void positionChanged(TransportModel transportModel, long framePosition);
-
- /**
- * @param transportModel
- * @param state for example TransportModel.STATE_STOPPED
- */
- void stateChanged(TransportModel transportModel, int state);
-}
diff --git a/src/com/jsyn/util/TransportModel.java b/src/com/jsyn/util/TransportModel.java
deleted file mode 100644
index bcc75be..0000000
--- a/src/com/jsyn/util/TransportModel.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright 2009 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.util;
-
-import java.util.concurrent.CopyOnWriteArrayList;
-
-public class TransportModel {
- public static final int STATE_STOPPED = 0;
- public static final int STATE_PAUSED = 1;
- public static final int STATE_RUNNING = 2;
-
- private CopyOnWriteArrayList<TransportListener> listeners = new CopyOnWriteArrayList<TransportListener>();
- private int state = STATE_STOPPED;
- private long position;
-
- public void addTransportListener(TransportListener listener) {
- listeners.add(listener);
- }
-
- public void removeTransportListener(TransportListener listener) {
- listeners.remove(listener);
- }
-
- public void setState(int newState) {
- state = newState;
- fireStateChanged(newState);
- }
-
- public int getState() {
- return state;
- }
-
- public void setPosition(long newPosition) {
- position = newPosition;
- firePositionChanged(newPosition);
- }
-
- public long getPosition() {
- return position;
- }
-
- public void fireStateChanged(int newState) {
- for (TransportListener listener : listeners) {
- listener.stateChanged(this, newState);
- }
- }
-
- public void firePositionChanged(long newPosition) {
- for (TransportListener listener : listeners) {
- listener.positionChanged(this, newPosition);
- }
- }
-}
diff --git a/src/com/jsyn/util/VoiceAllocator.java b/src/com/jsyn/util/VoiceAllocator.java
deleted file mode 100644
index f20f7a5..0000000
--- a/src/com/jsyn/util/VoiceAllocator.java
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Copyright 2011 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.util;
-
-import com.jsyn.Synthesizer;
-import com.jsyn.unitgen.UnitVoice;
-import com.softsynth.shared.time.ScheduledCommand;
-import com.softsynth.shared.time.TimeStamp;
-
-/**
- * Allocate voices based on an integer tag. The tag could, for example, be a MIDI note number. Or a
- * tag could be an int that always increments. Use the same tag to refer to a voice for noteOn() and
- * noteOff(). If no new voices are available then a voice in use will be stolen.
- *
- * @author Phil Burk (C) 2011 Mobileer Inc
- */
-public class VoiceAllocator implements Instrument {
- private int maxVoices;
- private VoiceTracker[] trackers;
- private long tick;
- private Synthesizer synthesizer;
- private static final int UNASSIGNED_PRESET = -1;
- private int mPresetIndex = UNASSIGNED_PRESET;
-
- /**
- * Create an allocator for the array of UnitVoices. The array must be full of instantiated
- * UnitVoices that are connected to some kind of mixer.
- *
- * @param voices
- */
- public VoiceAllocator(UnitVoice[] voices) {
- maxVoices = voices.length;
- trackers = new VoiceTracker[maxVoices];
- for (int i = 0; i < maxVoices; i++) {
- trackers[i] = new VoiceTracker();
- trackers[i].voice = voices[i];
- }
- }
-
- public Synthesizer getSynthesizer() {
- if (synthesizer == null) {
- synthesizer = trackers[0].voice.getUnitGenerator().getSynthesizer();
- }
- return synthesizer;
- }
-
- private class VoiceTracker {
- UnitVoice voice;
- int tag = -1;
- int presetIndex = UNASSIGNED_PRESET;
- long when;
- boolean on;
-
- public void off() {
- on = false;
- when = tick++;
- }
- }
-
- /**
- * @return number of UnitVoices passed to the allocator.
- */
- public int getVoiceCount() {
- return maxVoices;
- }
-
- private VoiceTracker findVoice(int tag) {
- for (VoiceTracker tracker : trackers) {
- if (tracker.tag == tag) {
- return tracker;
- }
- }
- return null;
- }
-
- private VoiceTracker stealVoice() {
- VoiceTracker bestOff = null;
- VoiceTracker bestOn = null;
- for (VoiceTracker tracker : trackers) {
- if (tracker.voice == null) {
- return tracker;
- }
- // If we have a bestOff voice then don't even bother with on voices.
- else if (bestOff != null) {
- // Older off voice?
- if (!tracker.on && (tracker.when < bestOff.when)) {
- bestOff = tracker;
- }
- } else if (tracker.on) {
- if (bestOn == null) {
- bestOn = tracker;
- } else if (tracker.when < bestOn.when) {
- bestOn = tracker;
- }
- } else {
- bestOff = tracker;
- }
- }
- if (bestOff != null) {
- return bestOff;
- } else {
- return bestOn;
- }
- }
-
- /**
- * Allocate a Voice associated with this tag. It will first pick a voice already assigned to
- * that tag. Next it will pick the oldest voice that is off. Next it will pick the oldest voice
- * that is on. If you are using timestamps to play the voice in the future then you should use
- * the noteOn() noteOff() and setPort() methods.
- *
- * @param tag
- * @return Voice that is most available.
- */
- protected synchronized UnitVoice allocate(int tag) {
- VoiceTracker tracker = allocateTracker(tag);
- return tracker.voice;
- }
-
- private VoiceTracker allocateTracker(int tag) {
- VoiceTracker tracker = findVoice(tag);
- if (tracker == null) {
- tracker = stealVoice();
- }
- tracker.tag = tag;
- tracker.when = tick++;
- tracker.on = true;
- return tracker;
- }
-
- protected synchronized boolean isOn(int tag) {
- VoiceTracker tracker = findVoice(tag);
- if (tracker != null) {
- return tracker.on;
- }
- return false;
- }
-
- protected synchronized UnitVoice off(int tag) {
- VoiceTracker tracker = findVoice(tag);
- if (tracker != null) {
- tracker.off();
- return tracker.voice;
- }
- return null;
- }
-
- /** Turn off all the note currently on. */
- @Override
- public void allNotesOff(TimeStamp timeStamp) {
- getSynthesizer().scheduleCommand(timeStamp, new ScheduledCommand() {
- @Override
- public void run() {
- for (VoiceTracker tracker : trackers) {
- if (tracker.on) {
- tracker.voice.noteOff(getSynthesizer().createTimeStamp());
- tracker.off();
- }
- }
- }
- });
- }
-
- /**
- * Play a note on the voice and associate it with the given tag. if needed a new voice will be
- * allocated and an old voice may be turned off.
- */
- @Override
- public void noteOn(final int tag, final double frequency, final double amplitude,
- TimeStamp timeStamp) {
- getSynthesizer().scheduleCommand(timeStamp, new ScheduledCommand() {
- @Override
- public void run() {
- VoiceTracker voiceTracker = allocateTracker(tag);
- if (voiceTracker.presetIndex != mPresetIndex) {
- voiceTracker.voice.usePreset(mPresetIndex);
- voiceTracker.presetIndex = mPresetIndex;
- }
- voiceTracker.voice.noteOn(frequency, amplitude, getSynthesizer().createTimeStamp());
- }
- });
- }
-
- /**
- * Play a note on the voice and associate it with the given tag. if needed a new voice will be
- * allocated and an old voice may be turned off.
- * Apply an operation to the voice.
- */
- public void noteOn(final int tag,
- final double frequency,
- final double amplitude,
- final VoiceOperation operation,
- TimeStamp timeStamp) {
- getSynthesizer().scheduleCommand(timeStamp, new ScheduledCommand() {
- @Override
- public void run() {
- VoiceTracker voiceTracker = allocateTracker(tag);
- operation.operate(voiceTracker.voice);
- voiceTracker.voice.noteOn(frequency, amplitude, getSynthesizer().createTimeStamp());
- }
- });
- }
-
- /** Turn off the voice associated with the given tag if allocated. */
- @Override
- public void noteOff(final int tag, TimeStamp timeStamp) {
- getSynthesizer().scheduleCommand(timeStamp, new ScheduledCommand() {
- @Override
- public void run() {
- VoiceTracker voiceTracker = findVoice(tag);
- if (voiceTracker != null) {
- voiceTracker.voice.noteOff(getSynthesizer().createTimeStamp());
- off(tag);
- }
- }
- });
- }
-
- /** Set a port on the voice associated with the given tag if allocated. */
- @Override
- public void setPort(final int tag, final String portName, final double value,
- TimeStamp timeStamp) {
- getSynthesizer().scheduleCommand(timeStamp, new ScheduledCommand() {
- @Override
- public void run() {
- VoiceTracker voiceTracker = findVoice(tag);
- if (voiceTracker != null) {
- voiceTracker.voice.setPort(portName, value, getSynthesizer().createTimeStamp());
- }
- }
- });
- }
-
- @Override
- public void usePreset(final int presetIndex, TimeStamp timeStamp) {
- getSynthesizer().scheduleCommand(timeStamp, new ScheduledCommand() {
- @Override
- public void run() {
- mPresetIndex = presetIndex;
- }
- });
- }
-
-}
diff --git a/src/com/jsyn/util/VoiceDescription.java b/src/com/jsyn/util/VoiceDescription.java
deleted file mode 100644
index b7be044..0000000
--- a/src/com/jsyn/util/VoiceDescription.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright 2011 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.util;
-
-import com.jsyn.unitgen.UnitVoice;
-
-/**
- * Describe a voice so that a user can pick it out of an InstrumentLibrary.
- *
- * @author Phil Burk (C) 2011 Mobileer Inc
- * @see PolyphonicInstrument
- */
-public abstract class VoiceDescription {
- private String name;
- private String[] presetNames;
-
- public VoiceDescription(String name, String[] presetNames) {
- this.name = name;
- this.presetNames = presetNames;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public int getPresetCount() {
- return presetNames.length;
- }
-
- public String[] getPresetNames() {
- return presetNames;
- }
-
- public abstract String[] getTags(int presetIndex);
-
- /**
- * Instantiate one of these voices. You may want to call usePreset(n) on the voice after
- * instantiating it.
- *
- * @return a voice
- */
- public abstract UnitVoice createUnitVoice();
-
- public abstract String getVoiceClassName();
-
- @Override
- public String toString() {
- return name + "[" + getPresetCount() + "]";
- }
-}
diff --git a/src/com/jsyn/util/VoiceOperation.java b/src/com/jsyn/util/VoiceOperation.java
deleted file mode 100644
index cd3b48e..0000000
--- a/src/com/jsyn/util/VoiceOperation.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.jsyn.util;
-
-import com.jsyn.unitgen.UnitVoice;
-
-public interface VoiceOperation {
- public void operate(UnitVoice voice);
-}
diff --git a/src/com/jsyn/util/WaveFileWriter.java b/src/com/jsyn/util/WaveFileWriter.java
deleted file mode 100644
index 32e9995..0000000
--- a/src/com/jsyn/util/WaveFileWriter.java
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Copyright 2011 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.util;
-
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.RandomAccessFile;
-
-import com.jsyn.io.AudioOutputStream;
-
-/**
- * Write audio data to a WAV file.
- *
- * <pre>
- * <code>
- * WaveFileWriter writer = new WaveFileWriter(file);
- * writer.setFrameRate(22050);
- * writer.setBitsPerSample(24);
- * writer.write(floatArray);
- * writer.close();
- * </code>
- * </pre>
- *
- * @author Phil Burk (C) 2011 Mobileer Inc
- */
-public class WaveFileWriter implements AudioOutputStream {
- private static final short WAVE_FORMAT_PCM = 1;
- private OutputStream outputStream;
- private long riffSizePosition = 0;
- private long dataSizePosition = 0;
- private int frameRate = 44100;
- private int samplesPerFrame = 1;
- private int bitsPerSample = 16;
- private int bytesWritten;
- private File outputFile;
- private boolean headerWritten = false;
- private final static int PCM24_MIN = -(1 << 23);
- private final static int PCM24_MAX = (1 << 23) - 1;
-
- /**
- * Create a writer that will write to the specified file.
- *
- * @param outputFile
- * @throws FileNotFoundException
- */
- public WaveFileWriter(File outputFile) throws FileNotFoundException {
- this.outputFile = outputFile;
- FileOutputStream fileOut = new FileOutputStream(outputFile);
- outputStream = new BufferedOutputStream(fileOut);
- }
-
- /**
- * @param frameRate default is 44100
- */
- public void setFrameRate(int frameRate) {
- this.frameRate = frameRate;
- }
-
- public int getFrameRate() {
- return frameRate;
- }
-
- /** For stereo, set this to 2. Default is 1. */
- public void setSamplesPerFrame(int samplesPerFrame) {
- this.samplesPerFrame = samplesPerFrame;
- }
-
- public int getSamplesPerFrame() {
- return samplesPerFrame;
- }
-
- /** Only 16 or 24 bit samples supported at the moment. Default is 16. */
- public void setBitsPerSample(int bits) {
- if ((bits != 16) && (bits != 24)) {
- throw new IllegalArgumentException("Only 16 or 24 bits per sample allowed. Not " + bits);
- }
- bitsPerSample = bits;
- }
-
- public int getBitsPerSample() {
- return bitsPerSample;
- }
-
- @Override
- public void close() throws IOException {
- outputStream.close();
- fixSizes();
- }
-
- /** Write entire buffer of audio samples to the WAV file. */
- @Override
- public void write(double[] buffer) throws IOException {
- write(buffer, 0, buffer.length);
- }
-
- /** Write audio to the WAV file. */
- public void write(float[] buffer) throws IOException {
- write(buffer, 0, buffer.length);
- }
-
- /** Write single audio data value to the WAV file. */
- @Override
- public void write(double value) throws IOException {
- if (!headerWritten) {
- writeHeader();
- }
-
- if (bitsPerSample == 24) {
- writePCM24(value);
- } else {
- writePCM16(value);
- }
- }
-
- private void writePCM24(double value) throws IOException {
- // Offset before casting so that we can avoid using floor().
- // Also round by adding 0.5 so that very small signals go to zero.
- double temp = (PCM24_MAX * value) + 0.5 - PCM24_MIN;
- int sample = ((int) temp) + PCM24_MIN;
- // clip to 24-bit range
- if (sample > PCM24_MAX) {
- sample = PCM24_MAX;
- } else if (sample < PCM24_MIN) {
- sample = PCM24_MIN;
- }
- // encode as little-endian
- writeByte(sample); // little end
- writeByte(sample >> 8); // middle
- writeByte(sample >> 16); // big end
- }
-
- private void writePCM16(double value) throws IOException {
- // Offset before casting so that we can avoid using floor().
- // Also round by adding 0.5 so that very small signals go to zero.
- double temp = (Short.MAX_VALUE * value) + 0.5 - Short.MIN_VALUE;
- int sample = ((int) temp) + Short.MIN_VALUE;
- if (sample > Short.MAX_VALUE) {
- sample = Short.MAX_VALUE;
- } else if (sample < Short.MIN_VALUE) {
- sample = Short.MIN_VALUE;
- }
- writeByte(sample); // little end
- writeByte(sample >> 8); // big end
- }
-
- /** Write audio to the WAV file. */
- @Override
- public void write(double[] buffer, int start, int count) throws IOException {
- for (int i = 0; i < count; i++) {
- write(buffer[start + i]);
- }
- }
-
- /** Write audio to the WAV file. */
- public void write(float[] buffer, int start, int count) throws IOException {
- for (int i = 0; i < count; i++) {
- write(buffer[start + i]);
- }
- }
-
- // Write lower 8 bits. Upper bits ignored.
- private void writeByte(int b) throws IOException {
- outputStream.write(b);
- bytesWritten += 1;
- }
-
- /**
- * Write a 32 bit integer to the stream in Little Endian format.
- */
- public void writeIntLittle(int n) throws IOException {
- writeByte(n);
- writeByte(n >> 8);
- writeByte(n >> 16);
- writeByte(n >> 24);
- }
-
- /**
- * Write a 16 bit integer to the stream in Little Endian format.
- */
- public void writeShortLittle(short n) throws IOException {
- writeByte(n);
- writeByte(n >> 8);
- }
-
- /**
- * Write a simple WAV header for PCM data.
- */
- private void writeHeader() throws IOException {
- writeRiffHeader();
- writeFormatChunk();
- writeDataChunkHeader();
- outputStream.flush();
- headerWritten = true;
- }
-
- /**
- * Write a 'RIFF' file header and a 'WAVE' ID to the WAV file.
- */
- private void writeRiffHeader() throws IOException {
- writeByte('R');
- writeByte('I');
- writeByte('F');
- writeByte('F');
- riffSizePosition = bytesWritten;
- writeIntLittle(Integer.MAX_VALUE);
- writeByte('W');
- writeByte('A');
- writeByte('V');
- writeByte('E');
- }
-
- /**
- * Write an 'fmt ' chunk to the WAV file containing the given information.
- */
- public void writeFormatChunk() throws IOException {
- int bytesPerSample = (bitsPerSample + 7) / 8;
-
- writeByte('f');
- writeByte('m');
- writeByte('t');
- writeByte(' ');
- writeIntLittle(16); // chunk size
- writeShortLittle(WAVE_FORMAT_PCM);
- writeShortLittle((short) samplesPerFrame);
- writeIntLittle(frameRate);
- // bytes/second
- writeIntLittle(frameRate * samplesPerFrame * bytesPerSample);
- // block align
- writeShortLittle((short) (samplesPerFrame * bytesPerSample));
- writeShortLittle((short) bitsPerSample);
- }
-
- /**
- * Write a 'data' chunk header to the WAV file. This should be followed by call to
- * writeShortLittle() to write the data to the chunk.
- */
- public void writeDataChunkHeader() throws IOException {
- writeByte('d');
- writeByte('a');
- writeByte('t');
- writeByte('a');
- dataSizePosition = bytesWritten;
- writeIntLittle(Integer.MAX_VALUE); // size
- }
-
- /**
- * Fix RIFF and data chunk sizes based on final size. Assume data chunk is the last chunk.
- */
- private void fixSizes() throws IOException {
- RandomAccessFile randomFile = new RandomAccessFile(outputFile, "rw");
- try {
- // adjust RIFF size
- long end = bytesWritten;
- int riffSize = (int) (end - riffSizePosition) - 4;
- randomFile.seek(riffSizePosition);
- writeRandomIntLittle(randomFile, riffSize);
- // adjust data size
- int dataSize = (int) (end - dataSizePosition) - 4;
- randomFile.seek(dataSizePosition);
- writeRandomIntLittle(randomFile, dataSize);
- } finally {
- randomFile.close();
- }
- }
-
- private void writeRandomIntLittle(RandomAccessFile randomFile, int n) throws IOException {
- byte[] buffer = new byte[4];
- buffer[0] = (byte) n;
- buffer[1] = (byte) (n >> 8);
- buffer[2] = (byte) (n >> 16);
- buffer[3] = (byte) (n >> 24);
- randomFile.write(buffer);
- }
-
-}
diff --git a/src/com/jsyn/util/WaveRecorder.java b/src/com/jsyn/util/WaveRecorder.java
deleted file mode 100644
index 059863b..0000000
--- a/src/com/jsyn/util/WaveRecorder.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright 2011 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.util;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-
-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
- * WAV format file that can be read by other programs.
- *
- * @author Phil Burk (C) 2011 Mobileer Inc
- */
-public class WaveRecorder {
- private AudioStreamReader reader;
- private WaveFileWriter writer;
- private StreamingThread thread;
- private Synthesizer synth;
- private TransportModel transportModel = new TransportModel();
- private double maxRecordingTime;
-
- /**
- * Create a stereo 16-bit recorder.
- *
- * @param synth
- * @param outputFile
- * @throws FileNotFoundException
- */
- public WaveRecorder(Synthesizer synth, File outputFile) throws FileNotFoundException {
- this(synth, outputFile, 2, 16);
- }
-
- public WaveRecorder(Synthesizer synth, File outputFile, int samplesPerFrame)
- throws FileNotFoundException {
- this(synth, outputFile, samplesPerFrame, 16);
- }
-
- /**
- * @param synth
- * @param outputFile
- * @param samplesPerFrame 1 for mono, 2 for stereo
- * @param bitsPerSample 16 or 24
- * @throws FileNotFoundException
- */
- public WaveRecorder(Synthesizer synth, File outputFile, int samplesPerFrame, int bitsPerSample)
- throws FileNotFoundException {
- this.synth = synth;
- reader = new AudioStreamReader(synth, samplesPerFrame);
-
- writer = new WaveFileWriter(outputFile);
- writer.setFrameRate(synth.getFrameRate());
- writer.setSamplesPerFrame(samplesPerFrame);
- writer.setBitsPerSample(bitsPerSample);
- }
-
- public UnitInputPort getInput() {
- return reader.getInput();
- }
-
- public void start() {
- stop();
- thread = new StreamingThread(reader, writer);
- thread.setTransportModel(transportModel);
- thread.setSamplesPerFrame(writer.getSamplesPerFrame());
- updateMaxRecordingTime();
- thread.start();
- }
-
- public void stop() {
- if (thread != null) {
- thread.requestStop();
- try {
- thread.join(500);
- } catch (InterruptedException e) {
- }
- thread = null;
- }
- }
-
- /** Close and disconnect any connected inputs. */
- public void close() throws IOException {
- stop();
- if (writer != null) {
- writer.close();
- writer = null;
- }
- if (reader != null) {
- reader.close();
- for (int i = 0; i < reader.getInput().getNumParts(); i++) {
- reader.getInput().disconnectAll(i);
- }
- reader = null;
- }
- }
-
- public void addTransportListener(TransportListener listener) {
- transportModel.addTransportListener(listener);
- }
-
- public void removeTransportListener(TransportListener listener) {
- transportModel.removeTransportListener(listener);
- }
-
- public void setMaxRecordingTime(double maxRecordingTime) {
- this.maxRecordingTime = maxRecordingTime;
- updateMaxRecordingTime();
- }
-
- private void updateMaxRecordingTime() {
- StreamingThread streamingThread = thread;
- if (streamingThread != null) {
- long maxFrames = (long) (maxRecordingTime * synth.getFrameRate());
- streamingThread.setMaxFrames(maxFrames);
- }
- }
-}
diff --git a/src/com/jsyn/util/soundfile/AIFFFileParser.java b/src/com/jsyn/util/soundfile/AIFFFileParser.java
deleted file mode 100644
index 2b09d78..0000000
--- a/src/com/jsyn/util/soundfile/AIFFFileParser.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Copyright 2009 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.util.soundfile;
-
-import java.io.EOFException;
-import java.io.IOException;
-
-import com.jsyn.data.FloatSample;
-import com.jsyn.data.SampleMarker;
-import com.jsyn.util.SampleLoader;
-
-public class AIFFFileParser extends AudioFileParser {
- private static final String SUPPORTED_FORMATS = "Only 16 and 24 bit PCM or 32-bit float AIF files supported.";
- static final int AIFF_ID = ('A' << 24) | ('I' << 16) | ('F' << 8) | 'F';
- static final int AIFC_ID = ('A' << 24) | ('I' << 16) | ('F' << 8) | 'C';
- static final int COMM_ID = ('C' << 24) | ('O' << 16) | ('M' << 8) | 'M';
- static final int SSND_ID = ('S' << 24) | ('S' << 16) | ('N' << 8) | 'D';
- static final int MARK_ID = ('M' << 24) | ('A' << 16) | ('R' << 8) | 'K';
- static final int INST_ID = ('I' << 24) | ('N' << 16) | ('S' << 8) | 'T';
- static final int NONE_ID = ('N' << 24) | ('O' << 16) | ('N' << 8) | 'E';
- static final int FL32_ID = ('F' << 24) | ('L' << 16) | ('3' << 8) | '2';
- static final int FL32_ID_LC = ('f' << 24) | ('l' << 16) | ('3' << 8) | '2';
-
- int sustainBeginID = -1;
- int sustainEndID = -1;
- int releaseBeginID = -1;
- int releaseEndID = -1;
- boolean typeFloat = false;
-
- @Override
- FloatSample finish() throws IOException {
- setLoops();
-
- if ((byteData == null)) {
- throw new IOException("No data found in audio sample.");
- }
- float[] floatData = new float[numFrames * samplesPerFrame];
- if (bitsPerSample == 16) {
- SampleLoader.decodeBigI16ToF32(byteData, 0, byteData.length, floatData, 0);
- } else if (bitsPerSample == 24) {
- SampleLoader.decodeBigI24ToF32(byteData, 0, byteData.length, floatData, 0);
- } else if (bitsPerSample == 32) {
- if (typeFloat) {
- SampleLoader.decodeBigF32ToF32(byteData, 0, byteData.length, floatData, 0);
- } else {
- SampleLoader.decodeBigI32ToF32(byteData, 0, byteData.length, floatData, 0);
- }
- } else {
- throw new IOException(SUPPORTED_FORMATS + " size = " + bitsPerSample);
- }
-
- return makeSample(floatData);
- }
-
- double read80BitFloat() throws IOException {
- /*
- * This is not a full decoding of the 80 bit number but it should suffice for the range we
- * expect.
- */
- byte[] bytes = new byte[10];
- parser.read(bytes);
- int exp = ((bytes[0] & 0x3F) << 8) | (bytes[1] & 0xFF);
- int mant = ((bytes[2] & 0xFF) << 16) | ((bytes[3] & 0xFF) << 8) | (bytes[4] & 0xFF);
- // System.out.println( "exp = " + exp + ", mant = " + mant );
- return mant / (double) (1 << (22 - exp));
- }
-
- void parseCOMMChunk(IFFParser parser, int ckSize) throws IOException {
- samplesPerFrame = parser.readShortBig();
- numFrames = parser.readIntBig();
- bitsPerSample = parser.readShortBig();
- frameRate = read80BitFloat();
- if (ckSize > 18) {
- int format = parser.readIntBig();
- // Validate data format.
- if ((format == FL32_ID) || (format == FL32_ID_LC)) {
- typeFloat = true;
- } else if (format == NONE_ID) {
- typeFloat = false;
- } else {
- throw new IOException(SUPPORTED_FORMATS + " format " + IFFParser.IDToString(format));
- }
- }
-
- bytesPerSample = (bitsPerSample + 7) / 8;
- bytesPerFrame = bytesPerSample * samplesPerFrame;
- }
-
- /* parse tuning and multi-sample info */
- @SuppressWarnings("unused")
- void parseINSTChunk(IFFParser parser, int ckSize) throws IOException {
- int baseNote = parser.readByte();
- int detune = parser.readByte();
- originalPitch = baseNote + (0.01 * detune);
-
- int lowNote = parser.readByte();
- int highNote = parser.readByte();
-
- parser.skip(2); /* lo,hi velocity */
- int gain = parser.readShortBig();
-
- int playMode = parser.readShortBig(); /* sustain */
- sustainBeginID = parser.readShortBig();
- sustainEndID = parser.readShortBig();
-
- playMode = parser.readShortBig(); /* release */
- releaseBeginID = parser.readShortBig();
- releaseEndID = parser.readShortBig();
- }
-
- private void setLoops() {
- SampleMarker cuePoint = cueMap.get(sustainBeginID);
- if (cuePoint != null) {
- sustainBegin = cuePoint.position;
- }
- cuePoint = cueMap.get(sustainEndID);
- if (cuePoint != null) {
- sustainEnd = cuePoint.position;
- }
- }
-
- void parseSSNDChunk(IFFParser parser, int ckSize) throws IOException {
- long numRead;
- // System.out.println("parseSSNDChunk()");
- int offset = parser.readIntBig();
- parser.readIntBig(); /* blocksize */
- parser.skip(offset);
- dataPosition = parser.getOffset();
- int numBytes = ckSize - 8 - offset;
- if (ifLoadData) {
- byteData = new byte[numBytes];
- numRead = parser.read(byteData);
- } else {
- numRead = parser.skip(numBytes);
- }
- if (numRead != numBytes)
- throw new EOFException("AIFF data chunk too short!");
- }
-
- void parseMARKChunk(IFFParser parser, int ckSize) throws IOException {
- long startOffset = parser.getOffset();
- int numCuePoints = parser.readShortBig();
- // System.out.println( "parseCueChunk: numCuePoints = " + numCuePoints
- // );
- for (int i = 0; i < numCuePoints; i++) {
- // Some AIF files have a bogus numCuePoints so check to see if we
- // are at end.
- long numInMark = parser.getOffset() - startOffset;
- if (numInMark >= ckSize) {
- System.out.println("Reached end of MARK chunk with bogus numCuePoints = "
- + numCuePoints);
- break;
- }
-
- int uniqueID = parser.readShortBig();
- int position = parser.readIntBig();
- int len = parser.read();
- String markerName = parseString(parser, len);
- if ((len & 1) == 0) {
- parser.skip(1); /* skip pad byte */
- }
-
- SampleMarker cuePoint = findOrCreateCuePoint(uniqueID);
- cuePoint.position = position;
- cuePoint.name = markerName;
-
- if (IFFParser.debug) {
- System.out.println("AIFF Marker at " + position + ", " + markerName);
- }
- }
- }
-
- /**
- * Called by parse() method to handle FORM chunks in an AIFF specific manner.
- *
- * @param ckID four byte chunk ID such as 'data'
- * @param ckSize size of chunk in bytes
- * @exception IOException If parsing fails, or IO error occurs.
- */
- @Override
- public void handleForm(IFFParser parser, int ckID, int ckSize, int type) throws IOException {
- if ((ckID == IFFParser.FORM_ID) && (type != AIFF_ID) && (type != AIFC_ID))
- throw new IOException("Bad AIFF form type = " + IFFParser.IDToString(type));
- }
-
- /**
- * Called by parse() method to handle chunks in an AIFF specific manner.
- *
- * @param ckID four byte chunk ID such as 'data'
- * @param ckSize size of chunk in bytes
- * @exception IOException If parsing fails, or IO error occurs.
- */
- @Override
- public void handleChunk(IFFParser parser, int ckID, int ckSize) throws IOException {
- switch (ckID) {
- case COMM_ID:
- parseCOMMChunk(parser, ckSize);
- break;
- case SSND_ID:
- parseSSNDChunk(parser, ckSize);
- break;
- case MARK_ID:
- parseMARKChunk(parser, ckSize);
- break;
- case INST_ID:
- parseINSTChunk(parser, ckSize);
- break;
- default:
- break;
- }
- }
-
-}
diff --git a/src/com/jsyn/util/soundfile/AudioFileParser.java b/src/com/jsyn/util/soundfile/AudioFileParser.java
deleted file mode 100644
index e7bb066..0000000
--- a/src/com/jsyn/util/soundfile/AudioFileParser.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright 2001 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.util.soundfile;
-
-import java.io.IOException;
-import java.util.HashMap;
-
-import com.jsyn.data.FloatSample;
-import com.jsyn.data.SampleMarker;
-
-/**
- * Base class for various types of audio specific file parsers.
- *
- * @author (C) 2001 Phil Burk, SoftSynth.com
- */
-
-abstract class AudioFileParser implements ChunkHandler {
- IFFParser parser;
- protected byte[] byteData;
- boolean ifLoadData = true; /* If true, load sound data into memory. */
- long dataPosition; /*
- * Number of bytes from beginning of file where sound data resides.
- */
- protected int bitsPerSample;
- protected int bytesPerFrame; // in the file
- protected int bytesPerSample; // in the file
- protected HashMap<Integer, SampleMarker> cueMap = new HashMap<Integer, SampleMarker>();
- protected short samplesPerFrame;
- protected double frameRate;
- protected int numFrames;
- protected double originalPitch = 60.0;
- protected int sustainBegin = -1;
- protected int sustainEnd = -1;
-
- public AudioFileParser() {
- }
-
- /**
- * @return Number of bytes from beginning of stream where sound data resides.
- */
- public long getDataPosition() {
- return dataPosition;
- }
-
- /**
- * This can be read by another thread when load()ing a sample to determine how many bytes have
- * been read so far.
- */
- public synchronized long getNumBytesRead() {
- IFFParser p = parser; // prevent race
- if (p != null)
- return p.getOffset();
- else
- return 0;
- }
-
- /**
- * This can be read by another thread when load()ing a sample to determine how many bytes need
- * to be read.
- */
- public synchronized long getFileSize() {
- IFFParser p = parser; // prevent race
- if (p != null)
- return p.getFileSize();
- else
- return 0;
- }
-
- protected SampleMarker findOrCreateCuePoint(int uniqueID) {
- SampleMarker cuePoint = cueMap.get(uniqueID);
- if (cuePoint == null) {
- cuePoint = new SampleMarker();
- cueMap.put(uniqueID, cuePoint);
- }
- return cuePoint;
- }
-
- public FloatSample load(IFFParser parser) throws IOException {
- this.parser = parser;
- parser.parseAfterHead(this);
- return finish();
- }
-
- abstract FloatSample finish() throws IOException;
-
- FloatSample makeSample(float[] floatData) throws IOException {
- FloatSample floatSample = new FloatSample(floatData, samplesPerFrame);
-
- floatSample.setChannelsPerFrame(samplesPerFrame);
- floatSample.setFrameRate(frameRate);
- floatSample.setPitch(originalPitch);
-
- if (sustainBegin >= 0) {
- floatSample.setSustainBegin(sustainBegin);
- floatSample.setSustainEnd(sustainEnd);
- }
-
- for (SampleMarker marker : cueMap.values()) {
- floatSample.addMarker(marker);
- }
-
- /* Set Sustain Loop by assuming first two markers are loop points. */
- if (floatSample.getMarkerCount() >= 2) {
- floatSample.setSustainBegin(floatSample.getMarker(0).position);
- floatSample.setSustainEnd(floatSample.getMarker(1).position);
- }
- return floatSample;
- }
-
- protected String parseString(IFFParser parser, int textLength) throws IOException {
- byte[] bar = new byte[textLength];
- parser.read(bar);
- return new String(bar);
- }
-}
diff --git a/src/com/jsyn/util/soundfile/ChunkHandler.java b/src/com/jsyn/util/soundfile/ChunkHandler.java
deleted file mode 100644
index 6dfe26d..0000000
--- a/src/com/jsyn/util/soundfile/ChunkHandler.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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.util.soundfile;
-
-import java.io.IOException;
-
-/**
- * Handle IFF Chunks as they are parsed from an IFF or RIFF file.
- *
- * @see IFFParser
- * @see AudioSampleAIFF
- * @author (C) 1997 Phil Burk, SoftSynth.com
- */
-interface ChunkHandler {
- /**
- * The parser will call this when it encounters a FORM or LIST chunk that contains other chunks.
- * This handler can either read the form's chunks, or let the parser find them and call
- * handleChunk().
- *
- * @param ID a 4 byte identifier such as FORM_ID that identifies the IFF chunk type.
- * @param numBytes number of bytes contained in the FORM, not counting the FORM type.
- * @param type a 4 byte identifier such as AIFF_ID that identifies the FORM type.
- */
- public void handleForm(IFFParser parser, int ID, int numBytes, int type) throws IOException;
-
- /**
- * The parser will call this when it encounters a chunk that is not a FORM or LIST. This handler
- * can either read the chunk's, or ignore it. The parser will skip over any unread data. Do NOT
- * read past the end of the chunk!
- *
- * @param ID a 4 byte identifier such as SSND_ID that identifies the IFF chunk type.
- * @param numBytes number of bytes contained in the chunk, not counting the ID and size field.
- */
- public void handleChunk(IFFParser parser, int ID, int numBytes) throws IOException;
-}
diff --git a/src/com/jsyn/util/soundfile/CustomSampleLoader.java b/src/com/jsyn/util/soundfile/CustomSampleLoader.java
deleted file mode 100644
index 14efde9..0000000
--- a/src/com/jsyn/util/soundfile/CustomSampleLoader.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2009 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.util.soundfile;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-
-import com.jsyn.data.FloatSample;
-import com.jsyn.util.AudioSampleLoader;
-
-public class CustomSampleLoader implements AudioSampleLoader {
-
- @Override
- public FloatSample loadFloatSample(File fileIn) throws IOException {
- FileInputStream fileStream = new FileInputStream(fileIn);
- BufferedInputStream inputStream = new BufferedInputStream(fileStream);
- return loadFloatSample(inputStream);
- }
-
- @Override
- public FloatSample loadFloatSample(URL url) throws IOException {
- InputStream rawStream = url.openStream();
- BufferedInputStream inputStream = new BufferedInputStream(rawStream);
- return loadFloatSample(inputStream);
- }
-
- @Override
- public FloatSample loadFloatSample(InputStream inputStream) throws IOException {
- AudioFileParser fileParser;
- IFFParser parser = new IFFParser(inputStream);
- parser.readHead();
- if (parser.isRIFF()) {
- fileParser = new WAVEFileParser();
- } else if (parser.isIFF()) {
- fileParser = new AIFFFileParser();
- } else {
- throw new IOException("Unsupported audio file type.");
- }
- return fileParser.load(parser);
- }
-
-}
diff --git a/src/com/jsyn/util/soundfile/IFFParser.java b/src/com/jsyn/util/soundfile/IFFParser.java
deleted file mode 100644
index f429657..0000000
--- a/src/com/jsyn/util/soundfile/IFFParser.java
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * 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.util.soundfile;
-
-import java.io.EOFException;
-import java.io.FilterInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * Parse Electronic Arts style IFF File. IFF is a file format that allows "chunks" of data to be
- * placed in a hierarchical file. It was designed by Jerry Morrison at Electronic Arts for the Amiga
- * computer and is now used extensively by Apple Computer and other companies. IFF is an open
- * standard.
- *
- * @see RIFFParser
- * @see AudioSampleAIFF
- * @author (C) 1997 Phil Burk, SoftSynth.com
- */
-
-class IFFParser extends FilterInputStream {
- private long numBytesRead = 0;
- private long totalSize = 0;
- private int fileId;
- static boolean debug = false;
-
- public static final int RIFF_ID = ('R' << 24) | ('I' << 16) | ('F' << 8) | 'F';
- public static final int LIST_ID = ('L' << 24) | ('I' << 16) | ('S' << 8) | 'T';
- public static final int FORM_ID = ('F' << 24) | ('O' << 16) | ('R' << 8) | 'M';
-
- IFFParser(InputStream stream) {
- super(stream);
- numBytesRead = 0;
- }
-
- /**
- * Size of file based on outermost chunk size plus 8. Can be used to report progress when
- * loading samples.
- *
- * @return Number of bytes in outer chunk plus header.
- */
- public long getFileSize() {
- return totalSize;
- }
-
- /**
- * Since IFF files use chunks with explicit size, it is important to keep track of how many
- * bytes have been read from the file. Can be used to report progress when loading samples.
- *
- * @return Number of bytes read from stream, or skipped.
- */
- public long getOffset() {
- return numBytesRead;
- }
-
- /** @return Next byte from stream. Increment offset by 1. */
- @Override
- public int read() throws IOException {
- numBytesRead++;
- return super.read();
- }
-
- /** @return Next byte array from stream. Increment offset by len. */
- @Override
- public int read(byte[] bar) throws IOException {
- return read(bar, 0, bar.length);
- }
-
- /** @return Next byte array from stream. Increment offset by len. */
- @Override
- public int read(byte[] bar, int off, int len) throws IOException {
- // Reading from a URL can return before all the bytes are available.
- // So we keep reading until we get the whole thing.
- int cursor = off;
- int numLeft = len;
- // keep reading data until we get it all
- while (numLeft > 0) {
- int numRead = super.read(bar, cursor, numLeft);
- if (numRead < 0)
- return numRead;
- cursor += numRead;
- numBytesRead += numRead;
- numLeft -= numRead;
- // System.out.println("read " + numRead + ", cursor = " + cursor +
- // ", len = " + len);
- }
- return cursor - off;
- }
-
- /** @return Skip forward in stream and add numBytes to offset. */
- @Override
- public long skip(long numBytes) throws IOException {
- numBytesRead += numBytes;
- return super.skip(numBytes);
- }
-
- /** Read 32 bit signed integer assuming Big Endian byte order. */
- public int readIntBig() throws IOException {
- int result = read() & 0xFF;
- result = (result << 8) | (read() & 0xFF);
- result = (result << 8) | (read() & 0xFF);
- int data = read();
- if (data == -1)
- throw new EOFException("readIntBig() - EOF in middle of word at offset " + numBytesRead);
- result = (result << 8) | (data & 0xFF);
- return result;
- }
-
- /** Read 32 bit signed integer assuming Little Endian byte order. */
- public int readIntLittle() throws IOException {
- int result = read() & 0xFF; // LSB
- result |= ((read() & 0xFF) << 8);
- result |= ((read() & 0xFF) << 16);
- int data = read();
- if (data == -1)
- throw new EOFException("readIntLittle() - EOF in middle of word at offset "
- + numBytesRead);
- result |= (data << 24);
- return result;
- }
-
- /** Read 16 bit signed short assuming Big Endian byte order. */
- public short readShortBig() throws IOException {
- short result = (short) ((read() << 8)); // MSB
- int data = read();
- if (data == -1)
- throw new EOFException("readShortBig() - EOF in middle of word at offset "
- + numBytesRead);
- result |= data & 0xFF;
- return result;
- }
-
- /** Read 16 bit signed short assuming Little Endian byte order. */
- public short readShortLittle() throws IOException {
- short result = (short) (read() & 0xFF); // LSB
- int data = read(); // MSB
- if (data == -1)
- throw new EOFException("readShortLittle() - EOF in middle of word at offset "
- + numBytesRead);
- result |= data << 8;
- return result;
- }
-
- public int readUShortLittle() throws IOException {
- return (readShortLittle()) & 0x0000FFFF;
- }
-
- /** Read 8 bit signed byte. */
- public byte readByte() throws IOException {
- return (byte) read();
- }
-
- /** Read 32 bit signed int assuming IFF order. */
- public int readChunkSize() throws IOException {
- if (isRIFF()) {
- return readIntLittle();
- }
- {
- return readIntBig();
- }
- }
-
- /** Convert a 4 character IFF ID to a String */
- public static String IDToString(int ID) {
- byte bar[] = new byte[4];
- bar[0] = (byte) (ID >> 24);
- bar[1] = (byte) (ID >> 16);
- bar[2] = (byte) (ID >> 8);
- bar[3] = (byte) ID;
- return new String(bar);
- }
-
- /**
- * Parse the stream after reading the first ID and pass the forms and chunks to the ChunkHandler
- */
- public void parseAfterHead(ChunkHandler handler) throws IOException {
- int numBytes = readChunkSize();
- totalSize = numBytes + 8;
- parseChunk(handler, fileId, numBytes);
- if (debug)
- System.out.println("parse() ------- end");
- }
-
- /**
- * Parse the FORM and pass the chunks to the ChunkHandler The cursor should be positioned right
- * after the type field.
- */
- void parseForm(ChunkHandler handler, int ID, int numBytes, int type) throws IOException {
- if (debug) {
- System.out.println("IFF: parseForm >>>>>>>>>>>>>>>>>> BEGIN");
- }
- while (numBytes > 8) {
- int ckid = readIntBig();
- int size = readChunkSize();
- numBytes -= 8;
- if (debug) {
- System.out.println("chunk( " + IDToString(ckid) + ", " + size + " )");
- }
- if (size < 0) {
- throw new IOException("Bad IFF chunk Size: " + IDToString(ckid) + " = 0x"
- + Integer.toHexString(ckid) + ", Size = " + size);
- }
- parseChunk(handler, ckid, size);
- if ((size & 1) == 1)
- size++; // even-up
- numBytes -= size;
- if (debug) {
- System.out.println("parseForm: numBytes left in form = " + numBytes);
- }
- }
- if (debug) {
- System.out.println("IFF: parseForm <<<<<<<<<<<<<<<<<<<< END");
- }
-
- if (numBytes > 0) {
- System.out.println("IFF Parser detected " + numBytes
- + " bytes of garbage at end of FORM.");
- skip(numBytes);
- }
- }
-
- /*
- * Parse one chunk from IFF file. After calling handler, make sure stream is positioned at end
- * of chunk.
- */
- void parseChunk(ChunkHandler handler, int ckid, int numBytes) throws IOException {
- long startOffset, endOffset;
- int numRead;
- startOffset = getOffset();
- if (isForm(ckid)) {
- int type = readIntBig();
- if (debug)
- System.out.println("parseChunk: form = " + IDToString(ckid) + ", " + numBytes
- + ", " + IDToString(type));
- handler.handleForm(this, ckid, numBytes - 4, type);
- endOffset = getOffset();
- numRead = (int) (endOffset - startOffset);
- if (numRead < numBytes)
- parseForm(handler, ckid, (numBytes - numRead), type);
- } else {
- handler.handleChunk(this, ckid, numBytes);
- }
- endOffset = getOffset();
- numRead = (int) (endOffset - startOffset);
- if (debug) {
- System.out.println("parseChunk: endOffset = " + endOffset);
- System.out.println("parseChunk: numRead = " + numRead);
- }
- if ((numBytes & 1) == 1)
- numBytes++; // even-up
- if (numRead < numBytes)
- skip(numBytes - numRead);
- }
-
- public void readHead() throws IOException {
- if (debug)
- System.out.println("parse() ------- begin");
- numBytesRead = 0;
- fileId = readIntBig();
- }
-
- public boolean isRIFF() {
- return (fileId == RIFF_ID);
- }
-
- public boolean isIFF() {
- return (fileId == FORM_ID);
- }
-
- /**
- * Does the following chunk ID correspond to a container type like FORM?
- */
- public boolean isForm(int ckid) {
- if (isRIFF()) {
- switch (ckid) {
- case LIST_ID:
- case RIFF_ID:
- return true;
- default:
- return false;
- }
- } else {
- switch (ckid) {
- case LIST_ID:
- case FORM_ID:
- return true;
- default:
- return false;
- }
- }
- }
-
-}
diff --git a/src/com/jsyn/util/soundfile/WAVEFileParser.java b/src/com/jsyn/util/soundfile/WAVEFileParser.java
deleted file mode 100644
index ec9350c..0000000
--- a/src/com/jsyn/util/soundfile/WAVEFileParser.java
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * Copyright 2009 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.util.soundfile;
-
-import java.io.EOFException;
-import java.io.IOException;
-
-import com.jsyn.data.FloatSample;
-import com.jsyn.data.SampleMarker;
-import com.jsyn.util.SampleLoader;
-
-class WAVEFileParser extends AudioFileParser implements ChunkHandler {
- static final short WAVE_FORMAT_PCM = 1;
- static final short WAVE_FORMAT_IEEE_FLOAT = 3;
- static final short WAVE_FORMAT_EXTENSIBLE = (short) 0xFFFE;
-
- static final byte[] KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = {
- 3, 0, 0, 0, 0, 0, 16, 0, -128, 0, 0, -86, 0, 56, -101, 113
- };
- static final byte[] KSDATAFORMAT_SUBTYPE_PCM = {
- 1, 0, 0, 0, 0, 0, 16, 0, -128, 0, 0, -86, 0, 56, -101, 113
- };
-
- static final int WAVE_ID = ('W' << 24) | ('A' << 16) | ('V' << 8) | 'E';
- static final int FMT_ID = ('f' << 24) | ('m' << 16) | ('t' << 8) | ' ';
- static final int DATA_ID = ('d' << 24) | ('a' << 16) | ('t' << 8) | 'a';
- static final int CUE_ID = ('c' << 24) | ('u' << 16) | ('e' << 8) | ' ';
- static final int FACT_ID = ('f' << 24) | ('a' << 16) | ('c' << 8) | 't';
- static final int SMPL_ID = ('s' << 24) | ('m' << 16) | ('p' << 8) | 'l';
- static final int LTXT_ID = ('l' << 24) | ('t' << 16) | ('x' << 8) | 't';
- static final int LABL_ID = ('l' << 24) | ('a' << 16) | ('b' << 8) | 'l';
-
- int samplesPerBlock = 0;
- int blockAlign = 0;
- private int numFactSamples = 0;
- private short format;
-
- WAVEFileParser() {
- }
-
- @Override
- FloatSample finish() throws IOException {
- if ((byteData == null)) {
- throw new IOException("No data found in audio sample.");
- }
- float[] floatData = new float[numFrames * samplesPerFrame];
- if (bitsPerSample == 16) {
- SampleLoader.decodeLittleI16ToF32(byteData, 0, byteData.length, floatData, 0);
- } else if (bitsPerSample == 24) {
- SampleLoader.decodeLittleI24ToF32(byteData, 0, byteData.length, floatData, 0);
- } else if (bitsPerSample == 32) {
- if (format == WAVE_FORMAT_IEEE_FLOAT) {
- SampleLoader.decodeLittleF32ToF32(byteData, 0, byteData.length, floatData, 0);
- } else if (format == WAVE_FORMAT_PCM) {
- SampleLoader.decodeLittleI32ToF32(byteData, 0, byteData.length, floatData, 0);
- } else {
- throw new IOException("WAV: Unsupported format = " + format);
- }
- } else {
- throw new IOException("WAV: Unsupported bitsPerSample = " + bitsPerSample);
- }
-
- return makeSample(floatData);
- }
-
- // typedef struct {
- // long dwIdentifier;
- // long dwPosition;
- // ID fccChunk;
- // long dwChunkStart;
- // long dwBlockStart;
- // long dwSampleOffset;
- // } CuePoint;
-
- /* Parse various chunks encountered in WAV file. */
- void parseCueChunk(IFFParser parser, int ckSize) throws IOException {
- int numCuePoints = parser.readIntLittle();
- if (IFFParser.debug) {
- System.out.println("WAV: numCuePoints = " + numCuePoints);
- }
- if ((ckSize - 4) != (6 * 4 * numCuePoints))
- throw new EOFException("Cue chunk too short!");
- for (int i = 0; i < numCuePoints; i++) {
- int dwName = parser.readIntLittle(); /* dwName */
- int position = parser.readIntLittle(); // dwPosition
- parser.skip(3 * 4); // fccChunk, dwChunkStart, dwBlockStart
- int sampleOffset = parser.readIntLittle(); // dwPosition
-
- if (IFFParser.debug) {
- System.out.println("WAV: parseCueChunk: #" + i + ", dwPosition = " + position
- + ", dwName = " + dwName + ", dwSampleOffset = " + sampleOffset);
- }
- SampleMarker cuePoint = findOrCreateCuePoint(dwName);
- cuePoint.position = position;
- }
- }
-
- void parseLablChunk(IFFParser parser, int ckSize) throws IOException {
- int dwName = parser.readIntLittle();
- int textLength = (ckSize - 4) - 1; // don't read NUL terminator
- String text = parseString(parser, textLength);
- if (IFFParser.debug) {
- System.out.println("WAV: label id = " + dwName + ", text = " + text);
- }
- SampleMarker cuePoint = findOrCreateCuePoint(dwName);
- cuePoint.name = text;
- }
-
- void parseLtxtChunk(IFFParser parser, int ckSize) throws IOException {
- int dwName = parser.readIntLittle();
- int dwSampleLength = parser.readIntLittle();
- parser.skip(4 + (4 * 2)); // purpose through codepage
- int textLength = (ckSize - ((4 * 4) + (4 * 2))) - 1; // don't read NUL
- // terminator
- if (textLength > 0) {
- String text = parseString(parser, textLength);
- if (IFFParser.debug) {
- System.out.println("WAV: ltxt id = " + dwName + ", dwSampleLength = "
- + dwSampleLength + ", text = " + text);
- }
- SampleMarker cuePoint = findOrCreateCuePoint(dwName);
- cuePoint.comment = text;
- }
- }
-
- void parseFmtChunk(IFFParser parser, int ckSize) throws IOException {
- format = parser.readShortLittle();
- samplesPerFrame = parser.readShortLittle();
- frameRate = parser.readIntLittle();
- parser.readIntLittle(); /* skip dwAvgBytesPerSec */
- blockAlign = parser.readShortLittle();
- bitsPerSample = parser.readShortLittle();
-
- if (IFFParser.debug) {
- System.out.println("WAV: format = 0x" + Integer.toHexString(format));
- System.out.println("WAV: bitsPerSample = " + bitsPerSample);
- System.out.println("WAV: samplesPerFrame = " + samplesPerFrame);
- }
- bytesPerFrame = blockAlign;
- bytesPerSample = bytesPerFrame / samplesPerFrame;
- samplesPerBlock = (8 * blockAlign) / bitsPerSample;
-
- if (format == WAVE_FORMAT_EXTENSIBLE) {
- int extraSize = parser.readShortLittle();
- short validBitsPerSample = parser.readShortLittle();
- int channelMask = parser.readIntLittle();
- byte[] guid = new byte[16];
- parser.read(guid);
- if (IFFParser.debug) {
- System.out.println("WAV: extraSize = " + extraSize);
- System.out.println("WAV: validBitsPerSample = " + validBitsPerSample);
- System.out.println("WAV: channelMask = " + channelMask);
- System.out.print("guid = {");
- for (int i = 0; i < guid.length; i++) {
- System.out.print(guid[i] + ", ");
- }
- System.out.println("}");
- }
- if (matchBytes(guid, KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)) {
- format = WAVE_FORMAT_IEEE_FLOAT;
- } else if (matchBytes(guid, KSDATAFORMAT_SUBTYPE_PCM)) {
- format = WAVE_FORMAT_PCM;
- }
- }
- if ((format != WAVE_FORMAT_PCM) && (format != WAVE_FORMAT_IEEE_FLOAT)) {
- throw new IOException(
- "Only WAVE_FORMAT_PCM and WAVE_FORMAT_IEEE_FLOAT supported. format = " + format);
- }
- if ((bitsPerSample != 16) && (bitsPerSample != 24) && (bitsPerSample != 32)) {
- throw new IOException(
- "Only 16 and 24 bit PCM or 32-bit float WAV files supported. width = "
- + bitsPerSample);
- }
- }
-
- private boolean matchBytes(byte[] bar1, byte[] bar2) {
- if (bar1.length != bar2.length)
- return false;
- for (int i = 0; i < bar1.length; i++) {
- if (bar1[i] != bar2[i])
- return false;
- }
- return true;
- }
-
- private int convertByteToFrame(int byteOffset) throws IOException {
- if (blockAlign == 0) {
- throw new IOException("WAV file has bytesPerBlock = zero");
- }
- if (samplesPerFrame == 0) {
- throw new IOException("WAV file has samplesPerFrame = zero");
- }
- int nFrames = (samplesPerBlock * byteOffset) / (samplesPerFrame * blockAlign);
- return nFrames;
- }
-
- private int calculateNumFrames(int numBytes) throws IOException {
- int nFrames;
- if (numFactSamples > 0) {
- // nFrames = numFactSamples / samplesPerFrame;
- nFrames = numFactSamples; // FIXME which is right
- } else {
- nFrames = convertByteToFrame(numBytes);
- }
- return nFrames;
- }
-
- // Read fraction in range of 0 to 0xFFFFFFFF and
- // convert to 0.0 to 1.0 range.
- private double readFraction(IFFParser parser) throws IOException {
- // Put L at end or we get -1.
- long maxFraction = 0x0FFFFFFFFL;
- // Get unsigned fraction. Have to fit in long.
- long fraction = (parser.readIntLittle()) & maxFraction;
- return (double) fraction / (double) maxFraction;
- }
-
- void parseSmplChunk(IFFParser parser, int ckSize) throws IOException {
- parser.readIntLittle(); // Manufacturer
- parser.readIntLittle(); // Product
- parser.readIntLittle(); // Sample Period
- int unityNote = parser.readIntLittle();
- double pitchFraction = readFraction(parser);
- originalPitch = unityNote + pitchFraction;
-
- parser.readIntLittle(); // SMPTE Format
- parser.readIntLittle(); // SMPTE Offset
- int numLoops = parser.readIntLittle();
- parser.readIntLittle(); // Sampler Data
-
- int lastCueID = Integer.MAX_VALUE;
- for (int i = 0; i < numLoops; i++) {
- int cueID = parser.readIntLittle();
- parser.readIntLittle(); // type
- int loopStartPosition = parser.readIntLittle();
- // Point to sample one after.
- int loopEndPosition = parser.readIntLittle() + 1;
- // TODO handle fractional loop sizes?
- double endFraction = readFraction(parser);
- parser.readIntLittle(); // playCount
-
- // Use lowest numbered cue.
- if (cueID < lastCueID) {
- sustainBegin = loopStartPosition;
- sustainEnd = loopEndPosition;
- }
- }
- }
-
- void parseFactChunk(IFFParser parser, int ckSize) throws IOException {
- numFactSamples = parser.readIntLittle();
- }
-
- void parseDataChunk(IFFParser parser, int ckSize) throws IOException {
- long numRead;
- dataPosition = parser.getOffset();
- if (ifLoadData) {
- byteData = new byte[ckSize];
- numRead = parser.read(byteData);
- } else {
- numRead = parser.skip(ckSize);
- }
- if (numRead != ckSize) {
- throw new EOFException("WAV data chunk too short! Read " + numRead + " instead of "
- + ckSize);
- }
- numFrames = calculateNumFrames(ckSize);
- }
-
- @Override
- public void handleForm(IFFParser parser, int ckID, int ckSize, int type) throws IOException {
- if ((ckID == IFFParser.RIFF_ID) && (type != WAVE_ID))
- throw new IOException("Bad WAV form type = " + IFFParser.IDToString(type));
- }
-
- /**
- * Called by parse() method to handle chunks in a WAV specific manner.
- *
- * @param ckID four byte chunk ID such as 'data'
- * @param ckSize size of chunk in bytes
- * @return number of bytes left in chunk
- */
- @Override
- public void handleChunk(IFFParser parser, int ckID, int ckSize) throws IOException {
- switch (ckID) {
- case FMT_ID:
- parseFmtChunk(parser, ckSize);
- break;
- case DATA_ID:
- parseDataChunk(parser, ckSize);
- break;
- case CUE_ID:
- parseCueChunk(parser, ckSize);
- break;
- case FACT_ID:
- parseFactChunk(parser, ckSize);
- break;
- case SMPL_ID:
- parseSmplChunk(parser, ckSize);
- break;
- case LABL_ID:
- parseLablChunk(parser, ckSize);
- break;
- case LTXT_ID:
- parseLtxtChunk(parser, ckSize);
- break;
- default:
- break;
- }
- }
-
- /*
- * (non-Javadoc)
- * @see com.softsynth.javasonics.util.AudioSampleLoader#isLittleEndian()
- */
- boolean isLittleEndian() {
- return true;
- }
-
-}