aboutsummaryrefslogtreecommitdiffstats
path: root/src/mdaJX10.cpp
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2008-08-08 22:45:58 +0000
committerDavid Robillard <d@drobilla.net>2008-08-08 22:45:58 +0000
commite360047054117d63fb579ec9231e9dc77c99f12a (patch)
tree4a497365f6ecd30449e2c66c1fe77c816bd1fe4a /src/mdaJX10.cpp
downloadmda.lv2-e360047054117d63fb579ec9231e9dc77c99f12a.tar.gz
mda.lv2-e360047054117d63fb579ec9231e9dc77c99f12a.tar.bz2
mda.lv2-e360047054117d63fb579ec9231e9dc77c99f12a.zip
Add preliminary (library side only) LV2 port of MDA (open-sourced VST plugins).
git-svn-id: http://svn.drobilla.net/lad/mda-lv2@1321 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/mdaJX10.cpp')
-rw-r--r--src/mdaJX10.cpp1000
1 files changed, 1000 insertions, 0 deletions
diff --git a/src/mdaJX10.cpp b/src/mdaJX10.cpp
new file mode 100644
index 0000000..4014d5c
--- /dev/null
+++ b/src/mdaJX10.cpp
@@ -0,0 +1,1000 @@
+//
+// Plug-in: "mda JX10" v1.1
+//
+// Copyright(c)1999-2001 Paul Kellett (maxim digital audio)
+//
+
+#include "mdaJX10.h"
+
+#include <stdio.h>
+#include <stdlib.h> //rand()
+#include <math.h>
+
+
+AudioEffect *createEffectInstance(audioMasterCallback audioMaster)
+{
+ return new mdaJX10(audioMaster);
+}
+
+
+mdaJX10Program::mdaJX10Program()
+{
+ param[0] = 0.00f; //OSC Mix
+ param[1] = 0.25f; //OSC Tune
+ param[2] = 0.50f; //OSC Fine
+
+ param[3] = 0.00f; //OSC Mode
+ param[4] = 0.35f; //OSC Rate
+ param[5] = 0.50f; //OSC Bend
+
+ param[6] = 1.00f; //VCF Freq
+ param[7] = 0.15f; //VCF Reso
+ param[8] = 0.75f; //VCF <Env
+
+ param[9] = 0.00f; //VCF <LFO
+ param[10] = 0.50f; //VCF <Vel
+ param[11] = 0.00f; //VCF Att
+
+ param[12] = 0.30f; //VCF Dec
+ param[13] = 0.00f; //VCF Sus
+ param[14] = 0.25f; //VCF Rel
+
+ param[15] = 0.00f; //ENV Att
+ param[16] = 0.50f; //ENV Dec
+ param[17] = 1.00f; //ENV Sus
+
+ param[18] = 0.30f; //ENV Rel
+ param[19] = 0.81f; //LFO Rate
+ param[20] = 0.50f; //Vibrato
+
+ param[21] = 0.00f; //Noise - not present in original patches
+ param[22] = 0.50f; //Octave
+ param[23] = 0.50f; //Tuning
+ strcpy (name, "Empty Patch");
+}
+
+
+mdaJX10::mdaJX10(audioMasterCallback audioMaster) : AudioEffectX(audioMaster, NPROGS, NPARAMS)
+{
+ long i=0;
+ Fs = 44100.0f;
+
+ programs = new mdaJX10Program[NPROGS];
+ if(programs)
+ {
+ fillpatch(i++, "5th Sweep Pad", 1.0f, 0.37f, 0.25f, 0.3f, 0.32f, 0.5f, 0.9f, 0.6f, 0.12f, 0.0f, 0.5f, 0.9f, 0.89f, 0.9f, 0.73f, 0.0f, 0.5f, 1.0f, 0.71f, 0.81f, 0.65f, 0.0f, 0.5f, 0.5f);
+ fillpatch(i++, "Echo Pad [SA]", 0.88f, 0.51f, 0.5f, 0.0f, 0.49f, 0.5f, 0.46f, 0.76f, 0.69f, 0.1f, 0.69f, 1.0f, 0.86f, 0.76f, 0.57f, 0.3f, 0.8f, 0.68f, 0.66f, 0.79f, 0.13f, 0.25f, 0.45f, 0.5f);
+ fillpatch(i++, "Space Chimes [SA]", 0.88f, 0.51f, 0.5f, 0.16f, 0.49f, 0.5f, 0.49f, 0.82f, 0.66f, 0.08f, 0.89f, 0.85f, 0.69f, 0.76f, 0.47f, 0.12f, 0.22f, 0.55f, 0.66f, 0.89f, 0.34f, 0.0f, 1.0f, 0.5f);
+ fillpatch(i++, "Solid Backing", 1.0f, 0.26f, 0.14f, 0.0f, 0.35f, 0.5f, 0.3f, 0.25f, 0.7f, 0.0f, 0.63f, 0.0f, 0.35f, 0.0f, 0.25f, 0.0f, 0.5f, 1.0f, 0.3f, 0.81f, 0.5f, 0.5f, 0.5f, 0.5f);
+ fillpatch(i++, "Velocity Backing [SA]", 0.41f, 0.5f, 0.79f, 0.0f, 0.08f, 0.32f, 0.49f, 0.01f, 0.34f, 0.0f, 0.93f, 0.61f, 0.87f, 1.0f, 0.93f, 0.11f, 0.48f, 0.98f, 0.32f, 0.81f, 0.5f, 0.0f, 0.5f, 0.5f);
+ fillpatch(i++, "Rubber Backing [ZF]", 0.29f, 0.76f, 0.26f, 0.0f, 0.18f, 0.76f, 0.35f, 0.15f, 0.77f, 0.14f, 0.54f, 0.0f, 0.42f, 0.13f, 0.21f, 0.0f, 0.56f, 0.0f, 0.32f, 0.2f, 0.58f, 0.22f, 0.53f, 0.5f);
+ fillpatch(i++, "808 State Lead", 1.0f, 0.65f, 0.24f, 0.4f, 0.34f, 0.85f, 0.65f, 0.63f, 0.75f, 0.16f, 0.5f, 0.0f, 0.3f, 0.0f, 0.25f, 0.17f, 0.5f, 1.0f, 0.03f, 0.81f, 0.5f, 0.0f, 0.68f, 0.5f);
+ fillpatch(i++, "Mono Glide", 0.0f, 0.25f, 0.5f, 1.0f, 0.46f, 0.5f, 0.51f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.3f, 0.0f, 0.25f, 0.37f, 0.5f, 1.0f, 0.38f, 0.81f, 0.62f, 0.0f, 0.5f, 0.5f);
+ fillpatch(i++, "Detuned Techno Lead", 0.84f, 0.51f, 0.15f, 0.45f, 0.41f, 0.42f, 0.54f, 0.01f, 0.58f, 0.21f, 0.67f, 0.0f, 0.09f, 1.0f, 0.25f, 0.2f, 0.85f, 1.0f, 0.3f, 0.83f, 0.09f, 0.4f, 0.49f, 0.5f);
+ fillpatch(i++, "Hard Lead [SA]", 0.71f, 0.75f, 0.53f, 0.18f, 0.24f, 1.0f, 0.56f, 0.52f, 0.69f, 0.19f, 0.7f, 1.0f, 0.14f, 0.65f, 0.95f, 0.07f, 0.91f, 1.0f, 0.15f, 0.84f, 0.33f, 0.0f, 0.49f, 0.5f);
+ fillpatch(i++, "Bubble", 0.0f, 0.25f, 0.43f, 0.0f, 0.71f, 0.48f, 0.23f, 0.77f, 0.8f, 0.32f, 0.63f, 0.4f, 0.18f, 0.66f, 0.14f, 0.0f, 0.38f, 0.65f, 0.16f, 0.48f, 0.5f, 0.0f, 0.67f, 0.5f);
+ fillpatch(i++, "Monosynth", 0.62f, 0.26f, 0.51f, 0.79f, 0.35f, 0.54f, 0.64f, 0.39f, 0.51f, 0.65f, 0.0f, 0.07f, 0.52f, 0.24f, 0.84f, 0.13f, 0.3f, 0.76f, 0.21f, 0.58f, 0.3f, 0.0f, 0.36f, 0.5f);
+ fillpatch(i++, "Moogcury Lite", 0.81f, 1.0f, 0.21f, 0.78f, 0.15f, 0.35f, 0.39f, 0.17f, 0.69f, 0.4f, 0.62f, 0.0f, 0.47f, 0.19f, 0.37f, 0.0f, 0.5f, 0.2f, 0.33f, 0.38f, 0.53f, 0.0f, 0.12f, 0.5f);
+ fillpatch(i++, "Gangsta Whine", 0.0f, 0.51f, 0.52f, 0.96f, 0.44f, 0.5f, 0.41f, 0.46f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.25f, 0.15f, 0.5f, 1.0f, 0.32f, 0.81f, 0.49f, 0.0f, 0.83f, 0.5f);
+ fillpatch(i++, "Higher Synth [ZF]", 0.48f, 0.51f, 0.22f, 0.0f, 0.0f, 0.5f, 0.5f, 0.47f, 0.73f, 0.3f, 0.8f, 0.0f, 0.1f, 0.0f, 0.07f, 0.0f, 0.42f, 0.0f, 0.22f, 0.21f, 0.59f, 0.16f, 0.98f, 0.5f);
+ fillpatch(i++, "303 Saw Bass", 0.0f, 0.51f, 0.5f, 0.83f, 0.49f, 0.5f, 0.55f, 0.75f, 0.69f, 0.35f, 0.5f, 0.0f, 0.56f, 0.0f, 0.56f, 0.0f, 0.8f, 1.0f, 0.24f, 0.26f, 0.49f, 0.0f, 0.07f, 0.5f);
+ fillpatch(i++, "303 Square Bass", 0.75f, 0.51f, 0.5f, 0.83f, 0.49f, 0.5f, 0.55f, 0.75f, 0.69f, 0.35f, 0.5f, 0.14f, 0.49f, 0.0f, 0.39f, 0.0f, 0.8f, 1.0f, 0.24f, 0.26f, 0.49f, 0.0f, 0.07f, 0.5f);
+ fillpatch(i++, "Analog Bass", 1.0f, 0.25f, 0.2f, 0.81f, 0.19f, 0.5f, 0.3f, 0.51f, 0.85f, 0.09f, 0.0f, 0.0f, 0.88f, 0.0f, 0.21f, 0.0f, 0.5f, 1.0f, 0.46f, 0.81f, 0.5f, 0.0f, 0.27f, 0.5f);
+ fillpatch(i++, "Analog Bass 2", 1.0f, 0.25f, 0.2f, 0.72f, 0.19f, 0.86f, 0.48f, 0.43f, 0.94f, 0.0f, 0.8f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.61f, 1.0f, 0.32f, 0.81f, 0.5f, 0.0f, 0.27f, 0.5f);
+ fillpatch(i++, "Low Pulses", 0.97f, 0.26f, 0.3f, 0.0f, 0.35f, 0.5f, 0.8f, 0.4f, 0.52f, 0.0f, 0.5f, 0.0f, 0.77f, 0.0f, 0.25f, 0.0f, 0.5f, 1.0f, 0.3f, 0.81f, 0.16f, 0.0f, 0.0f, 0.5f);
+ fillpatch(i++, "Sine Infra-Bass", 0.0f, 0.25f, 0.5f, 0.65f, 0.35f, 0.5f, 0.33f, 0.76f, 0.53f, 0.0f, 0.5f, 0.0f, 0.3f, 0.0f, 0.25f, 0.0f, 0.55f, 0.25f, 0.3f, 0.81f, 0.52f, 0.0f, 0.14f, 0.5f);
+ fillpatch(i++, "Wobble Bass [SA]", 1.0f, 0.26f, 0.22f, 0.64f, 0.82f, 0.59f, 0.72f, 0.47f, 0.34f, 0.34f, 0.82f, 0.2f, 0.69f, 1.0f, 0.15f, 0.09f, 0.5f, 1.0f, 0.07f, 0.81f, 0.46f, 0.0f, 0.24f, 0.5f);
+ fillpatch(i++, "Squelch Bass", 1.0f, 0.26f, 0.22f, 0.71f, 0.35f, 0.5f, 0.67f, 0.7f, 0.26f, 0.0f, 0.5f, 0.48f, 0.69f, 1.0f, 0.15f, 0.0f, 0.5f, 1.0f, 0.07f, 0.81f, 0.46f, 0.0f, 0.24f, 0.5f);
+ fillpatch(i++, "Rubber Bass [ZF]", 0.49f, 0.25f, 0.66f, 0.81f, 0.35f, 0.5f, 0.36f, 0.15f, 0.75f, 0.2f, 0.5f, 0.0f, 0.38f, 0.0f, 0.25f, 0.0f, 0.6f, 1.0f, 0.22f, 0.19f, 0.5f, 0.0f, 0.17f, 0.5f);
+ fillpatch(i++, "Soft Pick Bass", 0.37f, 0.51f, 0.77f, 0.71f, 0.22f, 0.5f, 0.33f, 0.47f, 0.71f, 0.16f, 0.59f, 0.0f, 0.0f, 0.0f, 0.25f, 0.04f, 0.58f, 0.0f, 0.22f, 0.15f, 0.44f, 0.33f, 0.15f, 0.5f);
+ fillpatch(i++, "Fretless Bass", 0.5f, 0.51f, 0.17f, 0.8f, 0.34f, 0.5f, 0.51f, 0.0f, 0.58f, 0.0f, 0.67f, 0.0f, 0.09f, 0.0f, 0.25f, 0.2f, 0.85f, 0.0f, 0.3f, 0.81f, 0.7f, 0.0f, 0.0f, 0.5f);
+ fillpatch(i++, "Whistler", 0.23f, 0.51f, 0.38f, 0.0f, 0.35f, 0.5f, 0.33f, 1.0f, 0.5f, 0.0f, 0.5f, 0.0f, 0.29f, 0.0f, 0.25f, 0.68f, 0.39f, 0.58f, 0.36f, 0.81f, 0.64f, 0.38f, 0.92f, 0.5f);
+ fillpatch(i++, "Very Soft Pad", 0.39f, 0.51f, 0.27f, 0.38f, 0.12f, 0.5f, 0.35f, 0.78f, 0.5f, 0.0f, 0.5f, 0.0f, 0.3f, 0.0f, 0.25f, 0.35f, 0.5f, 0.8f, 0.7f, 0.81f, 0.5f, 0.0f, 0.5f, 0.5f);
+ fillpatch(i++, "Pizzicato", 0.0f, 0.25f, 0.5f, 0.0f, 0.35f, 0.5f, 0.23f, 0.2f, 0.75f, 0.0f, 0.5f, 0.0f, 0.22f, 0.0f, 0.25f, 0.0f, 0.47f, 0.0f, 0.3f, 0.81f, 0.5f, 0.8f, 0.5f, 0.5f);
+ fillpatch(i++, "Synth Strings", 1.0f, 0.51f, 0.24f, 0.0f, 0.0f, 0.35f, 0.42f, 0.26f, 0.75f, 0.14f, 0.69f, 0.0f, 0.67f, 0.55f, 0.97f, 0.82f, 0.7f, 1.0f, 0.42f, 0.84f, 0.67f, 0.3f, 0.47f, 0.5f);
+ fillpatch(i++, "Synth Strings 2", 0.75f, 0.51f, 0.29f, 0.0f, 0.49f, 0.5f, 0.55f, 0.16f, 0.69f, 0.08f, 0.2f, 0.76f, 0.29f, 0.76f, 1.0f, 0.46f, 0.8f, 1.0f, 0.39f, 0.79f, 0.27f, 0.0f, 0.68f, 0.5f);
+ fillpatch(i++, "Leslie Organ", 0.0f, 0.5f, 0.53f, 0.0f, 0.13f, 0.39f, 0.38f, 0.74f, 0.54f, 0.2f, 0.0f, 0.0f, 0.55f, 0.52f, 0.31f, 0.0f, 0.17f, 0.73f, 0.28f, 0.87f, 0.24f, 0.0f, 0.29f, 0.5f);
+ fillpatch(i++, "Click Organ", 0.5f, 0.77f, 0.52f, 0.0f, 0.35f, 0.5f, 0.44f, 0.5f, 0.65f, 0.16f, 0.0f, 0.0f, 0.0f, 0.18f, 0.0f, 0.0f, 0.75f, 0.8f, 0.0f, 0.81f, 0.49f, 0.0f, 0.44f, 0.5f);
+ fillpatch(i++, "Hard Organ", 0.89f, 0.91f, 0.37f, 0.0f, 0.35f, 0.5f, 0.51f, 0.62f, 0.54f, 0.0f, 0.0f, 0.0f, 0.37f, 0.0f, 1.0f, 0.04f, 0.08f, 0.72f, 0.04f, 0.77f, 0.49f, 0.0f, 0.58f, 0.5f);
+ fillpatch(i++, "Bass Clarinet", 1.0f, 0.51f, 0.51f, 0.37f, 0.0f, 0.5f, 0.51f, 0.1f, 0.5f, 0.11f, 0.5f, 0.0f, 0.0f, 0.0f, 0.25f, 0.35f, 0.65f, 0.65f, 0.32f, 0.79f, 0.49f, 0.2f, 0.35f, 0.5f);
+ fillpatch(i++, "Trumpet", 0.0f, 0.51f, 0.51f, 0.82f, 0.06f, 0.5f, 0.57f, 0.0f, 0.32f, 0.15f, 0.5f, 0.21f, 0.15f, 0.0f, 0.25f, 0.24f, 0.6f, 0.8f, 0.1f, 0.75f, 0.55f, 0.25f, 0.69f, 0.5f);
+ fillpatch(i++, "Soft Horn", 0.12f, 0.9f, 0.67f, 0.0f, 0.35f, 0.5f, 0.5f, 0.21f, 0.29f, 0.12f, 0.6f, 0.0f, 0.35f, 0.36f, 0.25f, 0.08f, 0.5f, 1.0f, 0.27f, 0.83f, 0.51f, 0.1f, 0.25f, 0.5f);
+ fillpatch(i++, "Brass Section", 0.43f, 0.76f, 0.23f, 0.0f, 0.28f, 0.36f, 0.5f, 0.0f, 0.59f, 0.0f, 0.5f, 0.24f, 0.16f, 0.91f, 0.08f, 0.17f, 0.5f, 0.8f, 0.45f, 0.81f, 0.5f, 0.0f, 0.58f, 0.5f);
+ fillpatch(i++, "Synth Brass", 0.4f, 0.51f, 0.25f, 0.0f, 0.3f, 0.28f, 0.39f, 0.15f, 0.75f, 0.0f, 0.5f, 0.39f, 0.3f, 0.82f, 0.25f, 0.33f, 0.74f, 0.76f, 0.41f, 0.81f, 0.47f, 0.23f, 0.5f, 0.5f);
+ fillpatch(i++, "Detuned Syn Brass [ZF]", 0.68f, 0.5f, 0.93f, 0.0f, 0.31f, 0.62f, 0.26f, 0.07f, 0.85f, 0.0f, 0.66f, 0.0f, 0.83f, 0.0f, 0.05f, 0.0f, 0.75f, 0.54f, 0.32f, 0.76f, 0.37f, 0.29f, 0.56f, 0.5f);
+ fillpatch(i++, "Power PWM", 1.0f, 0.27f, 0.22f, 0.0f, 0.35f, 0.5f, 0.82f, 0.13f, 0.75f, 0.0f, 0.0f, 0.24f, 0.3f, 0.88f, 0.34f, 0.0f, 0.5f, 1.0f, 0.48f, 0.71f, 0.37f, 0.0f, 0.35f, 0.5f);
+ fillpatch(i++, "Water Velocity [SA]", 0.76f, 0.51f, 0.35f, 0.0f, 0.49f, 0.5f, 0.87f, 0.67f, 1.0f, 0.32f, 0.09f, 0.95f, 0.56f, 0.72f, 1.0f, 0.04f, 0.76f, 0.11f, 0.46f, 0.88f, 0.72f, 0.0f, 0.38f, 0.5f);
+ fillpatch(i++, "Ghost [SA]", 0.75f, 0.51f, 0.24f, 0.45f, 0.16f, 0.48f, 0.38f, 0.58f, 0.75f, 0.16f, 0.81f, 0.0f, 0.3f, 0.4f, 0.31f, 0.37f, 0.5f, 1.0f, 0.54f, 0.85f, 0.83f, 0.43f, 0.46f, 0.5f);
+ fillpatch(i++, "Soft E.Piano", 0.31f, 0.51f, 0.43f, 0.0f, 0.35f, 0.5f, 0.34f, 0.26f, 0.53f, 0.0f, 0.63f, 0.0f, 0.22f, 0.0f, 0.39f, 0.0f, 0.8f, 0.0f, 0.44f, 0.81f, 0.51f, 0.0f, 0.5f, 0.5f);
+ fillpatch(i++, "Thumb Piano", 0.72f, 0.82f, 1.0f, 0.0f, 0.35f, 0.5f, 0.37f, 0.47f, 0.54f, 0.0f, 0.5f, 0.0f, 0.45f, 0.0f, 0.39f, 0.0f, 0.39f, 0.0f, 0.48f, 0.81f, 0.6f, 0.0f, 0.71f, 0.5f);
+ fillpatch(i++, "Steel Drums [ZF]", 0.81f, 0.76f, 0.19f, 0.0f, 0.18f, 0.7f, 0.4f, 0.3f, 0.54f, 0.17f, 0.4f, 0.0f, 0.42f, 0.23f, 0.47f, 0.12f, 0.48f, 0.0f, 0.49f, 0.53f, 0.36f, 0.34f, 0.56f, 0.5f);
+
+ fillpatch(58, "Car Horn", 0.57f, 0.49f, 0.31f, 0.0f, 0.35f, 0.5f, 0.46f, 0.0f, 0.68f, 0.0f, 0.5f, 0.46f, 0.3f, 1.0f, 0.23f, 0.3f, 0.5f, 1.0f, 0.31f, 1.0f, 0.38f, 0.0f, 0.5f, 0.5f);
+ fillpatch(59, "Helicopter", 0.0f, 0.25f, 0.5f, 0.0f, 0.35f, 0.5f, 0.08f, 0.36f, 0.69f, 1.0f, 0.5f, 1.0f, 1.0f, 0.0f, 1.0f, 0.96f, 0.5f, 1.0f, 0.92f, 0.97f, 0.5f, 1.0f, 0.0f, 0.5f);
+ fillpatch(60, "Arctic Wind", 0.0f, 0.25f, 0.5f, 0.0f, 0.35f, 0.5f, 0.16f, 0.85f, 0.5f, 0.28f, 0.5f, 0.37f, 0.3f, 0.0f, 0.25f, 0.89f, 0.5f, 1.0f, 0.89f, 0.24f, 0.5f, 1.0f, 1.0f, 0.5f);
+ fillpatch(61, "Thip", 1.0f, 0.37f, 0.51f, 0.0f, 0.35f, 0.5f, 0.0f, 1.0f, 0.97f, 0.0f, 0.5f, 0.02f, 0.2f, 0.0f, 0.2f, 0.0f, 0.46f, 0.0f, 0.3f, 0.81f, 0.5f, 0.78f, 0.48f, 0.5f);
+ fillpatch(62, "Synth Tom", 0.0f, 0.25f, 0.5f, 0.0f, 0.76f, 0.94f, 0.3f, 0.33f, 0.76f, 0.0f, 0.68f, 0.0f, 0.59f, 0.0f, 0.59f, 0.1f, 0.5f, 0.0f, 0.5f, 0.81f, 0.5f, 0.7f, 0.0f, 0.5f);
+ fillpatch(63, "Squelchy Frog", 0.5f, 0.41f, 0.23f, 0.45f, 0.77f, 0.0f, 0.4f, 0.65f, 0.95f, 0.0f, 0.5f, 0.33f, 0.5f, 0.0f, 0.25f, 0.0f, 0.7f, 0.65f, 0.18f, 0.32f, 1.0f, 0.0f, 0.06f, 0.5f);
+
+ //for testing...
+ //fillpatch(0, "Monosynth", 0.62f, 0.26f, 0.51f, 0.79f, 0.35f, 0.54f, 0.64f, 0.39f, 0.51f, 0.65f, 0.0f, 0.07f, 0.52f, 0.24f, 0.84f, 0.13f, 0.3f, 0.76f, 0.21f, 0.58f, 0.3f, 0.0f, 0.36f, 0.5f);
+
+ setProgram(0);
+ }
+
+ if(audioMaster)
+ {
+ setNumInputs(0);
+ setNumOutputs(NOUTS);
+ canProcessReplacing();
+ isSynth();
+ setUniqueID("MDAj"); ///
+ }
+
+ //initialise...
+ for(long v=0; v<NVOICES; v++)
+ {
+ voice[v].dp = voice[v].dp2 = 1.0f;
+ voice[v].saw = voice[v].p = voice[v].p2 = 0.0f;
+ voice[v].env = voice[v].envd = voice[v].envl = 0.0f;
+ voice[v].fenv = voice[v].fenvd = voice[v].fenvl = 0.0f;
+ voice[v].f0 = voice[v].f1 = voice[v].f2 = 0.0f;
+ voice[v].note = 0;
+ }
+ notes[0] = EVENTS_DONE;
+ lfo = modwhl = filtwhl = press = fzip = 0.0f;
+ rezwhl = pbend = ipbend = 1.0f;
+ volume = 0.0005f;
+ K = mode = lastnote = sustain = activevoices = 0;
+ noise = 22222;
+
+ update();
+ suspend();
+}
+
+
+void mdaJX10::update() //parameter change
+{
+ double ifs = 1.0 / Fs;
+
+ mode = (long)(7.9f * param[3]);
+ noisemix = param[21] * param[21];
+ voltrim = (3.2f - param[0] - 1.5f * noisemix) * (1.5f - 0.5f * param[7]);
+ noisemix *= 0.06f;
+ oscmix = param[0];
+
+ semi = (float)floor(48.0f * param[1]) - 24.0f;
+ cent = 15.876f * param[2] - 7.938f;
+ cent = 0.1f * (float)floor(cent * cent * cent);
+ detune = (float)pow(1.059463094359f, - semi - 0.01f * cent);
+ tune = -23.376f - 2.0f * param[23] - 12.0f * (float)floor(param[22] * 4.9);
+ tune = Fs * (float)pow(1.059463094359f, tune);
+
+ vibrato = pwmdep = 0.2f * (param[20] - 0.5f) * (param[20] - 0.5f);
+ if(param[20]<0.5f) vibrato = 0.0f;
+
+ lfoHz = (float)exp(7.0f * param[19] - 4.0f);
+ dlfo = lfoHz * (float)(ifs * TWOPI * KMAX);
+
+ filtf = 8.0f * param[6] - 1.5f;
+ filtq = (1.0f - param[7]) * (1.0f - param[7]); ////// + 0.02f;
+ filtlfo = 2.5f * param[9] * param[9];
+ filtenv = 12.0f * param[8] - 6.0f;
+ filtvel = 0.1f * param[10] - 0.05f;
+ if(param[10]<0.05f) { veloff = 1; filtvel = 0; } else veloff = 0;
+
+ att = 1.0f - (float)exp(-ifs * exp(5.5 - 7.5 * param[15]));
+ dec = 1.0f - (float)exp(-ifs * exp(5.5 - 7.5 * param[16]));
+ sus = param[17];
+ rel = 1.0f - (float)exp(-ifs * exp(5.5 - 7.5 * param[18]));
+ if(param[18]<0.01f) rel = 0.1f; //extra fast release
+
+ ifs *= KMAX; //lower update rate...
+
+ fatt = 1.0f - (float)exp(-ifs * exp(5.5 - 7.5 * param[11]));
+ fdec = 1.0f - (float)exp(-ifs * exp(5.5 - 7.5 * param[12]));
+ fsus = param[13] * param[13];
+ frel = 1.0f - (float)exp(-ifs * exp(5.5 - 7.5 * param[14]));
+
+ if(param[4]<0.02f) glide = 1.0f; else
+ glide = 1.0f - (float)exp(-ifs * exp(6.0 - 7.0 * param[4]));
+ glidedisp = (6.604f * param[5] - 3.302f);
+ glidedisp *= glidedisp * glidedisp;
+}
+
+
+void mdaJX10::setSampleRate(float sampleRate)
+{
+ AudioEffectX::setSampleRate(sampleRate);
+ Fs = sampleRate;
+
+ dlfo = lfoHz * (float)(TWOPI * KMAX) / Fs;
+}
+
+
+void mdaJX10::resume()
+{
+ DECLARE_LVZ_DEPRECATED (wantEvents) ();
+}
+
+
+void mdaJX10::suspend() //Used by Logic (have note off code in 3 places now...)
+{
+ for(long v=0; v<NVOICES; v++)
+ {
+ voice[v].envl = voice[v].env = 0.0f;
+ voice[v].envd = 0.99f;
+ voice[v].note = 0;
+ voice[v].f0 = voice[v].f1 = voice[v].f2 = 0.0f;
+ }
+}
+
+
+mdaJX10::~mdaJX10() //destroy any buffers...
+{
+ if(programs) delete[] programs;
+}
+
+
+void mdaJX10::setProgram(LvzInt32 program)
+{
+ long i;
+
+ mdaJX10Program *p = &programs[program];
+ curProgram = program;
+ for(i=0; i<NPARAMS; i++) param[i] = p->param[i];
+ update();
+} //may want all notes off here - but this stops use of patches as snapshots!
+
+
+void mdaJX10::setParameter(LvzInt32 index, float value)
+{
+ mdaJX10Program *p = &programs[curProgram];
+ param[index] = p->param[index] = value;
+ update();
+
+ ///if(editor) editor->postUpdate();
+}
+
+
+void mdaJX10::fillpatch(long p, const char *name,
+ float p0, float p1, float p2, float p3, float p4, float p5,
+ float p6, float p7, float p8, float p9, float p10, float p11,
+ float p12, float p13, float p14, float p15, float p16, float p17,
+ float p18, float p19, float p20, float p21, float p22, float p23)
+{
+ strcpy(programs[p].name, name);
+ programs[p].param[0] = p0; programs[p].param[1] = p1;
+ programs[p].param[2] = p2; programs[p].param[3] = p3;
+ programs[p].param[4] = p4; programs[p].param[5] = p5;
+ programs[p].param[6] = p6; programs[p].param[7] = p7;
+ programs[p].param[8] = p8; programs[p].param[9] = p9;
+ programs[p].param[10] = p10; programs[p].param[11] = p11;
+ programs[p].param[12] = p12; programs[p].param[13] = p13;
+ programs[p].param[14] = p14; programs[p].param[15] = p15;
+ programs[p].param[16] = p16; programs[p].param[17] = p17;
+ programs[p].param[18] = p18; programs[p].param[19] = p19;
+ programs[p].param[20] = p20; programs[p].param[21] = p21;
+ programs[p].param[22] = p22; programs[p].param[23] = p23;
+}
+
+
+float mdaJX10::getParameter(LvzInt32 index) { return param[index]; }
+void mdaJX10::setProgramName(char *name) { strcpy(programs[curProgram].name, name); }
+void mdaJX10::getProgramName(char *name) { strcpy(name, programs[curProgram].name); }
+void mdaJX10::setBlockSize(LvzInt32 blockSize) { AudioEffectX::setBlockSize(blockSize); }
+bool mdaJX10::getEffectName(char* name) { strcpy(name, "mda JX10 Synth"); return true; }
+bool mdaJX10::getVendorString(char* text) { strcpy(text, "maxim digital audio"); return true; }
+bool mdaJX10::getProductString(char* text) { strcpy(text, "mda JX10 Synth"); return true; }
+
+
+bool mdaJX10::getOutputProperties(LvzInt32 index, LvzPinProperties* properties)
+{
+ if(index<NOUTS)
+ {
+ sprintf(properties->label, "JX10%d", index + 1);
+ properties->flags = kLvzPinIsActive;
+ if(index<2) properties->flags |= kLvzPinIsStereo; //make channel 1+2 stereo
+ return true;
+ }
+ return false;
+}
+
+
+bool mdaJX10::getProgramNameIndexed(LvzInt32 category, LvzInt32 index, char* text)
+{
+ if(index<NPROGS)
+ {
+ strcpy(text, programs[index].name);
+ return true;
+ }
+ return false;
+}
+
+
+bool mdaJX10::copyProgram(LvzInt32 destination)
+{
+ if(destination<NPROGS)
+ {
+ programs[destination] = programs[curProgram];
+ return true;
+ }
+ return false;
+}
+
+
+LvzInt32 mdaJX10::canDo(char* text)
+{
+ if(!strcmp (text, "receiveLvzEvents")) return 1;
+ if(!strcmp (text, "receiveLvzMidiEvent")) return 1;
+ return -1;
+}
+
+
+void mdaJX10::getParameterName(LvzInt32 index, char *label)
+{
+ switch (index)
+ {
+ case 0: strcpy(label, "OSC Mix "); break;
+ case 1: strcpy(label, "OSC Tune"); break;
+ case 2: strcpy(label, "OSC Fine"); break;
+
+ case 3: strcpy(label, "Glide "); break;
+ case 4: strcpy(label, "Gld Rate"); break;
+ case 5: strcpy(label, "Gld Bend"); break;
+
+ case 6: strcpy(label, "VCF Freq"); break;
+ case 7: strcpy(label, "VCF Reso"); break;
+ case 8: strcpy(label, "VCF Env "); break;
+
+ case 9: strcpy(label, "VCF LFO "); break;
+ case 10: strcpy(label, "VCF Vel "); break;
+ case 11: strcpy(label, "VCF Att "); break;
+
+ case 12: strcpy(label, "VCF Dec "); break;
+ case 13: strcpy(label, "VCF Sus "); break;
+ case 14: strcpy(label, "VCF Rel "); break;
+
+ case 15: strcpy(label, "ENV Att "); break;
+ case 16: strcpy(label, "ENV Dec "); break;
+ case 17: strcpy(label, "ENV Sus "); break;
+
+ case 18: strcpy(label, "ENV Rel "); break;
+ case 19: strcpy(label, "LFO Rate"); break;
+ case 20: strcpy(label, "Vibrato "); break;
+
+ case 21: strcpy(label, "Noise "); break;
+ case 22: strcpy(label, "Octave "); break;
+ default: strcpy(label, "Tuning ");
+ }
+}
+
+
+void mdaJX10::getParameterDisplay(LvzInt32 index, char *text)
+{
+ char string[16];
+
+ switch(index)
+ {
+ case 0: sprintf(string, "%4.0f:%2.0f", 100.0-50.0f*param[index], 50.0f*param[index]); break;
+ case 1: sprintf(string, "%.0f", semi); break;
+ case 2: sprintf(string, "%.1f", cent); break;
+ case 3: switch(mode)
+ { case 0:
+ case 1: strcpy(string, "POLY "); break;
+ case 2: strcpy(string, "P-LEGATO"); break;
+ case 3: strcpy(string, "P-GLIDE "); break;
+ case 4:
+ case 5: strcpy(string, "MONO "); break;
+ case 6: strcpy(string, "M-LEGATO"); break;
+ default: strcpy(string, "M-GLIDE "); break; } break;
+ case 5: sprintf(string, "%.2f", glidedisp); break;
+ case 6: sprintf(string, "%.1f", 100.0f * param[index]); break;
+ case 8:
+ case 23: sprintf(string, "%.1f", 200.0f * param[index] - 100.0f); break;
+ case 10: if(param[index]<0.05f) strcpy(string, " OFF ");
+ else sprintf(string, "%.0f", 200.0f * param[index] - 100.0f); break;
+ case 19: sprintf(string, "%.3f", lfoHz); break;
+ case 20: if(param[index]<0.5f) sprintf(string, "PWM %3.0f", 100.0f - 200.0f * param[index]);
+ else sprintf(string, "%7.0f", 200.0f * param[index] - 100.0f); break;
+ case 22: sprintf(string, "%ld", (long)(param[index] * 4.9f) - 2); break;
+ default: sprintf(string, "%.0f", 100.0f * param[index]);
+ }
+ string[8] = 0;
+ strcpy(text, (char *)string);
+}
+
+
+void mdaJX10::getParameterLabel(LvzInt32 index, char *label)
+{
+ switch(index)
+ {
+ case 1:
+ case 5: strcpy(label, " semi "); break;
+ case 2:
+ case 23: strcpy(label, " cent "); break;
+ case 3:
+ case 22: strcpy(label, " "); break;
+ case 19: strcpy(label, " Hz "); break;
+ default: strcpy(label, " % ");
+ }
+}
+
+
+void mdaJX10::process(float **inputs, float **outputs, LvzInt32 sampleFrames)
+{
+ float* out1 = outputs[0];
+ float* out2 = outputs[1];
+ long event=0, frame=0, frames, v;
+ float o, e, vib, pwm, pb=pbend, ipb=ipbend, gl=glide;
+ float x, y, hpf=0.997f, min=1.0f, w=0.0f, ww=noisemix;
+ float ff, fe=filtenv, fq=filtq * rezwhl, fx=1.97f-0.85f*fq, fz=fzip;
+ long k=K;
+ unsigned long r;
+
+ vib = (float)sin(lfo);
+ ff = filtf + filtwhl + (filtlfo + press) * vib; //have to do again here as way that
+ pwm = 1.0f + vib * (modwhl + pwmdep); //below triggers on k was too cheap!
+ vib = 1.0f + vib * (modwhl + vibrato);
+
+ if(activevoices>0 || notes[event]<sampleFrames)
+ {
+ while(frame<sampleFrames)
+ {
+ frames = notes[event++];
+ if(frames>sampleFrames) frames = sampleFrames;
+ frames -= frame;
+ frame += frames;
+
+ while(--frames>=0)
+ {
+ VOICE *V = voice;
+ o = 0.0f;
+
+ noise = (noise * 196314165) + 907633515;
+ r = (noise & 0x7FFFFF) + 0x40000000; //generate noise + fast convert to float
+ w = *(float *)&r;
+ w = ww * (w - 3.0f);
+
+ if(--k<0)
+ {
+ lfo += dlfo;
+ if(lfo>PI) lfo -= TWOPI;
+ vib = (float)sin(lfo);
+ ff = filtf + filtwhl + (filtlfo + press) * vib;
+ pwm = 1.0f + vib * (modwhl + pwmdep);
+ vib = 1.0f + vib * (modwhl + vibrato);
+ k = KMAX;
+ }
+
+ for(v=0; v<NVOICES; v++) //for each voice
+ {
+ e = V->env;
+ if(e > SILENCE)
+ { //Sinc-Loop Oscillator
+ x = V->p + V->dp;
+ if(x > min)
+ {
+ if(x > V->pmax)
+ {
+ x = V->pmax + V->pmax - x;
+ V->dp = -V->dp;
+ }
+ V->p = x;
+ x = V->sin0 * V->sinx - V->sin1; //sine osc
+ V->sin1 = V->sin0;
+ V->sin0 = x;
+ x = x / V->p;
+ }
+ else
+ {
+ V->p = x = - x;
+ V->dp = V->period * vib * pb; //set period for next cycle
+ V->pmax = (float)floor(0.5f + V->dp) - 0.5f;
+ V->dc = -0.5f * V->lev / V->pmax;
+ V->pmax *= PI;
+ V->dp = V->pmax / V->dp;
+ V->sin0 = V->lev * (float)sin(x);
+ V->sin1 = V->lev * (float)sin(x - V->dp);
+ V->sinx = 2.0f * (float)cos(V->dp);
+ if(x*x > .1f) x = V->sin0 / x; else x = V->lev; //was 0.01f;
+ }
+
+ y = V->p2 + V->dp2; //osc2
+ if(y > min)
+ {
+ if(y > V->pmax2)
+ {
+ y = V->pmax2 + V->pmax2 - y;
+ V->dp2 = -V->dp2;
+ }
+ V->p2 = y;
+ y = V->sin02 * V->sinx2 - V->sin12;
+ V->sin12 = V->sin02;
+ V->sin02 = y;
+ y = y / V->p2;
+ }
+ else
+ {
+ V->p2 = y = - y;
+ V->dp2 = V->period * V->detune * pwm * pb;
+ V->pmax2 = (float)floor(0.5f + V->dp2) - 0.5f;
+ V->dc2 = -0.5f * V->lev2 / V->pmax2;
+ V->pmax2 *= PI;
+ V->dp2 = V->pmax2 / V->dp2;
+ V->sin02 = V->lev2 * (float)sin(y);
+ V->sin12 = V->lev2 * (float)sin(y - V->dp2);
+ V->sinx2 = 2.0f * (float)cos(V->dp2);
+ if(y*y > .1f) y = V->sin02 / y; else y = V->lev2;
+ }
+ V->saw = V->saw * hpf + V->dc + x - V->dc2 - y; //integrated sinc = saw
+ x = V->saw + w;
+ V->env += V->envd * (V->envl - V->env);
+
+ if(k==KMAX) //filter freq update at LFO rate
+ {
+ if((V->env+V->envl)>3.0f) { V->envd=dec; V->envl=sus; } //envelopes
+ V->fenv += V->fenvd * (V->fenvl - V->fenv);
+ if((V->fenv+V->fenvl)>3.0f) { V->fenvd=fdec; V->fenvl=fsus; }
+
+ fz += 0.005f * (ff - fz); //filter zipper noise filter
+ y = V->fc * (float)exp(fz + fe * V->fenv) * ipb; //filter cutoff
+ if(y<0.005f) y=0.005f;
+ V->ff = y;
+
+ V->period += gl * (V->target - V->period); //glide
+ if(V->target < V->period) V->period += gl * (V->target - V->period);
+ }
+
+ if(V->ff > fx) V->ff = fx; //stability limit
+
+ V->f0 += V->ff * V->f1; //state-variable filter
+ V->f1 -= V->ff * (V->f0 + fq * V->f1 - x - V->f2);
+ V->f1 -= 0.2f * V->f1 * V->f1 * V->f1; //soft limit //was 0.08f
+ V->f2 = x;
+
+ o += V->env * V->f0;
+ }
+ V++;
+ }
+
+ *out1++ += o;
+ *out2++ += o;
+ }
+
+ if(frame<sampleFrames)
+ {
+ long note = notes[event++];
+ long vel = notes[event++];
+ noteOn(note, vel);
+ }
+ }
+
+ activevoices = NVOICES;
+ for(v=0; v<NVOICES; v++)
+ {
+ if(voice[v].env<SILENCE) //choke voices
+ {
+ voice[v].env = voice[v].envl = 0.0f;
+ voice[v].f0 = voice[v].f1 = voice[v].f2 = 0.0f;
+ activevoices--;
+ }
+ }
+ }
+ notes[0] = EVENTS_DONE; //mark events buffer as done
+ fzip = fz;
+ K = k;
+}
+
+
+void mdaJX10::processReplacing(float **inputs, float **outputs, LvzInt32 sampleFrames)
+{
+ float* out1 = outputs[0];
+ float* out2 = outputs[1];
+ long event=0, frame=0, frames, v;
+ float o, e, vib, pwm, pb=pbend, ipb=ipbend, gl=glide;
+ float x, y, hpf=0.997f, min=1.0f, w=0.0f, ww=noisemix;
+ float ff, fe=filtenv, fq=filtq * rezwhl, fx=1.97f-0.85f*fq, fz=fzip;
+ long k=K;
+ unsigned long r;
+
+ vib = (float)sin(lfo);
+ ff = filtf + filtwhl + (filtlfo + press) * vib; //have to do again here as way that
+ pwm = 1.0f + vib * (modwhl + pwmdep); //below triggers on k was too cheap!
+ vib = 1.0f + vib * (modwhl + vibrato);
+
+ if(activevoices>0 || notes[event]<sampleFrames)
+ {
+ while(frame<sampleFrames)
+ {
+ frames = notes[event++];
+ if(frames>sampleFrames) frames = sampleFrames;
+ frames -= frame;
+ frame += frames;
+
+ while(--frames>=0)
+ {
+ VOICE *V = voice;
+ o = 0.0f;
+
+ noise = (noise * 196314165) + 907633515;
+ r = (noise & 0x7FFFFF) + 0x40000000; //generate noise + fast convert to float
+ w = *(float *)&r;
+ w = ww * (w - 3.0f);
+
+ if(--k<0)
+ {
+ lfo += dlfo;
+ if(lfo>PI) lfo -= TWOPI;
+ vib = (float)sin(lfo);
+ ff = filtf + filtwhl + (filtlfo + press) * vib;
+ pwm = 1.0f + vib * (modwhl + pwmdep);
+ vib = 1.0f + vib * (modwhl + vibrato);
+ k = KMAX;
+ }
+
+ for(v=0; v<NVOICES; v++) //for each voice
+ {
+ e = V->env;
+ if(e > SILENCE)
+ { //Sinc-Loop Oscillator
+ x = V->p + V->dp;
+ if(x > min)
+ {
+ if(x > V->pmax)
+ {
+ x = V->pmax + V->pmax - x;
+ V->dp = -V->dp;
+ }
+ V->p = x;
+ x = V->sin0 * V->sinx - V->sin1; //sine osc
+ V->sin1 = V->sin0;
+ V->sin0 = x;
+ x = x / V->p;
+ }
+ else
+ {
+ V->p = x = - x;
+ V->dp = V->period * vib * pb; //set period for next cycle
+ V->pmax = (float)floor(0.5f + V->dp) - 0.5f;
+ V->dc = -0.5f * V->lev / V->pmax;
+ V->pmax *= PI;
+ V->dp = V->pmax / V->dp;
+ V->sin0 = V->lev * (float)sin(x);
+ V->sin1 = V->lev * (float)sin(x - V->dp);
+ V->sinx = 2.0f * (float)cos(V->dp);
+ if(x*x > .1f) x = V->sin0 / x; else x = V->lev; //was 0.01f;
+ }
+
+ y = V->p2 + V->dp2; //osc2
+ if(y > min)
+ {
+ if(y > V->pmax2)
+ {
+ y = V->pmax2 + V->pmax2 - y;
+ V->dp2 = -V->dp2;
+ }
+ V->p2 = y;
+ y = V->sin02 * V->sinx2 - V->sin12;
+ V->sin12 = V->sin02;
+ V->sin02 = y;
+ y = y / V->p2;
+ }
+ else
+ {
+ V->p2 = y = - y;
+ V->dp2 = V->period * V->detune * pwm * pb;
+ V->pmax2 = (float)floor(0.5f + V->dp2) - 0.5f;
+ V->dc2 = -0.5f * V->lev2 / V->pmax2;
+ V->pmax2 *= PI;
+ V->dp2 = V->pmax2 / V->dp2;
+ V->sin02 = V->lev2 * (float)sin(y);
+ V->sin12 = V->lev2 * (float)sin(y - V->dp2);
+ V->sinx2 = 2.0f * (float)cos(V->dp2);
+ if(y*y > .1f) y = V->sin02 / y; else y = V->lev2;
+ }
+ V->saw = V->saw * hpf + V->dc + x - V->dc2 - y; //integrated sinc = saw
+ x = V->saw + w;
+ V->env += V->envd * (V->envl - V->env);
+
+ if(k==KMAX) //filter freq update at LFO rate
+ {
+ if((V->env+V->envl)>3.0f) { V->envd=dec; V->envl=sus; } //envelopes
+ V->fenv += V->fenvd * (V->fenvl - V->fenv);
+ if((V->fenv+V->fenvl)>3.0f) { V->fenvd=fdec; V->fenvl=fsus; }
+
+ fz += 0.005f * (ff - fz); //filter zipper noise filter
+ y = V->fc * (float)exp(fz + fe * V->fenv) * ipb; //filter cutoff
+ if(y<0.005f) y=0.005f;
+ V->ff = y;
+
+ V->period += gl * (V->target - V->period); //glide
+ if(V->target < V->period) V->period += gl * (V->target - V->period);
+ }
+
+ if(V->ff > fx) V->ff = fx; //stability limit
+
+ V->f0 += V->ff * V->f1; //state-variable filter
+ V->f1 -= V->ff * (V->f0 + fq * V->f1 - x - V->f2);
+ V->f1 -= 0.2f * V->f1 * V->f1 * V->f1; //soft limit
+
+ V->f2 = x;
+
+ o += V->env * V->f0;
+ }
+ V++;
+ }
+
+ *out1++ = o;
+ *out2++ = o;
+ }
+
+ if(frame<sampleFrames)
+ {
+ long note = notes[event++];
+ long vel = notes[event++];
+ noteOn(note, vel);
+ }
+ }
+
+ activevoices = NVOICES;
+ for(v=0; v<NVOICES; v++)
+ {
+ if(voice[v].env<SILENCE) //choke voices
+ {
+ voice[v].env = voice[v].envl = 0.0f;
+ voice[v].f0 = voice[v].f1 = voice[v].f2 = 0.0f;
+ activevoices--;
+ }
+ }
+ }
+ else //empty block
+ {
+ while(--sampleFrames >= 0)
+ {
+ *out1++ = 0.0f;
+ *out2++ = 0.0f;
+ }
+ }
+ notes[0] = EVENTS_DONE; //mark events buffer as done
+ fzip = fz;
+ K = k;
+}
+
+
+void mdaJX10::noteOn(long note, long velocity)
+{
+ float p, l=100.0f; //louder than any envelope!
+ long v=0, tmp, held=0;
+
+ if(velocity>0) //note on
+ {
+ if(veloff) velocity = 80;
+
+ if(mode & 4) //monophonic
+ {
+ if(voice[0].note > 0) //legato pitch change
+ {
+ for(tmp=(NVOICES-1); tmp>0; tmp--) //queue any held notes
+ {
+ voice[tmp].note = voice[tmp - 1].note;
+ }
+ p = tune * (float)exp(-0.05776226505 * ((double)note + ANALOG * (double)v));
+ while(p<3.0f || (p * detune)<3.0f) p += p;
+ voice[v].target = p;
+ if((mode & 2)==0) voice[v].period = p;
+ voice[v].fc = (float)exp(filtvel * (float)(velocity - 64)) / p;
+ voice[v].env += SILENCE + SILENCE; ///was missed out below if returned?
+ voice[v].note = note;
+ return;
+ }
+ }
+ else //polyphonic
+ {
+ for(tmp=0; tmp<NVOICES; tmp++) //replace quietest voice not in attack
+ {
+ if(voice[tmp].note > 0) held++;
+ if(voice[tmp].env<l && voice[tmp].envl<2.0f) { l=voice[tmp].env; v=tmp; }
+ }
+ }
+ p = tune * (float)exp(-0.05776226505 * ((double)note + ANALOG * (double)v));
+ while(p<3.0f || (p * detune)<3.0f) p += p;
+ voice[v].target = p;
+ voice[v].detune = detune;
+
+ tmp = 0;
+ if(mode & 2)
+ {
+ if((mode & 1) || held) tmp = note - lastnote; //glide
+ }
+ voice[v].period = p * (float)pow(1.059463094359, (double)tmp - glidedisp);
+ if(voice[v].period<3.0f) voice[v].period = 3.0f; //limit min period
+
+ voice[v].note = lastnote = note;
+
+ voice[v].fc = (float)exp(filtvel * (float)(velocity - 64)) / p; //filter tracking
+
+ voice[v].lev = voltrim * volume * (0.004f * (float)((velocity + 64) * (velocity + 64)) - 8.0f);
+ voice[v].lev2 = voice[v].lev * oscmix;
+
+ if(param[20]<0.5f) //force 180 deg phase difference for PWM
+ {
+ if(voice[v].dp>0.0f)
+ {
+ p = voice[v].pmax + voice[v].pmax - voice[v].p;
+ voice[v].dp2 = -voice[v].dp;
+ }
+ else
+ {
+ p = voice[v].p;
+ voice[v].dp2 = voice[v].dp;
+ }
+ voice[v].p2 = voice[v].pmax2 = p + PI * voice[v].period;
+
+ voice[v].dc2 = 0.0f;
+ voice[v].sin02 = voice[v].sin12 = voice[v].sinx2 = 0.0f;
+ }
+
+ if(mode & 4) //monophonic retriggering
+ {
+ voice[v].env += SILENCE + SILENCE;
+ }
+ else
+ {
+ //if(param[15] < 0.28f)
+ //{
+ // voice[v].f0 = voice[v].f1 = voice[v].f2 = 0.0f; //reset filter
+ // voice[v].env = SILENCE + SILENCE;
+ // voice[v].fenv = 0.0f;
+ //}
+ //else
+ voice[v].env += SILENCE + SILENCE; //anti-glitching trick
+ }
+ voice[v].envl = 2.0f;
+ voice[v].envd = att;
+ voice[v].fenvl = 2.0f;
+ voice[v].fenvd = fatt;
+ }
+ else //note off
+ {
+ if((mode & 4) && (voice[0].note==note)) //monophonic (and current note)
+ {
+ for(v=(NVOICES-1); v>0; v--)
+ {
+ if(voice[v].note>0) held = v; //any other notes queued?
+ }
+ if(held>0)
+ {
+ voice[v].note = voice[held].note;
+ voice[held].note = 0;
+
+ p = tune * (float)exp(-0.05776226505 * ((double)voice[v].note + ANALOG * (double)v));
+ while(p<3.0f || (p * detune)<3.0f) p += p;
+ voice[v].target = p;
+ if((mode & 2)==0) voice[v].period = p;
+ voice[v].fc = 1.0f / p;
+ }
+ else
+ {
+ voice[v].envl = 0.0f;
+ voice[v].envd = rel;
+ voice[v].fenvl = 0.0f;
+ voice[v].fenvd = frel;
+ voice[v].note = 0;
+ }
+ }
+ else //polyphonic
+ {
+ for(v=0; v<NVOICES; v++) if(voice[v].note==note) //any voices playing that note?
+ {
+ if(sustain==0)
+ {
+ voice[v].envl = 0.0f;
+ voice[v].envd = rel;
+ voice[v].fenvl = 0.0f;
+ voice[v].fenvd = frel;
+ voice[v].note = 0;
+ }
+ else voice[v].note = SUSTAIN;
+ }
+ }
+ }
+}
+
+
+LvzInt32 mdaJX10::processEvents(LvzEvents* ev)
+{
+ long npos=0;
+
+ for (long i=0; i<ev->numEvents; i++)
+ {
+ if((ev->events[i])->type != kLvzMidiType) continue;
+ LvzMidiEvent* event = (LvzMidiEvent*)ev->events[i];
+ char* midiData = event->midiData;
+
+ switch(midiData[0] & 0xf0) //status byte (all channels)
+ {
+ case 0x80: //note off
+ notes[npos++] = event->deltaFrames; //delta
+ notes[npos++] = midiData[1] & 0x7F; //note
+ notes[npos++] = 0; //vel
+ break;
+
+ case 0x90: //note on
+ notes[npos++] = event->deltaFrames; //delta
+ notes[npos++] = midiData[1] & 0x7F; //note
+ notes[npos++] = midiData[2] & 0x7F; //vel
+ break;
+
+ case 0xB0: //controller
+ switch(midiData[1])
+ {
+ case 0x01: //mod wheel
+ modwhl = 0.000005f * (float)(midiData[2] * midiData[2]);
+ break;
+ case 0x02: //filter +
+ case 0x4A:
+ filtwhl = 0.02f * (float)(midiData[2]);
+ break;
+ case 0x03: //filter -
+ filtwhl = -0.03f * (float)(midiData[2]);
+ break;
+
+ case 0x07: //volume
+ volume = 0.00000005f * (float)(midiData[2] * midiData[2]);
+ break;
+
+ case 0x10: //resonance
+ case 0x47:
+ rezwhl = 0.0065f * (float)(154 - midiData[2]);
+ break;
+
+ case 0x40: //sustain
+ sustain = midiData[2] & 0x40;
+ if(sustain==0)
+ {
+ notes[npos++] = event->deltaFrames;
+ notes[npos++] = SUSTAIN; //end all sustained notes
+ notes[npos++] = 0;
+ }
+ break;
+
+ default: //all notes off
+ if(midiData[1]>0x7A)
+ {
+ for(long v=0; v<NVOICES; v++)
+ {
+ voice[v].envl = voice[v].env = 0.0f;
+ voice[v].envd = 0.99f;
+ voice[v].note = 0;
+ //could probably reset some more stuff here for safety!
+ }
+ sustain = 0;
+ }
+ break;
+ }
+ break;
+
+ case 0xC0: //program change
+ if(midiData[1]<NPROGS) setProgram(midiData[1]);
+ break;
+
+ case 0xD0: //channel aftertouch
+ press = 0.00001f * (float)(midiData[1] * midiData[1]);
+ break;
+
+ case 0xE0: //pitch bend
+ ipbend = (float)exp(0.000014102 * (double)(midiData[1] + 128 * midiData[2] - 8192));
+ pbend = 1.0f / ipbend;
+ break;
+
+ default: break;
+ }
+
+ if(npos>EVENTBUFFER) npos -= 3; //discard events if buffer full!!
+ event++;
+ }
+ notes[npos] = EVENTS_DONE;
+ return 1;
+}
+