diff options
author | Phil Burk <[email protected]> | 2016-11-30 19:26:29 -0800 |
---|---|---|
committer | GitHub <[email protected]> | 2016-11-30 19:26:29 -0800 |
commit | 10ffa9acf32c7fb40f084d9cef9a0ff5e608fc0c (patch) | |
tree | c6e70f7a076bb65484f52709864975b21afab75d /src/com/jsyn | |
parent | 5cc223574b43d3f72b746e8f0bb4f31cbd2fd52f (diff) | |
parent | cc4bcfe2aa049543ee759823bc0a72282e4a1dc5 (diff) |
Merge pull request #43 from philburk/rc-1678
last minute changes for 16.7.8
Diffstat (limited to 'src/com/jsyn')
-rw-r--r-- | src/com/jsyn/JSyn.java | 6 | ||||
-rw-r--r-- | src/com/jsyn/data/DoubleTable.java | 12 | ||||
-rw-r--r-- | src/com/jsyn/midi/MidiSynthesizer.java | 20 | ||||
-rw-r--r-- | src/com/jsyn/unitgen/EdgeDetector.java | 13 | ||||
-rw-r--r-- | src/com/jsyn/util/MultiChannelSynthesizer.java | 60 | ||||
-rw-r--r-- | src/com/jsyn/util/PolyphonicInstrument.java | 2 |
6 files changed, 89 insertions, 24 deletions
diff --git a/src/com/jsyn/JSyn.java b/src/com/jsyn/JSyn.java index 7598305..8eed8a9 100644 --- a/src/com/jsyn/JSyn.java +++ b/src/com/jsyn/JSyn.java @@ -56,10 +56,10 @@ public class JSyn { // Update these for every release. private final static int VERSION_MAJOR = 16; private final static int VERSION_MINOR = 7; - private final static int VERSION_REVISION = 6; - public final static int BUILD_NUMBER = 460; + private final static int VERSION_REVISION = 8; + public final static int BUILD_NUMBER = 462; private final static long BUILD_TIME = new GregorianCalendar(2016, - GregorianCalendar.AUGUST, 9).getTime().getTime(); + GregorianCalendar.NOVEMBER, 30).getTime().getTime(); public final static String VERSION = VERSION_MAJOR + "." + VERSION_MINOR + "." + VERSION_REVISION; diff --git a/src/com/jsyn/data/DoubleTable.java b/src/com/jsyn/data/DoubleTable.java index 0a34a95..ca64c94 100644 --- a/src/com/jsyn/data/DoubleTable.java +++ b/src/com/jsyn/data/DoubleTable.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -21,7 +21,7 @@ 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 { @@ -60,6 +60,10 @@ public class DoubleTable implements Function { table = new double[numFrames]; } + public int length() { + return table.length; + } + public void write(double[] data) { write(0, data, 0, data.length); } @@ -79,7 +83,7 @@ public class DoubleTable implements Function { /** * 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 */ diff --git a/src/com/jsyn/midi/MidiSynthesizer.java b/src/com/jsyn/midi/MidiSynthesizer.java index e011430..30204b0 100644 --- a/src/com/jsyn/midi/MidiSynthesizer.java +++ b/src/com/jsyn/midi/MidiSynthesizer.java @@ -16,8 +16,28 @@ 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; diff --git a/src/com/jsyn/unitgen/EdgeDetector.java b/src/com/jsyn/unitgen/EdgeDetector.java index a5bff9d..e314f7d 100644 --- a/src/com/jsyn/unitgen/EdgeDetector.java +++ b/src/com/jsyn/unitgen/EdgeDetector.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -20,14 +20,13 @@ 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; - /* Define Unit Ports used by connect() and set(). */ public EdgeDetector() { } @@ -37,12 +36,8 @@ public class EdgeDetector extends UnitFilter { double[] outputs = output.getValues(); for (int i = start; i < limit; i++) { - double value = 0.0; double in = inputs[i]; - if ((previous <= 0.0) && (in > 0.0)) { - value = 1.0; - } - outputs[i] = value; + outputs[i] = ((previous <= 0.0) && (in > 0.0)) ? 1.0 : 0.0; previous = in; } } diff --git a/src/com/jsyn/util/MultiChannelSynthesizer.java b/src/com/jsyn/util/MultiChannelSynthesizer.java index 6db0790..8027994 100644 --- a/src/com/jsyn/util/MultiChannelSynthesizer.java +++ b/src/com/jsyn/util/MultiChannelSynthesizer.java @@ -52,6 +52,8 @@ 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; @@ -83,7 +85,6 @@ public class MultiChannelSynthesizer { private Pan panner; private double vibratoRate = 5.0; private double bendRangeOctaves = 2.0 / 12.0; -// private double bendRangeOctaves = 0.0 / 12.0; private int presetIndex; private ChannelGroupContext groupContext; VoiceOperation voiceOperation = new VoiceOperation() { @@ -120,7 +121,6 @@ public class MultiChannelSynthesizer { 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) { @@ -157,13 +157,12 @@ public class MultiChannelSynthesizer { presetIndex = programWrapped; } - void noteOff(int noteNumber, int velocity) { + void noteOff(int noteNumber, double amplitude) { groupContext.allocator.noteOff(noteNumber, synth.createTimeStamp()); } - void noteOn(int noteNumber, int velocity) { + void noteOn(int noteNumber, double amplitude) { double frequency = AudioMath.pitchToFrequency(noteNumber); - double amplitude = velocity / (4 * 128.0); TimeStamp timeStamp = synth.createTimeStamp(); //System.out.println("noteOn(noteNumber) -> " + frequency + " Hz"); groupContext.allocator.noteOn(noteNumber, frequency, amplitude, voiceOperation, timeStamp); @@ -257,14 +256,48 @@ public class MultiChannelSynthesizer { 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, velocity); + channelContext.noteOff(noteNumber, amplitude * mMasterAmplitude); } + /** + * 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) { ChannelContext channelContext = channels[channel]; - channelContext.noteOn(noteNumber, velocity); + channelContext.noteOn(noteNumber, amplitude * mMasterAmplitude); } /** @@ -321,8 +354,21 @@ public class MultiChannelSynthesizer { 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/PolyphonicInstrument.java b/src/com/jsyn/util/PolyphonicInstrument.java index 2cba78f..08460d0 100644 --- a/src/com/jsyn/util/PolyphonicInstrument.java +++ b/src/com/jsyn/util/PolyphonicInstrument.java @@ -86,7 +86,7 @@ public class PolyphonicInstrument extends Circuit implements UnitSource, Instrum * @param portName * @see exportAllInputPorts */ - void exportNamedInputPort(String portName) { + public void exportNamedInputPort(String portName) { UnitInputPort voicePort = null; PassThrough fanout = new PassThrough(); for (UnitVoice voice : voices) { |