Skip to content

Instantly share code, notes, and snippets.

@curlymorphic
Created November 15, 2022 21:58
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save curlymorphic/a413010dea449b66808ecf98b24e2c4d to your computer and use it in GitHub Desktop.
Save curlymorphic/a413010dea449b66808ecf98b24e2c4d to your computer and use it in GitHub Desktop.
// 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