mirror of
https://github.com/AquaMorph/Droplets.git
synced 2025-04-29 17:35:33 +00:00
AD envelope with splitting
This commit is contained in:
parent
1ab75579c5
commit
5cc3195db3
@ -2,16 +2,15 @@
|
|||||||
|
|
||||||
void AD::Init(DaisyPatch* m_patch,
|
void AD::Init(DaisyPatch* m_patch,
|
||||||
float sample_rate,
|
float sample_rate,
|
||||||
AnalogControl attack_knob,
|
DropletState* m_state) {
|
||||||
AnalogControl decay_knob) {
|
|
||||||
patch = m_patch;
|
patch = m_patch;
|
||||||
|
state = m_state;
|
||||||
env.Init(sample_rate);
|
env.Init(sample_rate);
|
||||||
env.SetMax(1.0f);
|
env.SetMax(1.0f);
|
||||||
env.SetMin(0.0f);
|
env.SetMin(0.0f);
|
||||||
env.SetCurve(0.0f);
|
env.SetCurve(0.0f);
|
||||||
attack_param.Init(attack_knob, .01f, 3.0f, Parameter::EXPONENTIAL);
|
|
||||||
decay_param.Init(decay_knob, .01f, 3.0f, Parameter::EXPONENTIAL);
|
SetControls();
|
||||||
curve_param.Init(attack_knob, -10.f, 10.0f, Parameter::LINEAR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AD::Process(DacHandle::Channel chn,
|
void AD::Process(DacHandle::Channel chn,
|
||||||
@ -19,19 +18,26 @@ void AD::Process(DacHandle::Channel chn,
|
|||||||
if(patch->gate_input[gate].Trig()) {
|
if(patch->gate_input[gate].Trig()) {
|
||||||
env.Trigger();
|
env.Trigger();
|
||||||
}
|
}
|
||||||
if (curve_menu) {
|
if (*state == DropletState::kFull) {
|
||||||
|
attack = attack_param.Process();
|
||||||
|
decay = decay_param.Process();
|
||||||
curve = curve_param.Process();
|
curve = curve_param.Process();
|
||||||
|
amp = amp_param.Process();
|
||||||
|
} else if (curve_menu) {
|
||||||
|
curve = curve_param.Process();
|
||||||
|
amp = amp_param.Process();
|
||||||
} else {
|
} else {
|
||||||
attack = attack_param.Process();
|
attack = attack_param.Process();
|
||||||
|
decay = decay_param.Process();
|
||||||
}
|
}
|
||||||
decay = decay_param.Process();
|
|
||||||
env.SetTime(ADENV_SEG_ATTACK, attack);
|
env.SetTime(ADENV_SEG_ATTACK, attack);
|
||||||
env.SetTime(ADENV_SEG_DECAY, decay);
|
env.SetTime(ADENV_SEG_DECAY, decay);
|
||||||
env.SetCurve(curve);
|
env.SetCurve(curve);
|
||||||
|
|
||||||
sig = env.Process();
|
sig = env.Process();
|
||||||
patch->seed.dac.WriteValue(chn,
|
patch->seed.dac.WriteValue(chn,
|
||||||
sig * 4095.0f);
|
sig * amp * 4095.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
float AD::GetSignal() {
|
float AD::GetSignal() {
|
||||||
@ -50,6 +56,10 @@ float AD::GetCurve() {
|
|||||||
return curve;
|
return curve;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float AD::GetAmp() {
|
||||||
|
return amp;
|
||||||
|
}
|
||||||
|
|
||||||
bool AD::GetMenu() {
|
bool AD::GetMenu() {
|
||||||
return curve_menu;
|
return curve_menu;
|
||||||
}
|
}
|
||||||
@ -58,36 +68,51 @@ void AD::ToggleCurve() {
|
|||||||
curve_menu = !curve_menu;
|
curve_menu = !curve_menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
ADDroplet::ADDroplet(DaisyPatch* m_patch,
|
void AD::SetControls() {
|
||||||
DropletState m_state,
|
AnalogControl attack_knob, decay_knob, curve_knob, amp_knob;
|
||||||
float sample_rate) :
|
|
||||||
Droplet(m_patch,
|
switch (*state) {
|
||||||
m_state) {
|
|
||||||
switch (GetState()) {
|
|
||||||
default:
|
default:
|
||||||
case DropletState::kFull:
|
case DropletState::kFull:
|
||||||
ad[0].Init(Patch(),
|
attack_knob = patch->controls[patch->CTRL_1];
|
||||||
sample_rate,
|
decay_knob = patch->controls[patch->CTRL_2];
|
||||||
Patch()->controls[Patch()->CTRL_1],
|
curve_knob = patch->controls[patch->CTRL_3];
|
||||||
Patch()->controls[Patch()->CTRL_2]);
|
amp_knob = patch->controls[patch->CTRL_4];
|
||||||
ad[1].Init(Patch(),
|
|
||||||
sample_rate,
|
|
||||||
Patch()->controls[Patch()->CTRL_3],
|
|
||||||
Patch()->controls[Patch()->CTRL_4]);
|
|
||||||
break;
|
break;
|
||||||
case DropletState::kLeft:
|
case DropletState::kLeft:
|
||||||
ad[0].Init(Patch(),
|
attack_knob = patch->controls[patch->CTRL_1];
|
||||||
sample_rate,
|
decay_knob = patch->controls[patch->CTRL_2];
|
||||||
Patch()->controls[Patch()->CTRL_1],
|
curve_knob = patch->controls[patch->CTRL_1];
|
||||||
Patch()->controls[Patch()->CTRL_2]);
|
amp_knob = patch->controls[patch->CTRL_2];
|
||||||
break;
|
break;
|
||||||
case DropletState::kRight:
|
case DropletState::kRight:
|
||||||
ad[0].Init(Patch(),
|
attack_knob = patch->controls[patch->CTRL_3];
|
||||||
sample_rate,
|
decay_knob = patch->controls[patch->CTRL_4];
|
||||||
Patch()->controls[Patch()->CTRL_3],
|
curve_knob = patch->controls[patch->CTRL_3];
|
||||||
Patch()->controls[Patch()->CTRL_4]);
|
amp_knob = patch->controls[patch->CTRL_4];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
attack_param.Init(attack_knob, .01f, 3.0f, Parameter::EXPONENTIAL);
|
||||||
|
decay_param.Init(decay_knob, .01f, 3.0f, Parameter::EXPONENTIAL);
|
||||||
|
curve_param.Init(curve_knob, -10.f, 10.0f, Parameter::LINEAR);
|
||||||
|
amp_param.Init(amp_knob, 0.0f, 1.0f, Parameter::LINEAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
ADDroplet::ADDroplet(DaisyPatch* m_patch,
|
||||||
|
DropletState m_state,
|
||||||
|
float m_sample_rate) :
|
||||||
|
Droplet(m_patch,
|
||||||
|
m_state) {
|
||||||
|
sample_rate = m_sample_rate;
|
||||||
|
ad[0].Init(Patch(),
|
||||||
|
sample_rate,
|
||||||
|
&m_state);
|
||||||
|
if (m_state == DropletState::kFull) {
|
||||||
|
ad[1].Init(Patch(),
|
||||||
|
sample_rate,
|
||||||
|
&m_state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ADDroplet::~ADDroplet() {}
|
ADDroplet::~ADDroplet() {}
|
||||||
@ -105,7 +130,6 @@ void ADDroplet::Control() {
|
|||||||
|
|
||||||
void ADDroplet::Process(AudioHandle::InputBuffer in, AudioHandle::OutputBuffer out, size_t size) {
|
void ADDroplet::Process(AudioHandle::InputBuffer in, AudioHandle::OutputBuffer out, size_t size) {
|
||||||
Patch()->ProcessAnalogControls();
|
Patch()->ProcessAnalogControls();
|
||||||
|
|
||||||
for(size_t i = 0; i < size; i++) {
|
for(size_t i = 0; i < size; i++) {
|
||||||
if (GetState() == DropletState::kRight) {
|
if (GetState() == DropletState::kRight) {
|
||||||
ad[0].Process(DacHandle::Channel::TWO, DaisyPatch::GATE_IN_2);
|
ad[0].Process(DacHandle::Channel::TWO, DaisyPatch::GATE_IN_2);
|
||||||
@ -120,7 +144,8 @@ void ADDroplet::Process(AudioHandle::InputBuffer in, AudioHandle::OutputBuffer o
|
|||||||
if(GetState() == DropletState::kFull && chn > 1) {
|
if(GetState() == DropletState::kFull && chn > 1) {
|
||||||
env_sel = 1;
|
env_sel = 1;
|
||||||
}
|
}
|
||||||
out[chn][i] = in[chn][i] * ad[env_sel].GetSignal();
|
out[chn][i] = in[chn][i] * ad[env_sel].GetSignal() *
|
||||||
|
ad[env_sel].GetAmp();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -146,36 +171,31 @@ void ADDroplet::Draw() {
|
|||||||
Font_6x8,
|
Font_6x8,
|
||||||
"C: " +
|
"C: " +
|
||||||
FloatToString(ad[0].GetCurve(), 2));
|
FloatToString(ad[0].GetCurve(), 2));
|
||||||
if(GetState() == DropletState::kFull) {
|
WriteString(Patch(),
|
||||||
int mid = (GetScreenMax() - GetScreenMin())/2;
|
GetScreenMin()+3,
|
||||||
WriteString(Patch(),
|
41,
|
||||||
mid,
|
Font_6x8,
|
||||||
11,
|
"Amp: " +
|
||||||
Font_6x8,
|
FloatToString(ad[0].GetAmp(), 2));
|
||||||
"A: " +
|
|
||||||
FloatToString(ad[1].GetAttack(), 2) +
|
|
||||||
"s");
|
|
||||||
WriteString(Patch(),
|
|
||||||
mid,
|
|
||||||
21,
|
|
||||||
Font_6x8,
|
|
||||||
"D: " +
|
|
||||||
FloatToString(ad[1].GetDecay(), 2) +
|
|
||||||
"s");
|
|
||||||
WriteString(Patch(),
|
|
||||||
mid,
|
|
||||||
31,
|
|
||||||
Font_6x8,
|
|
||||||
"C: " +
|
|
||||||
FloatToString(ad[1].GetCurve(), 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ad[0].GetMenu()) {
|
if (GetState() != DropletState::kFull) {
|
||||||
DrawSolidRect(Patch(), GetScreenMin(), 30, GetScreenMin()+1, 39, true);
|
if (ad[0].GetMenu()) {
|
||||||
} else {
|
DrawSolidRect(Patch(), GetScreenMin(), 30, GetScreenMin()+1, 49, true);
|
||||||
DrawSolidRect(Patch(), GetScreenMin(), 10, GetScreenMin()+1, 19, true);
|
} else {
|
||||||
|
DrawSolidRect(Patch(), GetScreenMin(), 10, GetScreenMin()+1, 29, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
DrawSolidRect(Patch(), GetScreenMin(), 20, GetScreenMin()+1, 29, true);
|
|
||||||
|
|
||||||
DrawName("AD");
|
DrawName("AD");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ADDroplet::UpdateStateCallback() {
|
||||||
|
ad[0].Init(Patch(),
|
||||||
|
sample_rate,
|
||||||
|
State());
|
||||||
|
if (GetState() == DropletState::kFull) {
|
||||||
|
ad[1].Init(Patch(),
|
||||||
|
sample_rate,
|
||||||
|
State());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -16,17 +16,20 @@ class AD {
|
|||||||
private:
|
private:
|
||||||
AdEnv env;
|
AdEnv env;
|
||||||
float attack, decay, curve = 0;
|
float attack, decay, curve = 0;
|
||||||
|
float amp = 1.0f;
|
||||||
Parameter attack_param;
|
Parameter attack_param;
|
||||||
Parameter decay_param;
|
Parameter decay_param;
|
||||||
Parameter curve_param;
|
Parameter curve_param;
|
||||||
|
Parameter amp_param;
|
||||||
float sig;
|
float sig;
|
||||||
DaisyPatch* patch;
|
DaisyPatch* patch;
|
||||||
bool curve_menu = false;
|
bool curve_menu = false;
|
||||||
|
DropletState* state;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void Init(DaisyPatch* m_patch,
|
void Init(DaisyPatch* m_patch,
|
||||||
float sample_rate,
|
float sample_rate,
|
||||||
AnalogControl attack_knob,
|
DropletState* state);
|
||||||
AnalogControl decay_knob);
|
|
||||||
|
|
||||||
void Process(DacHandle::Channel chn, DaisyPatch::GateInput gate);
|
void Process(DacHandle::Channel chn, DaisyPatch::GateInput gate);
|
||||||
|
|
||||||
@ -34,13 +37,16 @@ public:
|
|||||||
float GetAttack();
|
float GetAttack();
|
||||||
float GetDecay();
|
float GetDecay();
|
||||||
float GetCurve();
|
float GetCurve();
|
||||||
|
float GetAmp();
|
||||||
bool GetMenu();
|
bool GetMenu();
|
||||||
void ToggleCurve();
|
void ToggleCurve();
|
||||||
|
void SetControls();
|
||||||
};
|
};
|
||||||
|
|
||||||
class ADDroplet: public Droplet {
|
class ADDroplet: public Droplet {
|
||||||
private:
|
private:
|
||||||
AD ad[2];
|
AD ad[2];
|
||||||
|
float sample_rate;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*
|
/*
|
||||||
@ -78,6 +84,11 @@ public:
|
|||||||
* Processes information to be shown on the display.
|
* Processes information to be shown on the display.
|
||||||
*/
|
*/
|
||||||
void Draw();
|
void Draw();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Runs when droplet state is updated.
|
||||||
|
*/
|
||||||
|
void UpdateStateCallback();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CASCADE_DROPLETS_AD_DROPLET_H_
|
#endif // CASCADE_DROPLETS_AD_DROPLET_H_
|
||||||
|
@ -9,6 +9,10 @@ DaisyPatch* Droplet::Patch() {
|
|||||||
return patch;
|
return patch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DropletState* Droplet::State() {
|
||||||
|
return &state;
|
||||||
|
}
|
||||||
|
|
||||||
DropletState Droplet::GetState() {
|
DropletState Droplet::GetState() {
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
@ -51,6 +55,7 @@ void Droplet::UpdateState(DropletState m_state) {
|
|||||||
chn_min = 2;
|
chn_min = 2;
|
||||||
screen_min = SSD1309_WIDTH / 2;
|
screen_min = SSD1309_WIDTH / 2;
|
||||||
}
|
}
|
||||||
|
UpdateStateCallback();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Droplet::AnimationInc() {
|
void Droplet::AnimationInc() {
|
||||||
|
@ -47,7 +47,7 @@ public:
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Processes audio input and outputs.
|
* Processes audio input and outputs.
|
||||||
*
|
2 *
|
||||||
* @param in the audio inputs for the patch
|
* @param in the audio inputs for the patch
|
||||||
* @param out the audio outputs for the patch
|
* @param out the audio outputs for the patch
|
||||||
* @param size the number of inputs and outputs
|
* @param size the number of inputs and outputs
|
||||||
@ -62,12 +62,24 @@ public:
|
|||||||
virtual void Draw()=0;
|
virtual void Draw()=0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns patch
|
* Runs when droplet state is updated.
|
||||||
|
*/
|
||||||
|
virtual void UpdateStateCallback() {}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns patch.
|
||||||
*
|
*
|
||||||
* @return pointer to patch
|
* @return pointer to patch
|
||||||
*/
|
*/
|
||||||
DaisyPatch* Patch();
|
DaisyPatch* Patch();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns droplet state.
|
||||||
|
*
|
||||||
|
* @return pointer to state
|
||||||
|
*/
|
||||||
|
DropletState* State();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns the size of the droplet.
|
* Returns the size of the droplet.
|
||||||
*
|
*
|
||||||
|
@ -106,3 +106,5 @@ void LFODroplet::Draw() {
|
|||||||
}
|
}
|
||||||
DrawName("LFO");
|
DrawName("LFO");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LFODroplet::UpdateStateCallback() {}
|
||||||
|
@ -77,6 +77,11 @@ public:
|
|||||||
* Processes information to be shown on the display.
|
* Processes information to be shown on the display.
|
||||||
*/
|
*/
|
||||||
void Draw();
|
void Draw();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Runs when droplet state is updated.
|
||||||
|
*/
|
||||||
|
void UpdateStateCallback();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CASCADE_DROPLETS_LFO_DROPLET_H_
|
#endif // CASCADE_DROPLETS_LFO_DROPLET_H_
|
||||||
|
@ -58,3 +58,5 @@ void MixerDroplet::Process(AudioHandle::InputBuffer in, AudioHandle::OutputBuffe
|
|||||||
void MixerDroplet::Draw() {
|
void MixerDroplet::Draw() {
|
||||||
DrawName("Mixer");
|
DrawName("Mixer");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MixerDroplet::UpdateStateCallback() {}
|
||||||
|
@ -51,6 +51,11 @@ public:
|
|||||||
* Processes information to be shown on the display.
|
* Processes information to be shown on the display.
|
||||||
*/
|
*/
|
||||||
void Draw();
|
void Draw();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Runs when droplet state is updated.
|
||||||
|
*/
|
||||||
|
void UpdateStateCallback();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CASCADE_DROPLETS_VCA_DROPLET_H_
|
#endif // CASCADE_DROPLETS_VCA_DROPLET_H_
|
||||||
|
@ -26,3 +26,5 @@ void NoiseDroplet::Draw() {
|
|||||||
}
|
}
|
||||||
DrawName("Noise");
|
DrawName("Noise");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NoiseDroplet::UpdateStateCallback() {}
|
||||||
|
@ -41,6 +41,11 @@ public:
|
|||||||
* Processes information to be shown on the display.
|
* Processes information to be shown on the display.
|
||||||
*/
|
*/
|
||||||
void Draw();
|
void Draw();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Runs when droplet state is updated.
|
||||||
|
*/
|
||||||
|
void UpdateStateCallback();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CASCADE_DROPLETS_NOISE_DROPLET_H_
|
#endif // CASCADE_DROPLETS_NOISE_DROPLET_H_
|
||||||
|
@ -109,3 +109,5 @@ void VCADroplet::Draw() {
|
|||||||
}
|
}
|
||||||
DrawName("VCA");
|
DrawName("VCA");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VCADroplet::UpdateStateCallback() {}
|
||||||
|
@ -51,6 +51,11 @@ public:
|
|||||||
* Processes information to be shown on the display.
|
* Processes information to be shown on the display.
|
||||||
*/
|
*/
|
||||||
void Draw();
|
void Draw();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Runs when droplet state is updated.
|
||||||
|
*/
|
||||||
|
void UpdateStateCallback();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CASCADE_DROPLETS_VCA_DROPLET_H_
|
#endif // CASCADE_DROPLETS_VCA_DROPLET_H_
|
||||||
|
@ -144,3 +144,5 @@ void VCODroplet::SetWaveShape(int ws) {
|
|||||||
wave = ws % Oscillator::WAVE_LAST;
|
wave = ws % Oscillator::WAVE_LAST;
|
||||||
last_wave_ctrl = ws;
|
last_wave_ctrl = ws;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VCODroplet::UpdateStateCallback() {}
|
||||||
|
@ -68,6 +68,12 @@ public:
|
|||||||
*/
|
*/
|
||||||
void Draw();
|
void Draw();
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Runs when droplet state is updated.
|
||||||
|
*/
|
||||||
|
void UpdateStateCallback();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Changes the wave shape of the VCO.
|
* Changes the wave shape of the VCO.
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user