mirror of
https://github.com/AquaMorph/Droplets.git
synced 2025-04-30 09:45:35 +00:00
Added basic LFO
This commit is contained in:
parent
175a836715
commit
b834f3168a
108
src/droplets/lfo_droplet.cpp
Normal file
108
src/droplets/lfo_droplet.cpp
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
#include "lfo_droplet.h"
|
||||||
|
|
||||||
|
void LFO::Init(DaisyPatch* m_patch,
|
||||||
|
float samplerate,
|
||||||
|
AnalogControl freqKnob,
|
||||||
|
AnalogControl ampKnob) {
|
||||||
|
patch = m_patch;
|
||||||
|
osc.Init(samplerate);
|
||||||
|
osc.SetAmp(1);
|
||||||
|
wave = 0;
|
||||||
|
freqCtrl.Init(freqKnob, 0.1f, 35.0f, Parameter::LOGARITHMIC);
|
||||||
|
ampCtrl.Init(ampKnob, 0.0f, 1.0f, Parameter::LINEAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LFO::Process(DacHandle::Channel chn) {
|
||||||
|
osc.SetFreq(freqCtrl.Process());
|
||||||
|
osc.SetWaveform(wave);
|
||||||
|
|
||||||
|
patch->seed.dac.WriteValue(
|
||||||
|
chn,
|
||||||
|
uint16_t((osc.Process() + 1.f) *
|
||||||
|
.5f * ampCtrl.Process() * 4095.f));
|
||||||
|
}
|
||||||
|
|
||||||
|
void LFO::UpdateWave(int change) {
|
||||||
|
wave = (MAX_WAVE + wave + change) % MAX_WAVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t LFO::GetWave() {
|
||||||
|
return wave;
|
||||||
|
}
|
||||||
|
|
||||||
|
LFODroplet::LFODroplet(DaisyPatch* m_patch,
|
||||||
|
DropletState m_state,
|
||||||
|
float sample_rate) :
|
||||||
|
Droplet(m_patch,
|
||||||
|
m_state) {
|
||||||
|
switch (GetState()) {
|
||||||
|
default:
|
||||||
|
case DropletState::kFull:
|
||||||
|
lfo[0].Init(Patch(),
|
||||||
|
sample_rate,
|
||||||
|
Patch()->controls[Patch()->CTRL_1],
|
||||||
|
Patch()->controls[Patch()->CTRL_2]);
|
||||||
|
lfo[1].Init(Patch(),
|
||||||
|
sample_rate,
|
||||||
|
Patch()->controls[Patch()->CTRL_3],
|
||||||
|
Patch()->controls[Patch()->CTRL_4]);
|
||||||
|
break;
|
||||||
|
case DropletState::kLeft:
|
||||||
|
lfo[0].Init(Patch(),
|
||||||
|
sample_rate,
|
||||||
|
Patch()->controls[Patch()->CTRL_1],
|
||||||
|
Patch()->controls[Patch()->CTRL_2]);
|
||||||
|
break;
|
||||||
|
case DropletState::kRight:
|
||||||
|
lfo[0].Init(Patch(),
|
||||||
|
sample_rate,
|
||||||
|
Patch()->controls[Patch()->CTRL_3],
|
||||||
|
Patch()->controls[Patch()->CTRL_4]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LFODroplet::~LFODroplet() {}
|
||||||
|
|
||||||
|
void LFODroplet::Control() {
|
||||||
|
Patch()->ProcessAnalogControls();
|
||||||
|
Patch()->encoder.Debounce();
|
||||||
|
lfo[0].UpdateWave(Patch()->encoder.Increment());
|
||||||
|
if (GetState() == DropletState::kFull) {
|
||||||
|
lfo[1].UpdateWave(Patch()->encoder.Increment());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LFODroplet::Process(AudioHandle::InputBuffer in, AudioHandle::OutputBuffer out, size_t size) {
|
||||||
|
Patch()->ProcessAnalogControls();
|
||||||
|
|
||||||
|
for(size_t i = 0; i < size; i++) {
|
||||||
|
if (GetState() == DropletState::kRight) {
|
||||||
|
lfo[0].Process(DacHandle::Channel::TWO);
|
||||||
|
} else {
|
||||||
|
lfo[0].Process(DacHandle::Channel::ONE);
|
||||||
|
}
|
||||||
|
if (GetState() == DropletState::kFull) {
|
||||||
|
lfo[1].Process(DacHandle::Channel::TWO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LFODroplet::Draw() {
|
||||||
|
if (GetState() == DropletState::kFull) {
|
||||||
|
WriteCenteredString(Patch(),
|
||||||
|
(GetScreenMax()-GetScreenMin())/2,
|
||||||
|
54,
|
||||||
|
Font_6x8,
|
||||||
|
WaveToString(lfo[0].GetWave()));
|
||||||
|
} else {
|
||||||
|
WriteDoubleCentered(Patch(),
|
||||||
|
GetScreenMin() +
|
||||||
|
(GetScreenMax()-GetScreenMin())/2,
|
||||||
|
54,
|
||||||
|
GetScreenMax()-GetScreenMin(),
|
||||||
|
Font_6x8,
|
||||||
|
WaveToString(lfo[0].GetWave()));
|
||||||
|
}
|
||||||
|
DrawName("LFO");
|
||||||
|
}
|
82
src/droplets/lfo_droplet.h
Normal file
82
src/droplets/lfo_droplet.h
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef CASCADE_DROPLETS_LFO_DROPLET_H_
|
||||||
|
#define CASCADE_DROPLETS_LFO_DROPLET_H_
|
||||||
|
|
||||||
|
#include "daisysp.h"
|
||||||
|
#include "daisy_patch.h"
|
||||||
|
|
||||||
|
#include "droplet.h"
|
||||||
|
#include "../util.h"
|
||||||
|
|
||||||
|
using namespace daisy;
|
||||||
|
using namespace daisysp;
|
||||||
|
|
||||||
|
#define MAX_WAVE Oscillator::WAVE_POLYBLEP_TRI
|
||||||
|
|
||||||
|
class LFO {
|
||||||
|
private:
|
||||||
|
Oscillator osc;
|
||||||
|
Parameter freqCtrl;
|
||||||
|
Parameter ampCtrl;
|
||||||
|
float amp;
|
||||||
|
float freq;
|
||||||
|
uint8_t wave;
|
||||||
|
float value;
|
||||||
|
DaisyPatch* patch;
|
||||||
|
public:
|
||||||
|
void Init(DaisyPatch* m_patch,
|
||||||
|
float samplerate,
|
||||||
|
AnalogControl freqKnob,
|
||||||
|
AnalogControl ampKnob);
|
||||||
|
|
||||||
|
void Process(DacHandle::Channel chn);
|
||||||
|
|
||||||
|
void UpdateWave(int change);
|
||||||
|
|
||||||
|
uint8_t GetWave();
|
||||||
|
};
|
||||||
|
|
||||||
|
class LFODroplet: public Droplet {
|
||||||
|
private:
|
||||||
|
LFO lfo[2];
|
||||||
|
|
||||||
|
public:
|
||||||
|
/*
|
||||||
|
* Constructor for a LFO droplet.
|
||||||
|
*
|
||||||
|
* @param m_patch pointer to patch
|
||||||
|
* @param m_state droplet position
|
||||||
|
*/
|
||||||
|
LFODroplet(DaisyPatch* m_patch,
|
||||||
|
DropletState m_state,
|
||||||
|
float sample_rate);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Destructor for vco droplet.
|
||||||
|
*/
|
||||||
|
~LFODroplet();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Processes user controls and inputs.
|
||||||
|
*/
|
||||||
|
void Control();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Processes audio input and outputs.
|
||||||
|
*
|
||||||
|
* @param in the audio inputs for the patch
|
||||||
|
* @param out the audio outputs for the patch
|
||||||
|
* @param size the number of inputs and outputs
|
||||||
|
*/
|
||||||
|
void Process(AudioHandle::InputBuffer in,
|
||||||
|
AudioHandle::OutputBuffer out,
|
||||||
|
size_t size);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Processes information to be shown on the display.
|
||||||
|
*/
|
||||||
|
void Draw();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CASCADE_DROPLETS_LFO_DROPLET_H_
|
@ -105,28 +105,6 @@ void VCODroplet::Draw() {
|
|||||||
AnimationInc();
|
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) {
|
void VCODroplet::SetWaveState(uint8_t wf) {
|
||||||
switch(wf){
|
switch(wf){
|
||||||
case Oscillator::WAVE_TRI:
|
case Oscillator::WAVE_TRI:
|
||||||
|
@ -24,14 +24,6 @@ private:
|
|||||||
const double pi = std::acos(-1);
|
const double pi = std::acos(-1);
|
||||||
Wave* wave_graphic = new Wave(WaveShape::kTriangle, 21, GetTitleHeight());
|
Wave* wave_graphic = new Wave(WaveShape::kTriangle, 21, GetTitleHeight());
|
||||||
|
|
||||||
/*
|
|
||||||
* Converts oscilator to name of wave shape.
|
|
||||||
*
|
|
||||||
* @param wf wave shape
|
|
||||||
* @return name of wave shap
|
|
||||||
*/
|
|
||||||
std::string WaveToString(uint8_t wf);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sets the vco wave shap to display on screen.
|
* Sets the vco wave shap to display on screen.
|
||||||
*
|
*
|
||||||
|
@ -115,6 +115,10 @@ static void AudioThrough(AudioHandle::InputBuffer in,
|
|||||||
Droplet* GetDroplet(DropletState state) {
|
Droplet* GetDroplet(DropletState state) {
|
||||||
switch(selected_menu->GetState()) {
|
switch(selected_menu->GetState()) {
|
||||||
default:
|
default:
|
||||||
|
case MenuState::kLFO:
|
||||||
|
return new LFODroplet(&patch,
|
||||||
|
state,
|
||||||
|
sample_rate);
|
||||||
case MenuState::kMixer:
|
case MenuState::kMixer:
|
||||||
return new MixerDroplet(&patch,
|
return new MixerDroplet(&patch,
|
||||||
state);
|
state);
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
#include "droplets/droplet.h"
|
#include "droplets/droplet.h"
|
||||||
#include "droplets/droplet_manager.h"
|
#include "droplets/droplet_manager.h"
|
||||||
|
#include "droplets/lfo_droplet.h"
|
||||||
#include "droplets/mixer_droplet.h"
|
#include "droplets/mixer_droplet.h"
|
||||||
#include "droplets/noise_droplet.h"
|
#include "droplets/noise_droplet.h"
|
||||||
#include "droplets/vca_droplet.h"
|
#include "droplets/vca_droplet.h"
|
||||||
|
@ -9,6 +9,7 @@ Menu::Menu(DaisyPatch* m_patch,
|
|||||||
|
|
||||||
head = new MenuItem(MenuState::kSplit, "Split");
|
head = new MenuItem(MenuState::kSplit, "Split");
|
||||||
head->AddItemEnd(new MenuItem(MenuState::kChange, ""));
|
head->AddItemEnd(new MenuItem(MenuState::kChange, ""));
|
||||||
|
head->AddItemEnd(new MenuItem(MenuState::kLFO, "LFO"));
|
||||||
head->AddItemEnd(new MenuItem(MenuState::kMixer, "Mixer"));
|
head->AddItemEnd(new MenuItem(MenuState::kMixer, "Mixer"));
|
||||||
head->AddItemEnd(new MenuItem(MenuState::kNoise, "Noise"));
|
head->AddItemEnd(new MenuItem(MenuState::kNoise, "Noise"));
|
||||||
head->AddItemEnd(new MenuItem(MenuState::kVCA, "VCA"));
|
head->AddItemEnd(new MenuItem(MenuState::kVCA, "VCA"));
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
enum class MenuState {kSplit, kChange, kMixer, kNoise, kVCA, kVCO};
|
enum class MenuState {kSplit, kChange, kLFO, kMixer, kNoise, kVCA, kVCO};
|
||||||
|
|
||||||
class MenuItem {
|
class MenuItem {
|
||||||
private:
|
private:
|
||||||
|
22
src/util.cpp
22
src/util.cpp
@ -93,3 +93,25 @@ void WriteDoubleCentered(DaisyPatch* patch,
|
|||||||
std::string text) {
|
std::string text) {
|
||||||
WriteDoubleCentered(patch, x, y, width, font, text, true);
|
WriteDoubleCentered(patch, x, y, width, font, text, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string 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 "";
|
||||||
|
}
|
||||||
|
10
src/util.h
10
src/util.h
@ -3,11 +3,13 @@
|
|||||||
#ifndef CASCADE_UTIL_H_
|
#ifndef CASCADE_UTIL_H_
|
||||||
#define CASCADE_UTIL_H_
|
#define CASCADE_UTIL_H_
|
||||||
|
|
||||||
|
#include "daisysp.h"
|
||||||
#include "daisy_patch.h"
|
#include "daisy_patch.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
using namespace daisy;
|
using namespace daisy;
|
||||||
|
using namespace daisysp;
|
||||||
|
|
||||||
#define SSD1309_WIDTH 128
|
#define SSD1309_WIDTH 128
|
||||||
|
|
||||||
@ -128,4 +130,12 @@ void WriteDoubleCentered(DaisyPatch* patch,
|
|||||||
FontDef font,
|
FontDef font,
|
||||||
std::string text);
|
std::string text);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Converts oscilator to name of wave shape.
|
||||||
|
*
|
||||||
|
* @param wf wave shape
|
||||||
|
* @return name of wave shap
|
||||||
|
*/
|
||||||
|
std::string WaveToString(uint8_t wf);
|
||||||
|
|
||||||
#endif // CASCADE_UTIL_H_
|
#endif // CASCADE_UTIL_H_
|
||||||
|
Loading…
x
Reference in New Issue
Block a user