aboutsummaryrefslogtreecommitdiffstats
path: root/src/com/jsyn/instruments/DrumWoodFM.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/jsyn/instruments/DrumWoodFM.java')
-rw-r--r--src/com/jsyn/instruments/DrumWoodFM.java159
1 files changed, 159 insertions, 0 deletions
diff --git a/src/com/jsyn/instruments/DrumWoodFM.java b/src/com/jsyn/instruments/DrumWoodFM.java
new file mode 100644
index 0000000..ba6cd1b
--- /dev/null
+++ b/src/com/jsyn/instruments/DrumWoodFM.java
@@ -0,0 +1,159 @@
+/*
+ * 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();
+ }
+}