-
-
Save curlymorphic/a413010dea449b66808ecf98b24e2c4d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// copyright 2022 Curlymorphic, Dave French | |
#include "../Module.h" | |
#include "stdlib.h" | |
#include <cmath> | |
#include "../dsp/LookupTable.h" | |
class SuperSimpleSineVCO : public sspo::pms::Module | |
{ | |
public: | |
void process (volatile FixedDsp outBuffer[][sspo::pms::Settings::audioBufferSize], | |
const volatile FixedDsp inBuffer[][sspo::pms::Settings::audioBufferSize], | |
int length, | |
const sspo::pms::Parameters& params, | |
std::atomic<uint8_t>& led) override; | |
void setup() override; | |
private: | |
FixedDsp phase{ 0.0f }; | |
Fixed freq{ 1.0f }; | |
FixedDsp inc{ 0.0f }; | |
static constexpr FixedDsp pi{ 3.14159265359f }; | |
}; | |
void SuperSimpleSineVCO::process (volatile FixedDsp outBuffer[][sspo::pms::Settings::audioBufferSize], | |
const volatile FixedDsp inBuffer[][sspo::pms::Settings::audioBufferSize], | |
int length, | |
const sspo::pms::Parameters& params, | |
std::atomic<uint8_t>& led) | |
{ | |
// A Super simple sin vco | |
// for this we will use the sin() function but more efficient ways | |
// are preferred. This will demonstrate the use of parameters,cv inputs | |
// and audio outputs | |
// The parameters and cv inputs are updated once per buffer | |
// we will use these to calculate the frequency, and from that | |
// a phase increment. | |
// A potentiometer should be attached to P0 this will be a tuning knob | |
// we want to be able to tune our oscillator up or down 2 octaves. | |
// parameters are values are between 0.0f and 1.0f so we will do a conversion | |
auto octave = FixedDsp ((params.getParameter (p0) * 4.0f - 2.0f).toInt()); | |
// we will use inout CV0 as our voltage control input | |
// cv values are given in the range 0.0f to 5.0v, enough for | |
// five octave. This sounds reasonable, and the 1V per octave | |
// is standard in Kosmo and Eurorack modular synths | |
auto vOct = params.getCv (ocv0); | |
// we will add these two values together and use them as the voltage | |
// input on an exponential converter, that will calculate the frequency | |
// based on middle C being 261.63Hz | |
freq = Fixed (261.63f) * lookup.pow2 (octave + vOct); | |
// now we can calculate an increment for each frame, based upon the | |
// sample rate. | |
inc = freq / sspo::pms::Settings::sampleRate; | |
// audio should be between -5 and 5v,so we can use this as our amplitude | |
FixedDsp amplitude = 5.0f; | |
// Now the main loop, that iterates over the buffers | |
for (auto i = 0; i < length; ++i) | |
{ | |
// increment the phase each sample, and wrap when needed | |
phase += inc; | |
while (phase > 1.0f) | |
phase -= 1.0f; | |
// write each frame to the audio buffer | |
outBuffer[OutNames::oAudio00][i] = amplitude * lookup.sin (phase * 2.0f * pi); | |
} | |
// Try to take this example further, make it your own | |
// Things to try | |
// LFO | |
// Second oscillator, detuned from the fist | |
// Mix control | |
// Fine tune parameter, maybe just += 1/2 octave | |
// Octave select switch, quantized to +1 +2 +3 | |
} | |
void SuperSimpleSineVCO::setup() | |
{ | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment