Added generic fx paramters handling

pull/764/head
jnonis 7 months ago
parent 9b1ea33966
commit 7f110b284d
  1. 1
      src/effect_base.cpp
  2. 9
      src/effect_base.h
  3. 38
      src/effect_chorus.cpp
  4. 12
      src/effect_chorus.h
  5. 55
      src/effect_delay.cpp
  6. 17
      src/effect_delay.h
  7. 122
      src/effect_lpf.h
  8. 123
      src/minidexed.cpp
  9. 8
      src/minidexed.h
  10. 145
      src/uimenu.cpp
  11. 6
      src/uimenu.h

@ -24,7 +24,6 @@ unsigned AudioEffect::getId()
return EFFECT_NONE; return EFFECT_NONE;
} }
void AudioEffect::process(const float32_t* inblock, float32_t* outblock, uint16_t len) void AudioEffect::process(const float32_t* inblock, float32_t* outblock, uint16_t len)
{ {
// Mono process // Mono process

@ -19,8 +19,13 @@ public:
bool getBypass(); bool getBypass();
virtual unsigned getId(); virtual unsigned getId();
//virtual void setParameter(unsigned param, unsigned value); virtual void setParameter(unsigned param, unsigned value)
//virtual void getParameter(unsigned param); {
}
virtual unsigned getParameter(unsigned param)
{
return 0;
}
void process(const float32_t* inblockL, float32_t* outblockL, uint16_t len); void process(const float32_t* inblockL, float32_t* outblockL, uint16_t len);
void process(const float32_t* inblockL, const float32_t* inblockR, float32_t* outblockL, float32_t* outblockR, uint16_t len); void process(const float32_t* inblockL, const float32_t* inblockR, float32_t* outblockL, float32_t* outblockR, uint16_t len);

@ -22,6 +22,44 @@ unsigned AudioEffectChorus::getId()
return EFFECT_CHORUS; return EFFECT_CHORUS;
} }
void AudioEffectChorus::setParameter(unsigned param, unsigned value)
{
switch (param)
{
case AudioEffectChorus::Param::CHORUS_I_ENABLE:
this->setChorusI(value);
break;
case AudioEffectChorus::Param::CHORUS_II_ENABLE:
this->setChorusII(value);
break;
case AudioEffectChorus::Param::CHORUS_I_RATE:
this->setChorusIRate(value);
break;
case AudioEffectChorus::Param::CHORUS_II_RATE:
this->setChorusIIRate(value);
break;
default:
break;
}
}
unsigned AudioEffectChorus::getParameter(unsigned param)
{
switch (param)
{
case AudioEffectChorus::Param::CHORUS_I_ENABLE:
return this->getChorusI();
case AudioEffectChorus::Param::CHORUS_II_ENABLE:
return this->getChorusII();
case AudioEffectChorus::Param::CHORUS_I_RATE:
return this->getChorusIRate();
case AudioEffectChorus::Param::CHORUS_II_RATE:
return this->getChorusIIRate();
default:
return 0;
}
}
void AudioEffectChorus::doProcess(const float32_t* inblockL, const float32_t* inblockR, float32_t* outblockL, float32_t* outblockR, uint16_t len) void AudioEffectChorus::doProcess(const float32_t* inblockL, const float32_t* inblockR, float32_t* outblockL, float32_t* outblockR, uint16_t len)
{ {
for (uint16_t i=0; i < len; i++) for (uint16_t i=0; i < len; i++)

@ -7,11 +7,23 @@
class AudioEffectChorus : public AudioEffect class AudioEffectChorus : public AudioEffect
{ {
public: public:
enum Param
{
CHORUS_I_ENABLE,
CHORUS_II_ENABLE,
CHORUS_I_RATE,
CHORUS_II_RATE,
UNKNOWN
};
AudioEffectChorus(float32_t samplerate); AudioEffectChorus(float32_t samplerate);
virtual ~AudioEffectChorus(); virtual ~AudioEffectChorus();
virtual unsigned getId(); virtual unsigned getId();
virtual void setParameter(unsigned param, unsigned value);
virtual unsigned getParameter(unsigned param);
unsigned getChorusI(); unsigned getChorusI();
void setChorusI(unsigned enable); void setChorusI(unsigned enable);

@ -9,12 +9,13 @@ AudioEffectDelay::AudioEffectDelay(float32_t samplerate) : AudioEffect(samplerat
this->bufferL = new float32_t[this->bufferSize]; this->bufferL = new float32_t[this->bufferSize];
this->bufferR = new float32_t[this->bufferSize]; this->bufferR = new float32_t[this->bufferSize];
this->index = 0; this->index = 0;
this->lpf = new AudioEffectLPF(samplerate);
this->lpf->setParameter(AudioEffectLPF::Param::CUTOFF, 80);
this->lpf->setParameter(AudioEffectLPF::Param::RESONANCE, 0);
for (size_t i = 0; i < this->bufferSize; i++) // Clean buffers
{ memset(this->bufferL, 0, this->bufferSize * sizeof(float32_t));
this->bufferL[i] = 0.0f; memset(this->bufferR, 0, this->bufferSize * sizeof(float32_t));
this->bufferR[i] = 0.0f;
}
this->timeL = 0.36f; this->timeL = 0.36f;
this->timeR = 0.36f; this->timeR = 0.36f;
@ -25,6 +26,7 @@ AudioEffectDelay::~AudioEffectDelay()
{ {
delete this->bufferL; delete this->bufferL;
delete this->bufferR; delete this->bufferR;
delete this->lpf;
} }
unsigned AudioEffectDelay::getId() unsigned AudioEffectDelay::getId()
@ -32,6 +34,45 @@ unsigned AudioEffectDelay::getId()
return EFFECT_DELAY; return EFFECT_DELAY;
} }
void AudioEffectDelay::setParameter(unsigned param, unsigned value)
{
switch (param)
{
case AudioEffectDelay::Param::TIME_L:
this->timeL = (float32_t) value / 1000.0f;
break;
case AudioEffectDelay::Param::TIME_R:
this->timeR = (float32_t) value / 1000.0f;
break;
case AudioEffectDelay::Param::FEEDBACK:
this->feedback = (float32_t) value / 100.0f;
break;
case AudioEffectDelay::Param::TONE:
this->lpf->setParameter(AudioEffectLPF::Param::CUTOFF, value);
break;
default:
break;
}
}
unsigned AudioEffectDelay::getParameter(unsigned param)
{
switch (param)
{
case AudioEffectDelay::Param::TIME_L:
return roundf(this->timeL * 1000);
case AudioEffectDelay::Param::TIME_R:
return roundf(this->timeR * 1000);
case AudioEffectDelay::Param::FEEDBACK:
return roundf(this->feedback * 100);
case AudioEffectDelay::Param::TONE:
return this->lpf->getParameter(AudioEffectLPF::Param::CUTOFF);
default:
return 0;
}
}
void AudioEffectDelay::doProcess(const float32_t* inblockL, const float32_t* inblockR, float32_t* outblockL, float32_t* outblockR, uint16_t len) void AudioEffectDelay::doProcess(const float32_t* inblockL, const float32_t* inblockR, float32_t* outblockL, float32_t* outblockR, uint16_t len)
{ {
for (uint16_t i=0; i < len; i++) for (uint16_t i=0; i < len; i++)
@ -50,8 +91,8 @@ void AudioEffectDelay::doProcess(const float32_t* inblockL, const float32_t* inb
offsetR = this->bufferSize + offsetR; offsetR = this->bufferSize + offsetR;
} }
this->bufferL[index] += this->bufferL[offsetL] * this->feedback; this->bufferL[index] += this->lpf->processSampleL(this->bufferL[offsetL]) * this->feedback;
this->bufferR[index] += this->bufferR[offsetR] * this->feedback; this->bufferR[index] += this->lpf->processSampleR(this->bufferR[offsetR]) * this->feedback;
outblockL[i] = this->bufferL[index]; outblockL[i] = this->bufferL[index];
outblockR[i] = this->bufferR[index]; outblockR[i] = this->bufferR[index];

@ -2,16 +2,28 @@
#define _EFFECT_DELAY_H #define _EFFECT_DELAY_H
#include "effect_base.h" #include "effect_base.h"
#include "effect_lpf.h"
#define MAX_DELAY_TIME 1
class AudioEffectDelay : public AudioEffect class AudioEffectDelay : public AudioEffect
{ {
public: public:
static const unsigned MAX_DELAY_TIME = 1;
enum Param
{
TIME_L,
TIME_R,
FEEDBACK,
TONE,
UNKNOWN
};
AudioEffectDelay(float32_t samplerate); AudioEffectDelay(float32_t samplerate);
virtual ~AudioEffectDelay(); virtual ~AudioEffectDelay();
virtual unsigned getId(); virtual unsigned getId();
virtual void setParameter(unsigned param, unsigned value);
virtual unsigned getParameter(unsigned param);
protected: protected:
virtual void doProcess(const float32_t* inblockL, const float32_t* inblockR, float32_t* outblockL, float32_t* outblockR, uint16_t len); virtual void doProcess(const float32_t* inblockL, const float32_t* inblockR, float32_t* outblockL, float32_t* outblockR, uint16_t len);
private: private:
@ -23,6 +35,7 @@ private:
float32_t timeL; // Left delay time in seconds (0.0 - 2.0) float32_t timeL; // Left delay time in seconds (0.0 - 2.0)
float32_t timeR; // Right delay time in seconds (0.0 - 2.0) float32_t timeR; // Right delay time in seconds (0.0 - 2.0)
float32_t feedback; // Feedback (0.0 - 1.0) float32_t feedback; // Feedback (0.0 - 1.0)
AudioEffectLPF* lpf;
}; };
#endif // _EFFECT_DELAY_H #endif // _EFFECT_DELAY_H

@ -11,14 +11,37 @@ public:
static constexpr float32_t MIN_RES = 0.0f; static constexpr float32_t MIN_RES = 0.0f;
static constexpr float32_t MAX_RES = 1.0f; static constexpr float32_t MAX_RES = 1.0f;
struct LPFState
{
float32_t y1;
float32_t y2;
float32_t y3;
float32_t y4;
float32_t oldx;
float32_t oldy1;
float32_t oldy2;
float32_t oldy3;
};
enum Param
{
CUTOFF,
RESONANCE,
UNKNOWN
};
AudioEffectLPF(float32_t samplerate) : AudioEffect(samplerate) AudioEffectLPF(float32_t samplerate) : AudioEffect(samplerate)
{ {
// Setup init values // Setup init values
this->setCutoff(2000.0f); this->setCutoff(2000.0f);
this->setResonance(MIN_RES); this->setResonance(MIN_RES);
this->stateL = new LPFState();
this->stateR = new LPFState();
} }
virtual ~AudioEffectLPF() virtual ~AudioEffectLPF()
{ {
delete this->stateL;
delete this->stateR;
} }
virtual unsigned getId() virtual unsigned getId()
@ -26,6 +49,60 @@ public:
return EFFECT_LPF; return EFFECT_LPF;
} }
virtual void setParameter(unsigned param, unsigned value)
{
switch (param)
{
case AudioEffectLPF::Param::CUTOFF:
this->setCutoff(((float32_t) value / 100.0f) * MAX_CUTOFF);
break;
case AudioEffectLPF::Param::RESONANCE:
this->setResonance((float32_t) value / 100.0f);
break;
default:
break;
}
}
virtual unsigned getParameter(unsigned param)
{
switch (param)
{
case AudioEffectLPF::Param::CUTOFF:
return roundf((this->cutoff / MAX_CUTOFF) * 100);
case AudioEffectLPF::Param::RESONANCE:
return roundf(this->resonance * 100);
default:
return 0;
}
}
float32_t processSampleL(float32_t input)
{
return processSample(input, this->stateL);
}
float32_t processSampleR(float32_t input)
{
return processSample(input, this->stateR);
}
protected:
virtual void doProcess(const float32_t* inblockL, const float32_t* inblockR, float32_t* outblockL, float32_t* outblockR, uint16_t len)
{
for (int i = 0; i < len; i++) {
outblockL[i] = processSampleL(inblockL[i]);
outblockR[i] = processSampleR(inblockR[i]);
}
}
private:
float32_t cutoff;
float32_t resonance;
float32_t r, p, k;
LPFState* stateL;
LPFState* stateR;
/** /**
* Set the static cutoff frequency of the filter. * Set the static cutoff frequency of the filter.
* Cutoff frequency must be between MIN_CUTOFF and MAX_CUTOFF. * Cutoff frequency must be between MIN_CUTOFF and MAX_CUTOFF.
@ -56,23 +133,6 @@ public:
recalculate(); recalculate();
} }
protected:
virtual void doProcess(const float32_t* inblockL, const float32_t* inblockR, float32_t* outblockL, float32_t* outblockR, uint16_t len)
{
for (int i = 0; i < len; i++) {
// Get a sample to process
float32_t s = inblockL[i];
// Return processed sample from filter
outblockL[i] = processSample(s);
}
}
private:
float32_t cutoff;
float32_t resonance;
float32_t x, r, p, k, y1, y2, y3, y4, oldx, oldy1, oldy2, oldy3;
/** /**
* Recalculate filter parameters on changes to cutoff or resonance * Recalculate filter parameters on changes to cutoff or resonance
*/ */
@ -90,11 +150,19 @@ private:
/** /**
* Process a single sample through the filter * Process a single sample through the filter
*/ */
float32_t processSample(float32_t input) float32_t processSample(float32_t input, LPFState* state)
{ {
float32_t y1 = state->y1;
float32_t y2 = state->y2;
float32_t y3 = state->y3;
float32_t y4 = state->y4;
float32_t oldx = state->oldx;
float32_t oldy1 = state->oldy1;
float32_t oldy2 = state->oldy2;
float32_t oldy3 = state->oldy3;
// Process input // Process input
//x = ((float32_t) input/ F32_MAX) - r * y4; float32_t x = input - r * y4;
x = input - r * y4;
// Four cascaded one pole filters (bilinear transform) // Four cascaded one pole filters (bilinear transform)
y1 = x * p + oldx * p - k * y1; y1 = x * p + oldx * p - k * y1;
@ -105,11 +173,15 @@ private:
// Clipper band limited sigmoid // Clipper band limited sigmoid
y4 -= (y4 * y4 * y4) / 6.0; y4 -= (y4 * y4 * y4) / 6.0;
oldx = x; state->y1 = y1;
oldy1 = y1; state->y2 = y2;
oldy2 = y2; state->y3 = y3;
oldy3 = y3; state->y4 = y4;
//return (float32_t) (y4 * F32_MAX); state->oldx = x;
state->oldy1 = y1;
state->oldy2 = y2;
state->oldy3 = y3;
return y4; return y4;
} }
}; };

@ -946,11 +946,6 @@ void CMiniDexed::SetTGParameter (TTGParameter Parameter, int nValue, unsigned nT
case TGParameterReverbSend: SetReverbSend (nValue, nTG); break; case TGParameterReverbSend: SetReverbSend (nValue, nTG); break;
case TGParameterInsertFXType: setInsertFXType(nValue, nTG); break; case TGParameterInsertFXType: setInsertFXType(nValue, nTG); break;
case TGParameterFXChorusI: setChorusIEnable(nTG, nValue); break;
case TGParameterFXChorusII: setChorusIIEnable(nTG, nValue); break;
case TGParameterFXChorusIRate: setChorusIRate(nTG, nValue); break;
case TGParameterFXChorusIIRate: setChorusIIRate(nTG, nValue); break;
default: default:
assert (0); assert (0);
break; break;
@ -1002,17 +997,26 @@ int CMiniDexed::GetTGParameter (TTGParameter Parameter, unsigned nTG)
case TGParameterATAmplitude: return getModController(3, 2, nTG); case TGParameterATAmplitude: return getModController(3, 2, nTG);
case TGParameterATEGBias: return getModController(3, 3, nTG); case TGParameterATEGBias: return getModController(3, 3, nTG);
case TGParameterFXChorusI: return getChorusIEnable(nTG);
case TGParameterFXChorusII: return getChorusIIEnable(nTG);
case TGParameterFXChorusIRate: return getChorusIRate(nTG);
case TGParameterFXChorusIIRate: return getChorusIIRate(nTG);
default: default:
assert (0); assert (0);
return 0; return 0;
} }
} }
void CMiniDexed::SetTGFXParameter (unsigned Parameter, int nValue, unsigned nTG, unsigned nFXType) {
assert (nTG < CConfig::ToneGenerators);
assert (m_InsertFX[nTG]->getId() == nFXType);
m_InsertFX[nTG]->setParameter(Parameter, nValue);
}
int CMiniDexed::GetTGFXParameter (unsigned Parameter, unsigned nTG, unsigned nFXType) {
assert (nTG < CConfig::ToneGenerators);
assert (m_InsertFX[nTG]->getId() == nFXType);
return m_InsertFX[nTG]->getParameter(Parameter);;
}
void CMiniDexed::SetVoiceParameter (uint8_t uchOffset, uint8_t uchValue, unsigned nOP, unsigned nTG) void CMiniDexed::SetVoiceParameter (uint8_t uchOffset, uint8_t uchValue, unsigned nOP, unsigned nTG)
{ {
assert (nTG < CConfig::ToneGenerators); assert (nTG < CConfig::ToneGenerators);
@ -1982,102 +1986,3 @@ unsigned CMiniDexed::getModController (unsigned controller, unsigned parameter,
} }
unsigned CMiniDexed::getChorusIEnable (uint8_t nTG)
{
AudioEffect* effect = m_InsertFX[nTG];
if (effect->getId() != EFFECT_CHORUS) {
return 0;
}
AudioEffectChorus* chorus = (AudioEffectChorus*) effect;
return chorus->getChorusI();
}
void CMiniDexed::setChorusIEnable (uint8_t nTG, unsigned enable)
{
m_InsertFXSpinLock[nTG]->Acquire();
AudioEffect* effect = m_InsertFX[nTG];
if (effect->getId() != EFFECT_CHORUS) {
m_InsertFXSpinLock[nTG]->Release();
return;
}
AudioEffectChorus* chorus = (AudioEffectChorus*) effect;
chorus->setChorusI(enable);
m_InsertFXSpinLock[nTG]->Release();
}
unsigned CMiniDexed::getChorusIIEnable (uint8_t nTG)
{
AudioEffect* effect = m_InsertFX[nTG];
if (effect->getId() != EFFECT_CHORUS) {
return 0;
}
AudioEffectChorus* chorus = (AudioEffectChorus*) effect;
return chorus->getChorusII();
}
void CMiniDexed::setChorusIIEnable (uint8_t nTG, unsigned enable)
{
m_InsertFXSpinLock[nTG]->Acquire();
AudioEffect* effect = m_InsertFX[nTG];
if (effect->getId() != EFFECT_CHORUS) {
m_InsertFXSpinLock[nTG]->Release();
return;
}
AudioEffectChorus* chorus = (AudioEffectChorus*) effect;
chorus->setChorusII(enable);
m_InsertFXSpinLock[nTG]->Release();
}
unsigned CMiniDexed::getChorusIRate (uint8_t nTG)
{
AudioEffect* effect = m_InsertFX[nTG];
if (effect->getId() != EFFECT_CHORUS) {
return 0;
}
AudioEffectChorus* chorus = (AudioEffectChorus*) effect;
return chorus->getChorusIRate();
}
void CMiniDexed::setChorusIRate (uint8_t nTG, unsigned int rate)
{
m_InsertFXSpinLock[nTG]->Acquire();
AudioEffect* effect = m_InsertFX[nTG];
if (effect->getId() != EFFECT_CHORUS) {
m_InsertFXSpinLock[nTG]->Release();
return;
}
AudioEffectChorus* chorus = (AudioEffectChorus*) effect;
chorus->setChorusIRate(rate);
m_InsertFXSpinLock[nTG]->Release();
}
unsigned CMiniDexed::getChorusIIRate (uint8_t nTG)
{
AudioEffect* effect = m_InsertFX[nTG];
if (effect->getId() != EFFECT_CHORUS) {
return 0;
}
AudioEffectChorus* chorus = (AudioEffectChorus*) effect;
return chorus->getChorusIIRate();
}
void CMiniDexed::setChorusIIRate (uint8_t nTG, unsigned int rate)
{
m_InsertFXSpinLock[nTG]->Acquire();
AudioEffect* effect = m_InsertFX[nTG];
if (effect->getId() != EFFECT_CHORUS) {
m_InsertFXSpinLock[nTG]->Release();
return;
}
AudioEffectChorus* chorus = (AudioEffectChorus*) effect;
chorus->setChorusIIRate(rate);
m_InsertFXSpinLock[nTG]->Release();
}

@ -214,17 +214,15 @@ public:
TGParameterATAmplitude, TGParameterATAmplitude,
TGParameterATEGBias, TGParameterATEGBias,
TGParameterFXChorusI,
TGParameterFXChorusIRate,
TGParameterFXChorusII,
TGParameterFXChorusIIRate,
TGParameterUnknown TGParameterUnknown
}; };
void SetTGParameter (TTGParameter Parameter, int nValue, unsigned nTG); void SetTGParameter (TTGParameter Parameter, int nValue, unsigned nTG);
int GetTGParameter (TTGParameter Parameter, unsigned nTG); int GetTGParameter (TTGParameter Parameter, unsigned nTG);
void SetTGFXParameter (unsigned Parameter, int nValue, unsigned nTG, unsigned nFXType);
int GetTGFXParameter (unsigned Parameter, unsigned nTG, unsigned nFXType);
// access (global or OP-related) parameter of the active voice of a TG // access (global or OP-related) parameter of the active voice of a TG
static const unsigned NoOP = 6; // for global parameters static const unsigned NoOP = 6; // for global parameters
void SetVoiceParameter (uint8_t uchOffset, uint8_t uchValue, unsigned nOP, unsigned nTG); void SetVoiceParameter (uint8_t uchOffset, uint8_t uchValue, unsigned nOP, unsigned nTG);

@ -152,10 +152,26 @@ const CUIMenu::TMenuItem CUIMenu::s_FXNone[] =
const CUIMenu::TMenuItem CUIMenu::s_FXChorus[] = const CUIMenu::TMenuItem CUIMenu::s_FXChorus[] =
{ {
{"Chorus I", EditTGParameter2, 0, CMiniDexed::TGParameterFXChorusI}, {"Chorus I", EditTGFXParameter, 0, AudioEffectChorus::Param::CHORUS_I_ENABLE},
{"Chorus II", EditTGParameter2, 0, CMiniDexed::TGParameterFXChorusII}, {"Chorus II", EditTGFXParameter, 0, AudioEffectChorus::Param::CHORUS_II_ENABLE},
{"Rate I", EditTGParameter2, 0, CMiniDexed::TGParameterFXChorusIRate}, {"Rate I", EditTGFXParameter, 0, AudioEffectChorus::Param::CHORUS_I_RATE},
{"Rate II", EditTGParameter2, 0, CMiniDexed::TGParameterFXChorusIIRate}, {"Rate II", EditTGFXParameter, 0, AudioEffectChorus::Param::CHORUS_II_RATE},
{0}
};
const CUIMenu::TMenuItem CUIMenu::s_FXDelay[] =
{
{"Time L", EditTGFXParameter, 0, AudioEffectDelay::Param::TIME_L},
{"Time R", EditTGFXParameter, 0, AudioEffectDelay::Param::TIME_R},
{"Feedback", EditTGFXParameter, 0, AudioEffectDelay::Param::FEEDBACK},
{"Tone", EditTGFXParameter, 0, AudioEffectDelay::Param::TONE},
{0}
};
const CUIMenu::TMenuItem CUIMenu::s_FXLPFilter[] =
{
{"Cutoff", EditTGFXParameter, 0, AudioEffectLPF::Param::CUTOFF},
{"Resonance", EditTGFXParameter, 0, AudioEffectLPF::Param::RESONANCE},
{0} {0}
}; };
@ -277,12 +293,32 @@ const CUIMenu::TParameter CUIMenu::s_TGParameter[CMiniDexed::TGParameterUnknown]
{0, 99, 1}, //AT Range {0, 99, 1}, //AT Range
{0, 1, 1, ToOnOff}, //AT Pitch {0, 1, 1, ToOnOff}, //AT Pitch
{0, 1, 1, ToOnOff}, //AT Amp {0, 1, 1, ToOnOff}, //AT Amp
{0, 1, 1, ToOnOff}, //AT EGBias {0, 1, 1, ToOnOff} //AT EGBias
};
{0, 1, 1, ToOnOff}, // TGParameterFXChorusI // must match AudioEffectChorus::Param
{0, 100, 1}, // TGParameterFXChorusIRate const CUIMenu::TParameter CUIMenu::s_TGFXChorusParam[AudioEffectChorus::Param::UNKNOWN] =
{0, 1, 1, ToOnOff}, // TGParameterFXChorusII {
{0, 100, 1}, // TGParameterFXChorusIIRate {0, 1, 1, ToOnOff}, // CHORUS_I_ENABLE
{0, 1, 1, ToOnOff}, // CHORUS_II_ENABLE
{0, 100, 1}, // CHORUS_I_RATE,
{0, 100, 1} // CHORUS_II_RATE
};
// must match AudioEffectDelay::Param
const CUIMenu::TParameter CUIMenu::s_TGFXDelayParam[AudioEffectDelay::Param::UNKNOWN] =
{
{0, AudioEffectDelay::MAX_DELAY_TIME * 1000, 1}, // TIME_L
{0, AudioEffectDelay::MAX_DELAY_TIME * 1000, 1}, // TIME_R
{0, 100, 1}, // FEEDBACK,
{0, 100, 1} // TONE
};
// must match AudioEffectLPF::Param
const CUIMenu::TParameter CUIMenu::s_TGFXLPFParam[AudioEffectLPF::Param::UNKNOWN] =
{
{0, 100, 1}, // CUTOFF
{0, 100, 1} // RESONANCE
}; };
// must match DexedVoiceParameters in Synth_Dexed // must match DexedVoiceParameters in Synth_Dexed
@ -792,6 +828,14 @@ void CUIMenu::EditInsertFX (CUIMenu *pUIMenu, TMenuEvent Event)
pUIMenu->m_pCurrentMenu = s_FXChorus; pUIMenu->m_pCurrentMenu = s_FXChorus;
break; break;
case EFFECT_DELAY:
pUIMenu->m_pCurrentMenu = s_FXDelay;
break;
case EFFECT_LPF:
pUIMenu->m_pCurrentMenu = s_FXLPFilter;
break;
default: default:
pUIMenu->m_pCurrentMenu = s_FXNone; pUIMenu->m_pCurrentMenu = s_FXNone;
break; break;
@ -857,6 +901,89 @@ void CUIMenu::EditInsertFX (CUIMenu *pUIMenu, TMenuEvent Event)
} }
} }
void CUIMenu::EditTGFXParameter (CUIMenu *pUIMenu, TMenuEvent Event)
{
// Get TG
unsigned nTG = pUIMenu->m_nMenuStackParameter[pUIMenu->m_nCurrentMenuDepth-2];
// Get FX type
int nFXType = pUIMenu->m_pMiniDexed->GetTGParameter(CMiniDexed::TGParameterInsertFXType, nTG);
// Get Param
unsigned nParam = pUIMenu->m_nCurrentParameter;
TParameter pParam;
switch (nFXType)
{
case EFFECT_CHORUS:
pParam = s_TGFXChorusParam[nParam];
break;
case EFFECT_DELAY:
pParam = s_TGFXDelayParam[nParam];
break;
case EFFECT_LPF:
pParam = s_TGFXLPFParam[nParam];
break;
default:
return;
}
const TParameter &rParam = pParam;
int nValue = pUIMenu->m_pMiniDexed->GetTGFXParameter (nParam, nTG, nFXType);
switch (Event)
{
case MenuEventUpdate:
break;
case MenuEventStepDown:
nValue -= rParam.Increment;
if (nValue < rParam.Minimum)
{
nValue = rParam.Minimum;
}
pUIMenu->m_pMiniDexed->SetTGFXParameter (nParam, nValue, nTG, nFXType);
break;
case MenuEventStepUp:
nValue += rParam.Increment;
if (nValue > rParam.Maximum)
{
nValue = rParam.Maximum;
}
pUIMenu->m_pMiniDexed->SetTGFXParameter (nParam, nValue, nTG, nFXType);
break;
case MenuEventPressAndStepDown:
case MenuEventPressAndStepUp:
pUIMenu->TGShortcutHandler (Event);
return;
default:
return;
}
string TG ("TG");
TG += to_string (nTG+1);
// Get value again after change
nValue = pUIMenu->m_pMiniDexed->GetTGFXParameter (nParam, nTG, nFXType);
CUIMenu::TToString *pToString = rParam.ToString;
string Value;
if (pToString)
{
Value = (*pToString) (nValue);
}
else
{
Value = to_string (nValue);
}
pUIMenu->m_pUI->DisplayWrite (TG.c_str (),
pUIMenu->m_pParentMenu[pUIMenu->m_nCurrentMenuItem].Name,
Value.c_str (),
nValue > rParam.Minimum, nValue < rParam.Maximum);
}
void CUIMenu::EditVoiceParameter (CUIMenu *pUIMenu, TMenuEvent Event) void CUIMenu::EditVoiceParameter (CUIMenu *pUIMenu, TMenuEvent Event)
{ {
unsigned nTG = pUIMenu->m_nMenuStackParameter[pUIMenu->m_nCurrentMenuDepth-2]; unsigned nTG = pUIMenu->m_nMenuStackParameter[pUIMenu->m_nCurrentMenuDepth-2];

@ -94,6 +94,7 @@ private:
static void EditPerformanceBankNumber (CUIMenu *pUIMenu, TMenuEvent Event); static void EditPerformanceBankNumber (CUIMenu *pUIMenu, TMenuEvent Event);
static void EditInsertFX (CUIMenu *pUIMenu, TMenuEvent Event); static void EditInsertFX (CUIMenu *pUIMenu, TMenuEvent Event);
static void EditTGFXParameter (CUIMenu *pUIMenu, TMenuEvent Event);
static std::string GetGlobalValueString (unsigned nParameter, int nValue); static std::string GetGlobalValueString (unsigned nParameter, int nValue);
static std::string GetTGValueString (unsigned nTGParameter, int nValue); static std::string GetTGValueString (unsigned nTGParameter, int nValue);
@ -153,6 +154,8 @@ private:
static const TMenuItem s_InsertFX[]; static const TMenuItem s_InsertFX[];
static const TMenuItem s_FXNone[]; static const TMenuItem s_FXNone[];
static const TMenuItem s_FXChorus[]; static const TMenuItem s_FXChorus[];
static const TMenuItem s_FXDelay[];
static const TMenuItem s_FXLPFilter[];
static const TMenuItem s_EditVoiceMenu[]; static const TMenuItem s_EditVoiceMenu[];
static const TMenuItem s_OperatorMenu[]; static const TMenuItem s_OperatorMenu[];
static const TMenuItem s_SaveMenu[]; static const TMenuItem s_SaveMenu[];
@ -165,6 +168,9 @@ private:
static const TParameter s_GlobalParameter[]; static const TParameter s_GlobalParameter[];
static const TParameter s_TGParameter[]; static const TParameter s_TGParameter[];
static const TParameter s_TGFXChorusParam[];
static const TParameter s_TGFXDelayParam[];
static const TParameter s_TGFXLPFParam[];
static const TParameter s_VoiceParameter[]; static const TParameter s_VoiceParameter[];
static const TParameter s_OPParameter[]; static const TParameter s_OPParameter[];

Loading…
Cancel
Save