Added fixes from Synth_Dexed.

dev
Holger Wirtz 3 years ago
parent 37d25befec
commit c791c5b9cf
  1. 2
      third-party/Synth_Dexed/keywords.txt
  2. 4
      third-party/Synth_Dexed/src/PluginFx.cpp
  3. 262
      third-party/Synth_Dexed/src/dexed.cpp
  4. 13
      third-party/Synth_Dexed/src/dexed.h
  5. 14
      third-party/Synth_Dexed/src/fm_op_kernel.cpp

@ -18,7 +18,7 @@ activate KEYWORD2
deactivate KEYWORD2 deactivate KEYWORD2
getMonoMode KEYWORD2 getMonoMode KEYWORD2
setMonoMode KEYWORD2 setMonoMode KEYWORD2
setRefreshMode KEYWORD2 setNoteRefreshMode KEYWORD2
setMaxNotes KEYWORD2 setMaxNotes KEYWORD2
getMaxNotes KEYWORD2 getMaxNotes KEYWORD2
doRefreshVoice KEYWORD2 doRefreshVoice KEYWORD2

@ -48,11 +48,11 @@ inline static float tptlpupw(float & state , float inp , float cutoff , float sr
// return (param) * (max - min) + min; // return (param) * (max - min) + min;
//} //}
/* #ifdef USE_FX
static float logsc(float param, const float min, const float max, const float rolloff = 19.0f) { static float logsc(float param, const float min, const float max, const float rolloff = 19.0f) {
return ((EXP_FUNC(param * LOG_FUNC(rolloff + 1)) - 1.0f) / (rolloff)) * (max - min) + min; return ((EXP_FUNC(param * LOG_FUNC(rolloff + 1)) - 1.0f) / (rolloff)) * (max - min) + min;
} }
*/ #endif
PluginFx::PluginFx() { PluginFx::PluginFx() {
Cutoff = 1.0; Cutoff = 1.0;

@ -27,21 +27,21 @@
#include <limits.h> #include <limits.h>
#include <cstdlib> #include <cstdlib>
#include <stdint.h> #include <stdint.h>
#include "synth.h" #include <unistd.h>
#include "dexed.h" #include "dexed.h"
#include "synth.h"
#include "fm_core.h" #include "fm_core.h"
#include "exp2.h" #include "exp2.h"
#include "sin.h" #include "sin.h"
#include "freqlut.h" #include "freqlut.h"
#include "controllers.h" #include "controllers.h"
#include "PluginFx.h" #include "PluginFx.h"
#include <unistd.h>
#include "porta.h" #include "porta.h"
#include "compressor.h" #include "compressor.h"
Dexed::Dexed(uint8_t maxnotes, int rate) Dexed::Dexed(uint8_t maxnotes, int rate)
{ {
samplerate=float32_t(rate); samplerate = float32_t(rate);
Exp2::init(); Exp2::init();
Tanh::init(); Tanh::init();
@ -55,7 +55,7 @@ Dexed::Dexed(uint8_t maxnotes, int rate)
fx.init(rate); fx.init(rate);
engineMsfa = new FmCore; engineMsfa = new FmCore;
max_notes=maxnotes; max_notes = maxnotes;
currentNote = 0; currentNote = 0;
resetControllers(); resetControllers();
controllers.masterTune = 0; controllers.masterTune = 0;
@ -65,7 +65,7 @@ Dexed::Dexed(uint8_t maxnotes, int rate)
controllers.core = engineMsfa; controllers.core = engineMsfa;
lfo.reset(data + 137); lfo.reset(data + 137);
sustain = false; sustain = false;
voices=NULL; voices = NULL;
setMaxNotes(max_notes); setMaxNotes(max_notes);
setMonoMode(false); setMonoMode(false);
@ -76,7 +76,7 @@ Dexed::Dexed(uint8_t maxnotes, int rate)
#ifdef USE_DEXED_COMPRESSOR #ifdef USE_DEXED_COMPRESSOR
compressor = new Compressor(samplerate); compressor = new Compressor(samplerate);
use_compressor=false; use_compressor = false;
#endif #endif
} }
@ -95,33 +95,33 @@ Dexed::~Dexed()
void Dexed::setMaxNotes(uint8_t new_max_notes) void Dexed::setMaxNotes(uint8_t new_max_notes)
{ {
uint8_t i=0; uint8_t i = 0;
max_notes=constrain(max_notes,0,_MAX_NOTES); max_notes = constrain(max_notes, 0, _MAX_NOTES);
#ifdef DEBUG #if defined(MICRODEXED_VERSION) && defined(DEBUG)
Serial.print("Allocating memory for "); Serial.print("Allocating memory for ");
Serial.print(max_notes,DEC); Serial.print(max_notes, DEC);
Serial.println(" notes."); Serial.println(" notes.");
Serial.println(); Serial.println();
#endif #endif
if(voices) if (voices)
{ {
panic(); panic();
for (i = 0; i < max_notes; i++) for (i = 0; i < max_notes; i++)
{ {
if(voices[i].dx7_note) if (voices[i].dx7_note)
delete voices[i].dx7_note; delete voices[i].dx7_note;
} }
delete(voices); delete(voices);
} }
max_notes=constrain(new_max_notes,0,_MAX_NOTES); max_notes = constrain(new_max_notes, 0, _MAX_NOTES);
if(max_notes>0) if (max_notes > 0)
{ {
voices=new ProcessorVoice[max_notes]; // sizeof(ProcessorVoice) = 20 voices = new ProcessorVoice[max_notes]; // sizeof(ProcessorVoice) = 20
for (i = 0; i < max_notes; i++) for (i = 0; i < max_notes; i++)
{ {
voices[i].dx7_note = new Dx7Note; // sizeof(Dx7Note) = 692 voices[i].dx7_note = new Dx7Note; // sizeof(Dx7Note) = 692
@ -132,7 +132,7 @@ void Dexed::setMaxNotes(uint8_t new_max_notes)
} }
} }
else else
voices=NULL; voices = NULL;
} }
void Dexed::activate(void) void Dexed::activate(void)
@ -191,8 +191,8 @@ void Dexed::getSamples(float32_t* buffer, uint16_t n_samples)
fx.process(buffer, n_samples); // Needed for fx.Gain()!!! fx.process(buffer, n_samples); // Needed for fx.Gain()!!!
#if defined USE_DEXED_COMPRESSOR #if defined USE_DEXED_COMPRESSOR
if(use_compressor==true) if (use_compressor == true)
compressor->doCompression(buffer,n_samples); compressor->doCompression(buffer, n_samples);
#endif #endif
} }
@ -222,7 +222,7 @@ void Dexed::keydown(int16_t pitch, uint8_t velo) {
uint8_t note = currentNote; uint8_t note = currentNote;
uint8_t keydown_counter = 0; uint8_t keydown_counter = 0;
if (!monoMode && refreshMode) if (!monoMode && noteRefreshMode)
{ {
for (uint8_t i = 0; i < max_notes; i++) for (uint8_t i = 0; i < max_notes; i++)
{ {
@ -383,8 +383,8 @@ void Dexed::setMonoMode(bool mode) {
monoMode = mode; monoMode = mode;
} }
void Dexed::setRefreshMode(bool mode) { void Dexed::setNoteRefreshMode(bool mode) {
refreshMode = mode; noteRefreshMode = mode;
} }
void Dexed::setSustain(bool s) void Dexed::setSustain(bool s)
@ -393,6 +393,18 @@ void Dexed::setSustain(bool s)
return; return;
sustain = s; sustain = s;
if (!getSustain())
{
for (uint8_t note = 0; note < getMaxNotes(); note++)
{
if (voices[note].sustained && !voices[note].keydown)
{
voices[note].dx7_note->keyup();
voices[note].sustained = false;
}
}
}
} }
bool Dexed::getSustain(void) bool Dexed::getSustain(void)
@ -483,7 +495,7 @@ uint8_t Dexed::getNumNotesPlaying(void)
voices[i].live = false; voices[i].live = false;
voices[i].sustained = false; voices[i].sustained = false;
voices[i].keydown = false; voices[i].keydown = false;
#ifdef DEBUG #if defined(MICRODEXED_VERSION) && defined(DEBUG)
Serial.print(F("Shutdown voice: ")); Serial.print(F("Shutdown voice: "));
Serial.println(i, DEC); Serial.println(i, DEC);
#endif #endif
@ -563,7 +575,7 @@ bool Dexed::decodeVoice(uint8_t* new_data, uint8_t* encoded_data)
strncpy(dexed_voice_name, (char *)&encoded_data[118], sizeof(dexed_voice_name) - 1); strncpy(dexed_voice_name, (char *)&encoded_data[118], sizeof(dexed_voice_name) - 1);
dexed_voice_name[10] = '\0'; dexed_voice_name[10] = '\0';
#ifdef DEBUG #if defined(MICRODEXED_VERSION) && defined(DEBUG)
Serial.print(F("Voice [")); Serial.print(F("Voice ["));
Serial.print(dexed_voice_name); Serial.print(dexed_voice_name);
Serial.println(F("] decoded.")); Serial.println(F("] decoded."));
@ -632,6 +644,7 @@ void Dexed::setVoiceDataElement(uint8_t address, uint8_t value)
{ {
address = constrain(address, 0, NUM_VOICE_PARAMETERS); address = constrain(address, 0, NUM_VOICE_PARAMETERS);
data[address] = value; data[address] = value;
doRefreshVoice();
} }
uint8_t Dexed::getVoiceDataElement(uint8_t address) uint8_t Dexed::getVoiceDataElement(uint8_t address)
@ -642,14 +655,14 @@ uint8_t Dexed::getVoiceDataElement(uint8_t address)
void Dexed::loadVoiceParameters(uint8_t* new_data) void Dexed::loadVoiceParameters(uint8_t* new_data)
{ {
#ifdef DEBUG #if defined(MICRODEXED_VERSION) && defined(DEBUG)
char dexed_voice_name[11]; char dexed_voice_name[11];
#endif #endif
panic(); panic();
memcpy(&data, new_data, 155); memcpy(&data, new_data, 155);
doRefreshVoice(); doRefreshVoice();
#ifdef DEBUG #if defined(MICRODEXED_VERSION) && defined(DEBUG)
strncpy(dexed_voice_name, (char *)&new_data[145], sizeof(dexed_voice_name) - 1); strncpy(dexed_voice_name, (char *)&new_data[145], sizeof(dexed_voice_name) - 1);
dexed_voice_name[10] = '\0'; dexed_voice_name[10] = '\0';
@ -666,7 +679,7 @@ void Dexed::loadInitVoice(void)
void Dexed::setPBController(uint8_t pb_range, uint8_t pb_step) void Dexed::setPBController(uint8_t pb_range, uint8_t pb_step)
{ {
#ifdef DEBUG #if defined(MICRODEXED_VERSION) && defined(DEBUG)
Serial.println(F("Dexed::setPBController")); Serial.println(F("Dexed::setPBController"));
#endif #endif
@ -681,7 +694,7 @@ void Dexed::setPBController(uint8_t pb_range, uint8_t pb_step)
void Dexed::setMWController(uint8_t mw_range, uint8_t mw_assign, uint8_t mw_mode) void Dexed::setMWController(uint8_t mw_range, uint8_t mw_assign, uint8_t mw_mode)
{ {
#ifdef DEBUG #if defined(MICRODEXED_VERSION) && defined(DEBUG)
Serial.println(F("Dexed::setMWController")); Serial.println(F("Dexed::setMWController"));
#endif #endif
@ -698,7 +711,7 @@ void Dexed::setMWController(uint8_t mw_range, uint8_t mw_assign, uint8_t mw_mode
void Dexed::setFCController(uint8_t fc_range, uint8_t fc_assign, uint8_t fc_mode) void Dexed::setFCController(uint8_t fc_range, uint8_t fc_assign, uint8_t fc_mode)
{ {
#ifdef DEBUG #if defined(MICRODEXED_VERSION) && defined(DEBUG)
Serial.println(F("Dexed::setFCController")); Serial.println(F("Dexed::setFCController"));
#endif #endif
@ -715,7 +728,7 @@ void Dexed::setFCController(uint8_t fc_range, uint8_t fc_assign, uint8_t fc_mode
void Dexed::setBCController(uint8_t bc_range, uint8_t bc_assign, uint8_t bc_mode) void Dexed::setBCController(uint8_t bc_range, uint8_t bc_assign, uint8_t bc_mode)
{ {
#ifdef DEBUG #if defined(MICRODEXED_VERSION) && defined(DEBUG)
Serial.println(F("Dexed::setBCController")); Serial.println(F("Dexed::setBCController"));
#endif #endif
@ -732,7 +745,7 @@ void Dexed::setBCController(uint8_t bc_range, uint8_t bc_assign, uint8_t bc_mode
void Dexed::setATController(uint8_t at_range, uint8_t at_assign, uint8_t at_mode) void Dexed::setATController(uint8_t at_range, uint8_t at_assign, uint8_t at_mode)
{ {
#ifdef DEBUG #if defined(MICRODEXED_VERSION) && defined(DEBUG)
Serial.println(F("Dexed::setATController")); Serial.println(F("Dexed::setATController"));
#endif #endif
@ -747,11 +760,11 @@ void Dexed::setATController(uint8_t at_range, uint8_t at_assign, uint8_t at_mode
controllers.refresh(); controllers.refresh();
} }
void Dexed::setPortamentoMode(uint8_t portamento_mode, uint8_t portamento_glissando, uint8_t portamento_time) void Dexed::setPortamento(uint8_t portamento_mode, uint8_t portamento_glissando, uint8_t portamento_time)
{ {
portamento_mode = constrain(portamento_mode, 0, 1); portamento_mode = constrain(portamento_mode, 0, 1);
portamento_glissando = constrain(portamento_glissando, 0, 1); portamento_glissando = constrain(portamento_glissando, 0, 1);
portamento_mode = constrain(portamento_mode, 0, 99); portamento_time = constrain(portamento_time, 0, 99);
controllers.portamento_cc = portamento_time; controllers.portamento_cc = portamento_time;
controllers.portamento_enable_cc = portamento_mode > 63; controllers.portamento_enable_cc = portamento_mode > 63;
@ -766,6 +779,137 @@ void Dexed::setPortamentoMode(uint8_t portamento_mode, uint8_t portamento_glissa
controllers.refresh(); controllers.refresh();
} }
void Dexed::setPortamentoMode(uint8_t portamento_mode)
{
portamento_mode = constrain(portamento_mode, 0, 1);
controllers.portamento_enable_cc = portamento_mode > 63;
controllers.refresh();
}
uint8_t Dexed::getPortamentoMode(void)
{
return(controllers.portamento_enable_cc);
}
void Dexed::setPortamentoGlissando(uint8_t portamento_glissando)
{
portamento_glissando = constrain(portamento_glissando, 0, 1);
controllers.values_[kControllerPortamentoGlissando] = portamento_glissando;
controllers.refresh();
}
uint8_t Dexed::getPortamentoGlissando(void)
{
return(controllers.values_[kControllerPortamentoGlissando]);
}
void Dexed::setPortamentoTime(uint8_t portamento_time)
{
portamento_time = constrain(portamento_time, 0, 99);
controllers.portamento_cc = portamento_time;
if (portamento_time > 0)
controllers.portamento_enable_cc = true;
else
controllers.portamento_enable_cc = false;
controllers.refresh();
}
uint8_t Dexed::getPortamentoTime(void)
{
return(controllers.portamento_cc);
}
int16_t Dexed::checkSystemExclusive(const uint8_t* sysex, const uint16_t len)
/*
-1: SysEx end status byte not detected.
-2: SysEx vendor not Yamaha.
-3: Unknown SysEx parameter change.
-4: Unknown SysEx voice or function.
-5: Not a SysEx voice bulk upload.
-6: Wrong length for SysEx voice bulk upload (not 155).
-7: Checksum error for one voice.
-8: Not a SysEx bank bulk upload.
-9: Wrong length for SysEx bank bulk upload (not 4096).
-10: Checksum error for bank.
-11: Unknown SysEx message.
64-77: Function parameter changed.
100: Voice loaded.
200: Bank loaded.
300-455: Voice parameter changed.
*/
{
int32_t bulk_checksum_calc = 0;
const int8_t bulk_checksum = sysex[161];
// Check for SYSEX end byte
if (sysex[len - 1] != 0xf7)
return(-1);
// check for Yamaha sysex
if (sysex[1] != 0x43)
return(-2);
// Decode SYSEX by means of length
switch (len)
{
case 7: // parse parameter change
if (((sysex[3] & 0x7c) >> 2) != 0 && ((sysex[3] & 0x7c) >> 2) != 2)
return(-3);
if ((sysex[3] & 0x7c) >> 2 == 0) // Voice parameter
{
setVoiceDataElement((sysex[4] & 0x7f) + ((sysex[3] & 0x03) * 128), sysex[5]);
doRefreshVoice();
return((sysex[4] & 0x7f) + ((sysex[3] & 0x03) * 128)+300);
}
else if ((sysex[3] & 0x7c) >> 2 == 2) // Function parameter
return(sysex[4]);
else
return(-4);
break;
case 163: // 1 Voice bulk upload
if ((sysex[3] & 0x7f) != 0)
return(-5);
if (((sysex[4] << 7) | sysex[5]) != 0x9b)
return(-6);
// checksum calculation
for (uint8_t i = 0; i < 155 ; i++)
bulk_checksum_calc -= sysex[i + 6];
bulk_checksum_calc &= 0x7f;
if (bulk_checksum_calc != bulk_checksum)
return(-7);
return(100);
break;
case 4104: // 1 Bank bulk upload
if ((sysex[3] & 0x7f) != 9)
return(-8);
if (((sysex[4] << 7) | sysex[5]) != 0x1000)
return(-9);
// checksum calculation
for (uint16_t i = 0; i < 4096 ; i++)
bulk_checksum_calc -= sysex[i + 6];
bulk_checksum_calc &= 0x7f;
if (bulk_checksum_calc != bulk_checksum)
return(-10);
return(200);
break;
default:
return(-11);
}
}
uint32_t Dexed::getXRun(void) uint32_t Dexed::getXRun(void)
{ {
return (xrun); return (xrun);
@ -1019,6 +1163,7 @@ void Dexed::setOPRateAll(uint8_t rate)
data[(op * 21) + DEXED_OP_EG_R1 + step] = rate; data[(op * 21) + DEXED_OP_EG_R1 + step] = rate;
} }
} }
doRefreshVoice();
} }
void Dexed::setOPLevelAll(uint8_t level) void Dexed::setOPLevelAll(uint8_t level)
@ -1032,6 +1177,7 @@ void Dexed::setOPLevelAll(uint8_t level)
data[(op * 21) + DEXED_OP_EG_L1 + step] = level; data[(op * 21) + DEXED_OP_EG_L1 + step] = level;
} }
} }
doRefreshVoice();
} }
void Dexed::setOPRateAllModulator(uint8_t step, uint8_t rate) void Dexed::setOPRateAllModulator(uint8_t step, uint8_t rate)
@ -1046,6 +1192,7 @@ void Dexed::setOPRateAllModulator(uint8_t step, uint8_t rate)
if ((op_carrier & (1 << op)) == 0) if ((op_carrier & (1 << op)) == 0)
data[(op * 21) + DEXED_OP_EG_R1 + step] = rate; data[(op * 21) + DEXED_OP_EG_R1 + step] = rate;
} }
doRefreshVoice();
} }
void Dexed::setOPLevelAllModulator(uint8_t step, uint8_t level) void Dexed::setOPLevelAllModulator(uint8_t step, uint8_t level)
@ -1060,6 +1207,7 @@ void Dexed::setOPLevelAllModulator(uint8_t step, uint8_t level)
if ((op_carrier & (1 << op)) == 0) if ((op_carrier & (1 << op)) == 0)
data[(op * 21) + DEXED_OP_EG_L1 + step] = level; data[(op * 21) + DEXED_OP_EG_L1 + step] = level;
} }
doRefreshVoice();
} }
void Dexed::setOPRateAllCarrier(uint8_t step, uint8_t rate) void Dexed::setOPRateAllCarrier(uint8_t step, uint8_t rate)
@ -1074,6 +1222,7 @@ void Dexed::setOPRateAllCarrier(uint8_t step, uint8_t rate)
if ((op_carrier & (1 << op)) == 1) if ((op_carrier & (1 << op)) == 1)
data[(op * 21) + DEXED_OP_EG_R1 + step] = rate; data[(op * 21) + DEXED_OP_EG_R1 + step] = rate;
} }
doRefreshVoice();
} }
void Dexed::setOPLevelAllCarrier(uint8_t step, uint8_t level) void Dexed::setOPLevelAllCarrier(uint8_t step, uint8_t level)
@ -1088,6 +1237,7 @@ void Dexed::setOPLevelAllCarrier(uint8_t step, uint8_t level)
if ((op_carrier & (1 << op)) == 1) if ((op_carrier & (1 << op)) == 1)
data[(op * 21) + DEXED_OP_EG_L1 + step] = level; data[(op * 21) + DEXED_OP_EG_L1 + step] = level;
} }
doRefreshVoice();
} }
void Dexed::setOPRate(uint8_t op, uint8_t step, uint8_t rate) void Dexed::setOPRate(uint8_t op, uint8_t step, uint8_t rate)
@ -1097,6 +1247,7 @@ void Dexed::setOPRate(uint8_t op, uint8_t step, uint8_t rate)
rate = constrain(rate, 0, 99); rate = constrain(rate, 0, 99);
data[(op * 21) + DEXED_OP_EG_R1 + step] = rate; data[(op * 21) + DEXED_OP_EG_R1 + step] = rate;
doRefreshVoice();
} }
uint8_t Dexed::getOPRate(uint8_t op, uint8_t step) uint8_t Dexed::getOPRate(uint8_t op, uint8_t step)
@ -1114,6 +1265,7 @@ void Dexed::setOPLevel(uint8_t op, uint8_t step, uint8_t level)
level = constrain(level, 0, 99); level = constrain(level, 0, 99);
data[(op * 21) + DEXED_OP_EG_L1 + step] = level; data[(op * 21) + DEXED_OP_EG_L1 + step] = level;
doRefreshVoice();
} }
uint8_t Dexed::getOPLevel(uint8_t op, uint8_t step) uint8_t Dexed::getOPLevel(uint8_t op, uint8_t step)
@ -1130,6 +1282,7 @@ void Dexed::setOPKeyboardLevelScalingBreakPoint(uint8_t op, uint8_t level)
level = constrain(level, 0, 99); level = constrain(level, 0, 99);
data[(op * 21) + DEXED_OP_LEV_SCL_BRK_PT] = level; data[(op * 21) + DEXED_OP_LEV_SCL_BRK_PT] = level;
doRefreshVoice();
} }
uint8_t Dexed::getOPKeyboardLevelScalingBreakPoint(uint8_t op) uint8_t Dexed::getOPKeyboardLevelScalingBreakPoint(uint8_t op)
@ -1145,6 +1298,7 @@ void Dexed::setOPKeyboardLevelScalingDepthLeft(uint8_t op, uint8_t depth)
depth = constrain(depth, 0, 99); depth = constrain(depth, 0, 99);
data[(op * 21) + DEXED_OP_SCL_LEFT_DEPTH] = depth; data[(op * 21) + DEXED_OP_SCL_LEFT_DEPTH] = depth;
doRefreshVoice();
} }
uint8_t Dexed::getOPKeyboardLevelScalingDepthLeft(uint8_t op) uint8_t Dexed::getOPKeyboardLevelScalingDepthLeft(uint8_t op)
@ -1160,6 +1314,7 @@ void Dexed::setOPKeyboardLevelScalingDepthRight(uint8_t op, uint8_t depth)
depth = constrain(depth, 0, 99); depth = constrain(depth, 0, 99);
data[(op * 21) + DEXED_OP_SCL_RGHT_DEPTH] = depth; data[(op * 21) + DEXED_OP_SCL_RGHT_DEPTH] = depth;
doRefreshVoice();
} }
uint8_t Dexed::getOPKeyboardLevelScalingDepthRight(uint8_t op) uint8_t Dexed::getOPKeyboardLevelScalingDepthRight(uint8_t op)
@ -1175,6 +1330,7 @@ void Dexed::setOPKeyboardLevelScalingCurveLeft(uint8_t op, uint8_t curve)
curve = constrain(curve, 0, 3); curve = constrain(curve, 0, 3);
data[(op * 21) + DEXED_OP_SCL_LEFT_CURVE] = curve; data[(op * 21) + DEXED_OP_SCL_LEFT_CURVE] = curve;
doRefreshVoice();
} }
uint8_t Dexed::getOPKeyboardLevelScalingCurveLeft(uint8_t op) uint8_t Dexed::getOPKeyboardLevelScalingCurveLeft(uint8_t op)
@ -1190,6 +1346,7 @@ void Dexed::setOPKeyboardLevelScalingCurveRight(uint8_t op, uint8_t curve)
curve = constrain(curve, 0, 3); curve = constrain(curve, 0, 3);
data[(op * 21) + DEXED_OP_SCL_RGHT_CURVE] = curve; data[(op * 21) + DEXED_OP_SCL_RGHT_CURVE] = curve;
doRefreshVoice();
} }
uint8_t Dexed::getOPKeyboardLevelScalingCurveRight(uint8_t op) uint8_t Dexed::getOPKeyboardLevelScalingCurveRight(uint8_t op)
@ -1205,6 +1362,7 @@ void Dexed::setOPKeyboardRateScale(uint8_t op, uint8_t scale)
scale = constrain(scale, 0, 7); scale = constrain(scale, 0, 7);
data[(op * 21) + DEXED_OP_OSC_RATE_SCALE] = scale; data[(op * 21) + DEXED_OP_OSC_RATE_SCALE] = scale;
doRefreshVoice();
} }
uint8_t Dexed::getOPKeyboardRateScale(uint8_t op) uint8_t Dexed::getOPKeyboardRateScale(uint8_t op)
@ -1220,6 +1378,7 @@ void Dexed::setOPAmpModulationSensity(uint8_t op, uint8_t sensitivity)
sensitivity = constrain(sensitivity, 0, 3); sensitivity = constrain(sensitivity, 0, 3);
data[(op * 21) + DEXED_OP_AMP_MOD_SENS] = sensitivity; data[(op * 21) + DEXED_OP_AMP_MOD_SENS] = sensitivity;
doRefreshVoice();
} }
uint8_t Dexed::getOPAmpModulationSensity(uint8_t op) uint8_t Dexed::getOPAmpModulationSensity(uint8_t op)
@ -1235,6 +1394,7 @@ void Dexed::setOPKeyboardVelocitySensity(uint8_t op, uint8_t sensitivity)
sensitivity = constrain(sensitivity, 0, 7); sensitivity = constrain(sensitivity, 0, 7);
data[(op * 21) + DEXED_OP_KEY_VEL_SENS] = sensitivity; data[(op * 21) + DEXED_OP_KEY_VEL_SENS] = sensitivity;
doRefreshVoice();
} }
uint8_t Dexed::getOPKeyboardVelocitySensity(uint8_t op) uint8_t Dexed::getOPKeyboardVelocitySensity(uint8_t op)
@ -1250,6 +1410,7 @@ void Dexed::setOPOutputLevel(uint8_t op, uint8_t level)
level = constrain(level, 0, 99); level = constrain(level, 0, 99);
data[(op * 21) + DEXED_OP_OUTPUT_LEV] = level; data[(op * 21) + DEXED_OP_OUTPUT_LEV] = level;
doRefreshVoice();
} }
uint8_t Dexed::getOPOutputLevel(uint8_t op) uint8_t Dexed::getOPOutputLevel(uint8_t op)
@ -1265,6 +1426,7 @@ void Dexed::setOPMode(uint8_t op, uint8_t mode)
mode = constrain(mode, 0, 1); mode = constrain(mode, 0, 1);
data[(op * 21) + DEXED_OP_OSC_MODE] = mode; data[(op * 21) + DEXED_OP_OSC_MODE] = mode;
doRefreshVoice();
} }
uint8_t Dexed::getOPMode(uint8_t op) uint8_t Dexed::getOPMode(uint8_t op)
@ -1280,6 +1442,7 @@ void Dexed::setOPFrequencyCoarse(uint8_t op, uint8_t frq_coarse)
frq_coarse = constrain(frq_coarse, 0, 31); frq_coarse = constrain(frq_coarse, 0, 31);
data[(op * 21) + DEXED_OP_FREQ_COARSE] = frq_coarse; data[(op * 21) + DEXED_OP_FREQ_COARSE] = frq_coarse;
doRefreshVoice();
} }
uint8_t Dexed::getOPFrequencyCoarse(uint8_t op) uint8_t Dexed::getOPFrequencyCoarse(uint8_t op)
@ -1295,6 +1458,7 @@ void Dexed::setOPFrequencyFine(uint8_t op, uint8_t frq_fine)
frq_fine = constrain(frq_fine, 0, 99); frq_fine = constrain(frq_fine, 0, 99);
data[(op * 21) + DEXED_OP_FREQ_FINE] = frq_fine; data[(op * 21) + DEXED_OP_FREQ_FINE] = frq_fine;
doRefreshVoice();
} }
uint8_t Dexed::getOPFrequencyFine(uint8_t op) uint8_t Dexed::getOPFrequencyFine(uint8_t op)
@ -1310,6 +1474,7 @@ void Dexed::setOPDetune(uint8_t op, uint8_t detune)
detune = constrain(detune, 0, 14); detune = constrain(detune, 0, 14);
data[(op * 21) + DEXED_OP_OSC_DETUNE] = detune; data[(op * 21) + DEXED_OP_OSC_DETUNE] = detune;
doRefreshVoice();
} }
uint8_t Dexed::getOPDetune(uint8_t op) uint8_t Dexed::getOPDetune(uint8_t op)
@ -1325,6 +1490,7 @@ void Dexed::setPitchRate(uint8_t step, uint8_t rate)
rate = constrain(rate, 0, 99); rate = constrain(rate, 0, 99);
data[DEXED_VOICE_OFFSET + DEXED_PITCH_EG_R1 + step] = rate; data[DEXED_VOICE_OFFSET + DEXED_PITCH_EG_R1 + step] = rate;
doRefreshVoice();
} }
uint8_t Dexed::getPitchRate(uint8_t step) uint8_t Dexed::getPitchRate(uint8_t step)
@ -1340,6 +1506,7 @@ void Dexed::setPitchLevel(uint8_t step, uint8_t level)
level = constrain(level, 0, 99); level = constrain(level, 0, 99);
data[DEXED_VOICE_OFFSET + DEXED_PITCH_EG_L1 + step] = level; data[DEXED_VOICE_OFFSET + DEXED_PITCH_EG_L1 + step] = level;
doRefreshVoice();
} }
uint8_t Dexed::getPitchLevel(uint8_t step) uint8_t Dexed::getPitchLevel(uint8_t step)
@ -1354,6 +1521,7 @@ void Dexed::setAlgorithm(uint8_t algorithm)
algorithm = constrain(algorithm, 0, 31); algorithm = constrain(algorithm, 0, 31);
data[DEXED_VOICE_OFFSET + DEXED_ALGORITHM] = algorithm; data[DEXED_VOICE_OFFSET + DEXED_ALGORITHM] = algorithm;
doRefreshVoice();
} }
uint8_t Dexed::getAlgorithm(void) uint8_t Dexed::getAlgorithm(void)
@ -1366,6 +1534,7 @@ void Dexed::setFeedback(uint8_t feedback)
feedback = constrain(feedback, 0, 31); feedback = constrain(feedback, 0, 31);
data[DEXED_VOICE_OFFSET + DEXED_FEEDBACK] = feedback; data[DEXED_VOICE_OFFSET + DEXED_FEEDBACK] = feedback;
doRefreshVoice();
} }
uint8_t Dexed::getFeedback(void) uint8_t Dexed::getFeedback(void)
@ -1376,6 +1545,7 @@ uint8_t Dexed::getFeedback(void)
void Dexed::setOscillatorSync(bool sync) void Dexed::setOscillatorSync(bool sync)
{ {
data[DEXED_VOICE_OFFSET + DEXED_OSC_KEY_SYNC] = sync; data[DEXED_VOICE_OFFSET + DEXED_OSC_KEY_SYNC] = sync;
doRefreshVoice();
} }
bool Dexed::getOscillatorSync(void) bool Dexed::getOscillatorSync(void)
@ -1388,6 +1558,7 @@ void Dexed::setLFOSpeed(uint8_t speed)
speed = constrain(speed, 0, 99); speed = constrain(speed, 0, 99);
data[DEXED_VOICE_OFFSET + DEXED_LFO_SPEED] = speed; data[DEXED_VOICE_OFFSET + DEXED_LFO_SPEED] = speed;
lfo.reset(data + 137);
} }
uint8_t Dexed::getLFOSpeed(void) uint8_t Dexed::getLFOSpeed(void)
@ -1400,6 +1571,7 @@ void Dexed::setLFODelay(uint8_t delay)
delay = constrain(delay, 0, 99); delay = constrain(delay, 0, 99);
data[DEXED_VOICE_OFFSET + DEXED_LFO_DELAY] = delay; data[DEXED_VOICE_OFFSET + DEXED_LFO_DELAY] = delay;
lfo.reset(data + 137);
} }
uint8_t Dexed::getLFODelay(void) uint8_t Dexed::getLFODelay(void)
@ -1412,7 +1584,9 @@ void Dexed::setLFOPitchModulationDepth(uint8_t depth)
depth = constrain(depth, 0, 99); depth = constrain(depth, 0, 99);
data[DEXED_VOICE_OFFSET + DEXED_LFO_PITCH_MOD_DEP] = depth; data[DEXED_VOICE_OFFSET + DEXED_LFO_PITCH_MOD_DEP] = depth;
lfo.reset(data + 137);
} }
uint8_t Dexed::getLFOPitchModulationDepth(void) uint8_t Dexed::getLFOPitchModulationDepth(void)
{ {
return (data[DEXED_VOICE_OFFSET + DEXED_LFO_PITCH_MOD_DEP]); return (data[DEXED_VOICE_OFFSET + DEXED_LFO_PITCH_MOD_DEP]);
@ -1423,6 +1597,7 @@ void Dexed::setLFOAmpModulationDepth(uint8_t depth)
depth = constrain(depth, 0, 99); depth = constrain(depth, 0, 99);
data[DEXED_VOICE_OFFSET + DEXED_LFO_AMP_MOD_DEP] = depth; data[DEXED_VOICE_OFFSET + DEXED_LFO_AMP_MOD_DEP] = depth;
lfo.reset(data + 137);
} }
uint8_t Dexed::getLFOAmpModulationDepth(void) uint8_t Dexed::getLFOAmpModulationDepth(void)
@ -1438,6 +1613,7 @@ void Dexed::setLFOSync(bool sync)
bool Dexed::getLFOSync(void) bool Dexed::getLFOSync(void)
{ {
return (data[DEXED_VOICE_OFFSET + DEXED_LFO_SYNC]); return (data[DEXED_VOICE_OFFSET + DEXED_LFO_SYNC]);
lfo.reset(data + 137);
} }
void Dexed::setLFOWaveform(uint8_t waveform) void Dexed::setLFOWaveform(uint8_t waveform)
@ -1445,6 +1621,7 @@ void Dexed::setLFOWaveform(uint8_t waveform)
waveform = constrain(waveform, 0, 5); waveform = constrain(waveform, 0, 5);
data[DEXED_VOICE_OFFSET + DEXED_LFO_WAVE] = waveform; data[DEXED_VOICE_OFFSET + DEXED_LFO_WAVE] = waveform;
lfo.reset(data + 137);
} }
uint8_t Dexed::getLFOWaveform(void) uint8_t Dexed::getLFOWaveform(void)
@ -1457,6 +1634,7 @@ void Dexed::setLFOPitchModulationSensitivity(uint8_t sensitivity)
sensitivity = constrain(sensitivity, 0, 5); sensitivity = constrain(sensitivity, 0, 5);
data[DEXED_VOICE_OFFSET + DEXED_LFO_PITCH_MOD_SENS] = sensitivity; data[DEXED_VOICE_OFFSET + DEXED_LFO_PITCH_MOD_SENS] = sensitivity;
lfo.reset(data + 137);
} }
uint8_t Dexed::getLFOPitchModulationSensitivity(void) uint8_t Dexed::getLFOPitchModulationSensitivity(void)
@ -1490,12 +1668,12 @@ void Dexed::getName(char* buffer)
#ifdef USE_DEXED_COMPRESSOR #ifdef USE_DEXED_COMPRESSOR
void Dexed::setCompressor(bool enable_compressor) void Dexed::setCompressor(bool enable_compressor)
{ {
use_compressor=enable_compressor; use_compressor = enable_compressor;
} }
bool Dexed::getCompressor(void) bool Dexed::getCompressor(void)
{ {
return(use_compressor); return (use_compressor);
} }
void Dexed::setCompressorPreGain_dB(float32_t pre_gain) void Dexed::setCompressorPreGain_dB(float32_t pre_gain)
@ -1505,12 +1683,12 @@ void Dexed::setCompressorPreGain_dB(float32_t pre_gain)
void Dexed::setCompressorAttack_sec(float32_t attack_sec) void Dexed::setCompressorAttack_sec(float32_t attack_sec)
{ {
compressor->setAttack_sec(attack_sec,samplerate); compressor->setAttack_sec(attack_sec, samplerate);
} }
void Dexed::setCompressorRelease_sec(float32_t release_sec) void Dexed::setCompressorRelease_sec(float32_t release_sec)
{ {
compressor->setRelease_sec(release_sec,samplerate); compressor->setRelease_sec(release_sec, samplerate);
} }
void Dexed::setCompressorThresh_dBFS(float32_t thresh_dBFS) void Dexed::setCompressorThresh_dBFS(float32_t thresh_dBFS)
@ -1525,26 +1703,26 @@ void Dexed::setCompressionRatio(float32_t comp_ratio)
float32_t Dexed::getCompressorPreGain_dB(void) float32_t Dexed::getCompressorPreGain_dB(void)
{ {
return(compressor->getPreGain_dB()); return (compressor->getPreGain_dB());
} }
float32_t Dexed::getCompressorAttack_sec(void) float32_t Dexed::getCompressorAttack_sec(void)
{ {
return(compressor->getAttack_sec()); return (compressor->getAttack_sec());
} }
float32_t Dexed::getCompressorRelease_sec(void) float32_t Dexed::getCompressorRelease_sec(void)
{ {
return(compressor->getRelease_sec()); return (compressor->getRelease_sec());
} }
float32_t Dexed::getCompressorThresh_dBFS(void) float32_t Dexed::getCompressorThresh_dBFS(void)
{ {
return(compressor->getThresh_dBFS()); return (compressor->getThresh_dBFS());
} }
float32_t Dexed::getCompressionRatio(void) float32_t Dexed::getCompressionRatio(void)
{ {
return(compressor->getCompressionRatio()); return (compressor->getCompressionRatio());
} }
#endif #endif

@ -158,7 +158,7 @@ class Dexed
void deactivate(void); void deactivate(void);
bool getMonoMode(void); bool getMonoMode(void);
void setMonoMode(bool mode); void setMonoMode(bool mode);
void setRefreshMode(bool mode); void setNoteRefreshMode(bool mode);
void setMaxNotes(uint8_t n); void setMaxNotes(uint8_t n);
uint8_t getMaxNotes(void); uint8_t getMaxNotes(void);
void doRefreshVoice(void); void doRefreshVoice(void);
@ -189,6 +189,7 @@ class Dexed
float32_t getCompressorThresh_dBFS(void); float32_t getCompressorThresh_dBFS(void);
float32_t getCompressionRatio(void); float32_t getCompressionRatio(void);
#endif #endif
int16_t checkSystemExclusive(const uint8_t* sysex, const uint16_t len);
// Sound methods // Sound methods
void keyup(int16_t pitch); void keyup(int16_t pitch);
@ -200,7 +201,13 @@ class Dexed
void resetControllers(void); void resetControllers(void);
void setMasterTune(int8_t mastertune); void setMasterTune(int8_t mastertune);
int8_t getMasterTune(void); int8_t getMasterTune(void);
void setPortamentoMode(uint8_t portamento_mode, uint8_t portamento_glissando, uint8_t portamento_time); void setPortamento(uint8_t portamento_mode, uint8_t portamento_glissando, uint8_t portamento_time);
void setPortamentoMode(uint8_t portamento_mode);
uint8_t getPortamentoMode(void);
void setPortamentoGlissando(uint8_t portamento_glissando);
uint8_t getPortamentoGlissando(void);
void setPortamentoTime(uint8_t portamento_time);
uint8_t getPortamentoTime(void);
void setPBController(uint8_t pb_range, uint8_t pb_step); void setPBController(uint8_t pb_range, uint8_t pb_step);
void setMWController(uint8_t mw_range, uint8_t mw_assign, uint8_t mw_mode); void setMWController(uint8_t mw_range, uint8_t mw_assign, uint8_t mw_mode);
void setFCController(uint8_t fc_range, uint8_t fc_assign, uint8_t fc_mode); void setFCController(uint8_t fc_range, uint8_t fc_assign, uint8_t fc_mode);
@ -337,7 +344,7 @@ class Dexed
bool sustain; bool sustain;
float vuSignal; float vuSignal;
bool monoMode; bool monoMode;
bool refreshMode; bool noteRefreshMode;
bool refreshVoice; bool refreshVoice;
uint8_t engineType; uint8_t engineType;
VoiceStatus voiceStatus; VoiceStatus voiceStatus;

@ -17,18 +17,14 @@
#include <math.h> #include <math.h>
#include <cstdlib> #include <cstdlib>
#include <stdint.h> #include <stdint.h>
#ifdef __ARM_NEON
#include <arm_neon.h>
#endif
#include "synth.h" #include "synth.h"
#include "sin.h" #include "sin.h"
#include "fm_op_kernel.h" #include "fm_op_kernel.h"
#ifdef __ARM_NEON #ifdef __ARM_NEON
#include <arm_neon.h>
extern "C" extern "C"
void neon_fm_kernel(const int *in, const int *busin, int *out, int count, void neon_fm_kernel(const int32_t *in, const int32_t *busin, int32_t *out, int32_t count,
int32_t phase0, int32_t freq, int32_t gain1, int32_t dgain); int32_t phase0, int32_t freq, int32_t gain1, int32_t dgain);
const int32_t __attribute__ ((aligned(16))) const_0_1_2_3_arg[4] = {0, 1, 2, 3}; const int32_t __attribute__ ((aligned(16))) const_0_1_2_3_arg[4] = {0, 1, 2, 3};
@ -39,7 +35,7 @@ const float32_t __attribute__ ((aligned(16))) coeffs_arg[4] = {
const int32_t __attribute__ ((aligned(16))) zeros[_N_] = {0}; const int32_t __attribute__ ((aligned(16))) zeros[_N_] = {0};
void neon_fm_kernel(const int *in, const int *busin, int *out, int count, void neon_fm_kernel(const int32_t *in, const int32_t *busin, int32_t *out, int32_t count,
int32_t phase0, int32_t freq_arg, int32_t gain1_arg, int32_t dgain_arg) { int32_t phase0, int32_t freq_arg, int32_t gain1_arg, int32_t dgain_arg) {
int32x4_t phase = vld1q_dup_s32(&phase0); int32x4_t phase = vld1q_dup_s32(&phase0);
int32x4_t freq = vld1q_dup_s32(&freq_arg); int32x4_t freq = vld1q_dup_s32(&freq_arg);
@ -159,11 +155,11 @@ void FmOpKernel::compute(int32_t *output, const int32_t *input,
int32_t gain1, int32_t gain2, bool add) { int32_t gain1, int32_t gain2, bool add) {
int32_t dgain = (gain2 - gain1 + (_N_ >> 1)) >> LG_N; int32_t dgain = (gain2 - gain1 + (_N_ >> 1)) >> LG_N;
int32_t gain = gain1; int32_t gain = gain1;
int32_t phase = phase0;
#ifdef __ARM_NEON #ifdef __ARM_NEON
neon_fm_kernel(input, add ? output : zeros, output, _N_, neon_fm_kernel(input, add ? output : zeros, output, _N_,
phase0, freq, gain, dgain); phase0, freq, gain, dgain);
#else #else
int32_t phase = phase0;
if (add) { if (add) {
for (int i = 0; i < _N_; i++) { for (int i = 0; i < _N_; i++) {
gain += dgain; gain += dgain;
@ -188,11 +184,11 @@ void FmOpKernel::compute_pure(int32_t *output, int32_t phase0, int32_t freq,
int32_t gain1, int32_t gain2, bool add) { int32_t gain1, int32_t gain2, bool add) {
int32_t dgain = (gain2 - gain1 + (_N_ >> 1)) >> LG_N; int32_t dgain = (gain2 - gain1 + (_N_ >> 1)) >> LG_N;
int32_t gain = gain1; int32_t gain = gain1;
int32_t phase = phase0;
#ifdef __ARM_NEON #ifdef __ARM_NEON
neon_fm_kernel(zeros, add ? output : zeros, output, _N_, neon_fm_kernel(zeros, add ? output : zeros, output, _N_,
phase0, freq, gain, dgain); phase0, freq, gain, dgain);
#else #else
int32_t phase = phase0;
if (add) { if (add) {
for (int i = 0; i < _N_; i++) { for (int i = 0; i < _N_; i++) {
gain += dgain; gain += dgain;

Loading…
Cancel
Save