mirror of
https://github.com/AquaMorph/Droplets.git
synced 2025-05-22 18:16:58 +00:00
169 lines
4.2 KiB
C++
169 lines
4.2 KiB
C++
#include "vco_droplet.h"
|
|
|
|
VCODroplet::VCODroplet(DaisyPatch* m_patch,
|
|
DropletState m_state,
|
|
float sample_rate) :
|
|
Droplet(m_patch,
|
|
m_state) {
|
|
int num_waves = Oscillator::WAVE_LAST;
|
|
SetAnimationRate(10);
|
|
osc.Init(sample_rate);
|
|
|
|
wave = Oscillator::WAVE_SAW;
|
|
|
|
DaisyPatch::Ctrl freq, fine;
|
|
switch (GetState()){
|
|
default:
|
|
case DropletState::kFull:
|
|
wavectrl.Init(Patch()->controls[Patch()->CTRL_3], 0.0,
|
|
num_waves, Parameter::LINEAR);
|
|
ampctrl.Init(Patch()->controls[Patch()->CTRL_4], 0.0,
|
|
0.5f, Parameter::LINEAR);
|
|
freq = Patch()->CTRL_1;
|
|
fine = Patch()->CTRL_2;
|
|
SetWaveShape(wavectrl.Process());
|
|
break;
|
|
case DropletState::kLeft:
|
|
freq = Patch()->CTRL_1;
|
|
fine = Patch()->CTRL_2;
|
|
break;
|
|
case DropletState::kRight:
|
|
freq = Patch()->CTRL_3;
|
|
fine = Patch()->CTRL_4;
|
|
break;
|
|
}
|
|
freqctrl.Init(Patch()->controls[freq], 10.0,
|
|
110.0f, Parameter::LINEAR);
|
|
finectrl.Init(Patch()->controls[fine], 0.f,
|
|
7.f, Parameter::LINEAR);
|
|
}
|
|
|
|
VCODroplet::~VCODroplet() {
|
|
delete wave_graphic;
|
|
}
|
|
|
|
void VCODroplet::Control() {
|
|
Patch()->ProcessAnalogControls();
|
|
Patch()->encoder.Debounce();
|
|
AdjustWaveShape(Patch()->encoder.Increment());
|
|
}
|
|
|
|
void VCODroplet::Process(AudioHandle::InputBuffer in, AudioHandle::OutputBuffer out, size_t size) {
|
|
float sig, freq, amp = 1.0;
|
|
|
|
Patch()->ProcessAnalogControls();
|
|
|
|
for (size_t i = 0; i < size; i++) {
|
|
// Read Knobs
|
|
freq = mtof(freqctrl.Process() + finectrl.Process());
|
|
if (GetState() == DropletState::kFull) {
|
|
if((size_t) wavectrl.Process() != last_wave_ctrl) {
|
|
AdjustWaveShape((size_t)wavectrl.Process()-last_wave_ctrl);
|
|
last_wave_ctrl = wavectrl.Process();
|
|
}
|
|
amp = ampctrl.Process();
|
|
}
|
|
// Set osc params
|
|
osc.SetFreq(freq);
|
|
osc.SetWaveform(wave);
|
|
osc.SetAmp(amp);
|
|
// Process
|
|
sig = osc.Process();
|
|
// Assign Synthesized Waveform to outputs.
|
|
for (size_t chn = GetChannelMin(); chn < GetChannelMax(); chn++) {
|
|
out[chn][i] = sig;
|
|
}
|
|
}
|
|
}
|
|
|
|
void VCODroplet::Draw() {
|
|
SetWaveState(wave);
|
|
if (GetState() == DropletState::kFull) {
|
|
WriteCenteredString(Patch(),
|
|
(GetScreenMax()-GetScreenMin())/2,
|
|
54,
|
|
Font_6x8,
|
|
WaveToString(wave));
|
|
} else {
|
|
WriteDoubleCentered(Patch(),
|
|
GetScreenMin() +
|
|
(GetScreenMax()-GetScreenMin())/2,
|
|
54,
|
|
GetScreenMax()-GetScreenMin(),
|
|
Font_6x8,
|
|
WaveToString(wave));
|
|
}
|
|
wave_graphic->DrawTile(Patch(),
|
|
GetScreenMin(),
|
|
0,
|
|
GetScreenMax(),
|
|
GetTitleHeight());
|
|
if(NeedUpdate()) {
|
|
wave_graphic->AdjustXShift(1);
|
|
}
|
|
DrawName("VCO");
|
|
AnimationInc();
|
|
}
|
|
|
|
std::string VCODroplet::WaveToString(uint8_t wf) {
|
|
switch(wf){
|
|
case Oscillator::WAVE_TRI:
|
|
return "Triangle";
|
|
case Oscillator::WAVE_SQUARE:
|
|
return "Square";
|
|
case Oscillator::WAVE_SIN:
|
|
return "Sine";
|
|
case Oscillator::WAVE_SAW:
|
|
return "Saw";
|
|
case Oscillator::WAVE_RAMP:
|
|
return "Ramp";
|
|
case Oscillator::WAVE_POLYBLEP_TRI:
|
|
return "PolyBLEP Triangle";
|
|
case Oscillator::WAVE_POLYBLEP_SQUARE:
|
|
return "PolyBLEP Square";
|
|
case Oscillator::WAVE_POLYBLEP_SAW:
|
|
return "PolyBLEP Saw";
|
|
}
|
|
return "";
|
|
}
|
|
|
|
void VCODroplet::SetWaveState(uint8_t wf) {
|
|
switch(wf){
|
|
case Oscillator::WAVE_TRI:
|
|
wave_graphic->SetWaveShape(WaveShape::kTriangle);
|
|
return;
|
|
case Oscillator::WAVE_SQUARE:
|
|
wave_graphic->SetWaveShape(WaveShape::kSquare);
|
|
return;
|
|
case Oscillator::WAVE_SIN:
|
|
wave_graphic->SetWaveShape(WaveShape::kSine);
|
|
return;
|
|
case Oscillator::WAVE_SAW:
|
|
wave_graphic->SetWaveShape(WaveShape::kSaw);
|
|
return;
|
|
case Oscillator::WAVE_RAMP:
|
|
wave_graphic->SetWaveShape(WaveShape::kRamp);
|
|
return;
|
|
case Oscillator::WAVE_POLYBLEP_TRI:
|
|
wave_graphic->SetWaveShape(WaveShape::kTriangle);
|
|
return;
|
|
case Oscillator::WAVE_POLYBLEP_SQUARE:
|
|
wave_graphic->SetWaveShape(WaveShape::kSquare);
|
|
return;
|
|
default:
|
|
case Oscillator::WAVE_POLYBLEP_SAW:
|
|
wave_graphic->SetWaveShape(WaveShape::kSaw);
|
|
return;
|
|
}
|
|
}
|
|
|
|
void VCODroplet::AdjustWaveShape(int amount) {
|
|
wave = (Oscillator::WAVE_LAST + wave + amount) %
|
|
Oscillator::WAVE_LAST;
|
|
}
|
|
|
|
void VCODroplet::SetWaveShape(int ws) {
|
|
wave = ws % Oscillator::WAVE_LAST;
|
|
last_wave_ctrl = ws;
|
|
}
|