Skip to content

Implement Unison Mode in Synth_Dexed #901

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions src/common.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@

#ifndef _common_h
#define _common_h

#include <stdint.h>

inline long maplong(long x, long in_min, long in_max, long out_min, long out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
Expand All @@ -16,11 +17,11 @@ inline float32_t mapfloat(int val, int in_min, int in_max, float32_t out_min, fl
return (val - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

#define constrain(amt, low, high) ({ \
__typeof__(amt) _amt = (amt); \
__typeof__(low) _low = (low); \
__typeof__(high) _high = (high); \
(_amt < _low) ? _low : ((_amt > _high) ? _high : _amt); \
})
template<typename T>
// Code that used to use constrain shall use clamp instead
// This was renamed to avoid conflicts with the Synth_Dexed submodule
inline T clamp(T amt, T low, T high) {
return (amt < low) ? low : ((amt > high) ? high : amt);
}

#endif
46 changes: 43 additions & 3 deletions src/dexedadapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@

class CDexedAdapter : public Dexed
{
private:
CSpinLock m_SpinLock;
public:
CDexedAdapter (uint8_t maxnotes, int rate)
: Dexed (maxnotes, rate)
Expand Down Expand Up @@ -80,8 +82,46 @@ class CDexedAdapter : public Dexed
m_SpinLock.Release ();
}

private:
CSpinLock m_SpinLock;
};
// Unison wrapper: for now, simulate unison by calling keydown/keyup multiple times with detune/pan offsets
void keydown_unison(int16_t pitch, uint8_t velo, unsigned unisonVoices, unsigned unisonDetune, unsigned unisonSpread, int baseDetune, unsigned basePan) {
if (unisonVoices < 1) unisonVoices = 1;
for (unsigned v = 0; v < unisonVoices; ++v) {
float detuneOffset = ((float)v - (unisonVoices - 1) / 2.0f) * (float)unisonDetune;
int detune = baseDetune + (int)detuneOffset;
m_SpinLock.Acquire();
this->setMasterTune((int8_t)detune);
Dexed::keydown(pitch, velo);
m_SpinLock.Release();
}
}
void keyup_unison(int16_t pitch, unsigned unisonVoices, unsigned unisonDetune, unsigned unisonSpread, int baseDetune, unsigned basePan) {
if (unisonVoices < 1) unisonVoices = 1;
for (unsigned v = 0; v < unisonVoices; ++v) {
float detuneOffset = ((float)v - (unisonVoices - 1) / 2.0f) * (float)unisonDetune;
int detune = baseDetune + (int)detuneOffset;
m_SpinLock.Acquire();
this->setMasterTune((int8_t)detune);
Dexed::keyup(pitch);
m_SpinLock.Release();
}
}

#ifdef ARM_ALLOW_MULTI_CORE
// Stereo version for unison pan
void getSamplesStereo(float32_t* bufferL, float32_t* bufferR, uint16_t n_samples) {
m_SpinLock.Acquire();
Dexed::getSamplesStereo(bufferL, bufferR, n_samples);
m_SpinLock.Release();
}
// Set unison parameters for Dexed, now with base pan
void setUnisonParameters(unsigned voices, unsigned detune, unsigned spread, float basePan) {
m_SpinLock.Acquire();
// Map detune: 0..99 -> 0..0.02 (2 cents)
float detuneCents = ((float)detune / 99.0f) * 0.02f;
Dexed::setUnisonParameters((uint8_t)voices, detuneCents, (float)spread / 99.0f, basePan);
m_SpinLock.Release();
}
#endif
};

#endif // _dexedadapter_h
12 changes: 6 additions & 6 deletions src/effect_platervbstereo.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class AudioEffectPlateReverb

void size(float n)
{
n = constrain(n, 0.0f, 1.0f);
n = clamp(n, 0.0f, 1.0f);
n = mapfloat(n, 0.0f, 1.0f, 0.2f, rv_time_k_max);
float32_t attn = mapfloat(n, 0.0f, rv_time_k_max, 0.5f, 0.25f);
rv_time_k = n;
Expand All @@ -73,35 +73,35 @@ class AudioEffectPlateReverb

void hidamp(float n)
{
n = constrain(n, 0.0f, 1.0f);
n = clamp(n, 0.0f, 1.0f);
lp_hidamp_k = 1.0f - n;
}

void lodamp(float n)
{
n = constrain(n, 0.0f, 1.0f);
n = clamp(n, 0.0f, 1.0f);
lp_lodamp_k = -n;
rv_time_scaler = 1.0f - n * 0.12f; // limit the max reverb time, otherwise it will clip
}

void lowpass(float n)
{
n = constrain(n, 0.0f, 1.0f);
n = clamp(n, 0.0f, 1.0f);
n = mapfloat(n*n*n, 0.0f, 1.0f, 0.05f, 1.0f);
master_lowpass_f = n;
}

void diffusion(float n)
{
n = constrain(n, 0.0f, 1.0f);
n = clamp(n, 0.0f, 1.0f);
n = mapfloat(n, 0.0f, 1.0f, 0.005f, 0.65f);
in_allp_k = n;
loop_allp_k = n;
}

void level(float n)
{
reverb_level = constrain(n, 0.0f, 1.0f);
reverb_level = clamp(n, 0.0f, 1.0f);
}

float32_t get_size(void) {return rv_time_k;}
Expand Down
Loading
Loading