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