Function and parameter setting via SysEx added.

dev
Holger Wirtz 2 years ago
parent 377b7bb983
commit 0d6edb7f4f
  1. 2
      src/Makefile
  2. 77
      src/dexed.cpp
  3. 3
      src/dexed.h
  4. 158
      src/msfa/controllers.h
  5. 123
      src/msfa/controllers.h.old

@ -1,7 +1,7 @@
BUNDLE=dexed.lv2
TARGET=dexed.so
#DEBUG=1
DEBUG=1
#FILETRACE=1
INSTALL_DIR=/zynthian/zynthian-plugins/lv2

@ -581,80 +581,70 @@ bool Dexed::ProcessSysExParameterChange(const uint8_t *sysex, uint32_t len) {
}
bool Dexed::ProcessSysExVoiceParameterChange(const uint8_t *sysex, uint32_t len) {
sysex[4] &= 0x7f;
sysex[5] &= 0x7f;
uint8_t p = sysex[4] & 0x7f;
uint8_t v = sysex[5] & 0x7f;
TRACE("SysEx Voice parameter: #%d = %d",sysex[4] + (sysex[3] & 0x03) * 128, sysex[5]);
TRACE("SysEx Voice parameter: #%d = %d",p + (sysex[3] & 0x03) * 128, v);
onParam(sysex[4] + ((sysex[3] & 0x03) * 128), sysex[5]);
onParam(p + ((sysex[3] & 0x03) * 128), v);
return(true);
}
bool Dexed::ProcessSysExFunctionParameterChange(const uint8_t *sysex, uint32_t len) {
sysex[4] &= 0x7f;
sysex[5] &= 0x7f;
uint8_t p = sysex[4] & 0x7f;
uint8_t v = sysex[5] & 0x7f;
TRACE("SysEx Function parameter: #%d = %d",sysex[4], sysex[5]);
TRACE("SysEx Function parameter: #%d = %d",p, v);
switch (sysex[4])
switch (p)
{
case 65:
controllers.values_[kControllerPitchRange] = sysex[5];
controllers.values_[kControllerPitchRange] = v;
break;
case 66:
controllers.values_[kControllerPitchStep] = sysex[5];
controllers.values_[kControllerPitchStep] = v;
break;
case 67:
portamento_mode = sysex[5];
setPortamentoMode(v, controllers.values_[kControllerPortamentoGlissando], controllers.portamento_cc);
break;
case 68:
portamento_glissando = sysex[5];
setPortamentoMode(controllers.portamento_enable_cc, v, controllers.portamento_cc);
break;
case 69:
controllers.portamento_cc = = sysex[5];
if (portamento_time > 0)
controllers.portamento_enable_cc = true;
else
controllers.portamento_enable_cc = false;
controllers.values_[kControllerPortamentoGlissando] = portamento_glissando;
setPortamentoMode(controllers.portamento_enable_cc, controllers.values_[kControllerPortamentoGlissando], v);
break;
case 70:
controllers.wheel.setRange(sysex[5]);
controllers.wheel.setRange(v);
break;
case 71:
controllers.wheel.setTarget(sysex[5]);
controllers.wheel.setTarget(v);
break;
case 72:
controllers.foot.setRange(sysex[5]);
controllers.foot.setRange(v);
break;
case 73:
controllers.foot.setTarget(sysex[5]);
controllers.foot.setTarget(v);
break;
case 74:
controllers.breath.setRange(sysex[5]);
controllers.breath.setRange(v);
break;
case 75:
controllers.breath.setTarget(sysex[5]);
controllers.breath.setTarget(v);
break;
case 76:
controllers.at.setRange(sysex[5]);
controllers.at.setRange(v);
break;
case 77:
controllers.at.setTarget(sysex[5]);
controllers.at.setTarget(v);
break;
default:
onParam(sysex[4], sysex[5]);
onParam(p, v);
break;
}
controllers.refresh();
}
else
{
TRACE("Unknown SysEx voice or function: #%d = %d",sysex[4],sysex[5]);
return(false);
}
controllers.refresh();
TRACE("Unknown SysEx voice or function: #%d = %d",p,v);
return(true);
}
@ -738,7 +728,7 @@ bool Dexed::ProcessMidiMessage(const uint8_t *buf, uint32_t buf_size) {
break;
case 0xf0 :
// sysex
TRACE("MIDI sysex event: cmd=%d, size=%d",buf[0],size);
TRACE("MIDI sysex event: cmd=%d, size=%d",buf[0],buf_size);
if(buf[1]==0x43)
ProcessSysEx(buf, buf_size);
else
@ -753,6 +743,21 @@ bool Dexed::ProcessMidiMessage(const uint8_t *buf, uint32_t buf_size) {
return(false);
}
void Dexed::setPortamentoMode(uint8_t portamento_mode, uint8_t portamento_glissando, uint8_t portamento_time)
{
controllers.portamento_cc = portamento_time;
controllers.portamento_enable_cc = portamento_mode > 63;
if (portamento_time > 0)
controllers.portamento_enable_cc = true;
else
controllers.portamento_enable_cc = false;
controllers.values_[kControllerPortamentoGlissando] = portamento_glissando;
controllers.refresh();
}
void Dexed::keydown(uint8_t pitch, uint8_t velo) {
TRACE("Hi");
TRACE("pitch=%d, velo=%d\n",pitch,velo);

@ -94,7 +94,10 @@ class Dexed : public lvtk::Synth<DexedVoice, Dexed>
protected:
bool ProcessSysEx(const uint8_t *sysex, uint32_t len);
bool ProcessSysExParameterChange(const uint8_t *sysex, uint32_t len);
bool ProcessSysExVoiceParameterChange(const uint8_t *sysex, uint32_t len);
bool ProcessSysExFunctionParameterChange(const uint8_t *sysex, uint32_t len);
bool ProcessMidiMessage(const uint8_t *buf, uint32_t buf_size);
void setPortamentoMode(uint8_t portamento_mode, uint8_t portamento_glissando, uint8_t portamento_time);
void onParam(uint8_t param_num,float param_val);
void keyup(uint8_t pitch);
void keydown(uint8_t pitch, uint8_t velo);

@ -1,18 +1,18 @@
/*
* Copyright 2013 Google 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.
*/
Copyright 2013 Google 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.
*/
#ifndef __CONTROLLERS_H
#define __CONTROLLERS_H
@ -20,76 +20,98 @@
#include "synth.h"
#include <stdio.h>
#include <string.h>
#include "trace.h"
#include <math.h>
#ifdef _WIN32
#define snprintf _snprintf
#endif
#define MIDI_CONTROLLER_MODE_MAX 2
// State of MIDI controllers
const int kControllerPitch = 0;
const int kControllerPitchRange = 1;
const int kControllerPitchStep = 2;
const int kControllerPortamentoGlissando = 3;
class FmCore;
struct FmMod {
class FmMod {
public:
uint8_t range;
bool pitch;
bool amp;
bool eg;
FmMod() {
range = 0;
pitch = false;
amp = false;
eg = false;
uint8_t ctrl_mode;
uint8_t _dummy_;
FmMod()
{
range = 0;
ctrl_mode = 0;
pitch = false;
amp = false;
eg = false;
}
void setRange(uint8_t r) {
range = r < 0 || r > 127 ? 0 : r;
TRACE("range=%d",range);
void setRange(uint8_t r)
{
range = r < 0 && r > 99 ? 0 : r;
}
void setTarget(uint8_t assign) {
TRACE("Target: %d", assign);
assign=assign < 0 && assign > 7 ? 0 : assign;
pitch=assign&1; // AMP
amp=assign&2; // PITCH
eg=assign&4; // EG
void setTarget(uint8_t assign)
{
assign = assign < 0 && assign > 7 ? 0 : assign;
pitch = assign & 1; // PITCH
amp = assign & 2; // AMP
eg = assign & 4; // EG
}
TRACE("pitch[%d] amp[%d] eg[%d]", pitch,amp,eg);
void setMode(uint8_t m)
{
ctrl_mode = m > MIDI_CONTROLLER_MODE_MAX ? 0 : m;
}
};
class Controllers {
void applyMod(int cc, FmMod &mod) {
float range = 0.01 * mod.range;
uint8_t total = (float)cc * range;
TRACE("amp[%d]|pitch[%d]|eg[%d]",mod.amp,mod.pitch,mod.eg);
TRACE("range=%f mod.range=%d total=%d cc=%d",range,mod.range,total,cc);
if(mod.amp)
amp_mod = max(amp_mod, total);
if(mod.pitch)
pitch_mod = max(pitch_mod, total);
if(mod.eg)
eg_mod = max(eg_mod, total);
void applyMod(int cc, FmMod &mod)
{
uint8_t total = 0;
float range = mod.range / 100.0;
switch (mod.ctrl_mode)
{
case 0:
total = uint8_t(float(cc) * range); // LINEAR mode
break;
case 1:
total = uint8_t(127.0 * range - (float(cc) * range)); // REVERSE mode
break;
case 2:
total = uint8_t(range * float(cc) + (1.0 - range) * 127.0); // DIRECT BC mode by Thierry (opus.quatre)
break;
}
if (mod.amp)
amp_mod = max(amp_mod, total);
if (mod.pitch)
pitch_mod = max(pitch_mod, total);
if (mod.eg)
eg_mod = max(eg_mod, total);
}
public:
int32_t values_[3];
public:
int32_t values_[4];
uint8_t amp_mod;
uint8_t pitch_mod;
uint8_t eg_mod;
uint8_t aftertouch_cc;
uint8_t breath_cc;
uint8_t foot_cc;
uint8_t modwheel_cc;
bool portamento_enable_cc;
int portamento_cc;
bool portamento_gliss_cc;
int masterTune;
uint8_t opSwitch;
@ -98,25 +120,25 @@ public:
FmMod foot;
FmMod breath;
FmMod at;
Controllers() {
amp_mod = 0;
pitch_mod = 0;
eg_mod = 0;
amp_mod = 0;
pitch_mod = 0;
eg_mod = 0;
}
void refresh() {
amp_mod=pitch_mod=eg_mod=0;
applyMod(modwheel_cc, wheel);
applyMod(breath_cc, breath);
applyMod(foot_cc, foot);
applyMod(aftertouch_cc, at);
if ( ! ((wheel.eg || foot.eg) || (breath.eg || at.eg)) )
eg_mod = 127;
amp_mod = pitch_mod = eg_mod = 0;
applyMod(modwheel_cc, wheel);
applyMod(breath_cc, breath);
applyMod(foot_cc, foot);
applyMod(aftertouch_cc, at);
if ( ! ((wheel.eg || foot.eg) || (breath.eg || at.eg)) )
eg_mod = 127;
}
FmCore *core;
};

@ -0,0 +1,123 @@
/*
* Copyright 2013 Google 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.
*/
#ifndef __CONTROLLERS_H
#define __CONTROLLERS_H
#include "synth.h"
#include <stdio.h>
#include <string.h>
#include "trace.h"
#ifdef _WIN32
#define snprintf _snprintf
#endif
// State of MIDI controllers
const int kControllerPitch = 0;
const int kControllerPitchRange = 1;
const int kControllerPitchStep = 2;
class FmCore;
struct FmMod {
uint8_t range;
bool pitch;
bool amp;
bool eg;
FmMod() {
range = 0;
pitch = false;
amp = false;
eg = false;
}
void setRange(uint8_t r) {
range = r < 0 || r > 127 ? 0 : r;
TRACE("range=%d",range);
}
void setTarget(uint8_t assign) {
TRACE("Target: %d", assign);
assign=assign < 0 && assign > 7 ? 0 : assign;
pitch=assign&1; // AMP
amp=assign&2; // PITCH
eg=assign&4; // EG
TRACE("pitch[%d] amp[%d] eg[%d]", pitch,amp,eg);
}
};
class Controllers {
void applyMod(int cc, FmMod &mod) {
float range = 0.01 * mod.range;
uint8_t total = (float)cc * range;
TRACE("amp[%d]|pitch[%d]|eg[%d]",mod.amp,mod.pitch,mod.eg);
TRACE("range=%f mod.range=%d total=%d cc=%d",range,mod.range,total,cc);
if(mod.amp)
amp_mod = max(amp_mod, total);
if(mod.pitch)
pitch_mod = max(pitch_mod, total);
if(mod.eg)
eg_mod = max(eg_mod, total);
}
public:
int32_t values_[3];
uint8_t amp_mod;
uint8_t pitch_mod;
uint8_t eg_mod;
uint8_t aftertouch_cc;
uint8_t breath_cc;
uint8_t foot_cc;
uint8_t modwheel_cc;
int masterTune;
uint8_t opSwitch;
FmMod wheel;
FmMod foot;
FmMod breath;
FmMod at;
Controllers() {
amp_mod = 0;
pitch_mod = 0;
eg_mod = 0;
}
void refresh() {
amp_mod=pitch_mod=eg_mod=0;
applyMod(modwheel_cc, wheel);
applyMod(breath_cc, breath);
applyMod(foot_cc, foot);
applyMod(aftertouch_cc, at);
if ( ! ((wheel.eg || foot.eg) || (breath.eg || at.eg)) )
eg_mod = 127;
}
FmCore *core;
};
#endif // __CONTROLLERS_H
Loading…
Cancel
Save