added waveform selectors
This commit is contained in:
@@ -7,6 +7,7 @@ Envelope::Envelope() {
|
||||
|
||||
void Envelope::noteOn() {
|
||||
state_ = State::Attack;
|
||||
// there's interntionally no envelope value_ reset here because slurs
|
||||
}
|
||||
|
||||
void Envelope::noteOff() {
|
||||
@@ -26,7 +27,7 @@ float Envelope::process() {
|
||||
state_ = State::Decay;
|
||||
}
|
||||
break;
|
||||
case State::Decay: // TODO: if noteOff occurs during decay, release doesn't trigger until decay finishes
|
||||
case State::Decay:
|
||||
value_ -= (1.0f - sustain_) / (decay_ * sampleRate_);
|
||||
if(value_ <= sustain_) {
|
||||
value_ = sustain_;
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#include <vector>
|
||||
#include <atomic>
|
||||
|
||||
// the scope buffer is used by the ui to visualize the audio waveform
|
||||
// the ui thread shouldn't read directly from memory being read from/written to so it copies the data into this class
|
||||
class ScopeBuffer {
|
||||
public:
|
||||
|
||||
@@ -22,6 +24,7 @@ public:
|
||||
|
||||
// NOTE: there are limits to the wavelengths that the scope can show cleanly due to the size of the audio buffer
|
||||
// at a buffer size of 256 at 44100hz the min visible steady frequency is ~172hz
|
||||
// the min visible steady frequency can be lowered by increasing buffer size (increases latency) or decreasing sample rate (decreases audio fidelity)
|
||||
private:
|
||||
|
||||
std::vector<float> buffer_;
|
||||
|
||||
@@ -94,8 +94,25 @@ void Synth::process(float* out, uint32_t nFrames, uint32_t sampleRate) {
|
||||
// TODO: wavetables should be scaled by their RMS for equal loudness (prelim standard = 0.707)
|
||||
float sineSample = std::sin(phase_);
|
||||
float squareSample = (phase_ >= M_PI) ? 0.707f : -0.707f;
|
||||
float sawSample = ((phase_ / M_PI) - 1.0f) / 0.577f * 0.707f;
|
||||
sampleOut = squareSample * gain;
|
||||
float sawSample = ((phase_ / M_PI) - 1.0f) / 0.577f * 0.707f;
|
||||
// switch statement will be replaced with an array index for our array of wavetables
|
||||
switch (static_cast<int32_t>(std::round(getParam(ParamId::Osc1WaveSelector1)))) {
|
||||
case 0:
|
||||
sampleOut = sineSample * gain;
|
||||
break;
|
||||
case 1:
|
||||
sampleOut = squareSample * gain;
|
||||
break;
|
||||
case 2:
|
||||
sampleOut = sawSample * gain;
|
||||
break;
|
||||
case 3:
|
||||
// TODO: no triable wave yet :(
|
||||
sampleOut = sineSample * gain;
|
||||
break;
|
||||
default: // unreachable
|
||||
break;
|
||||
}
|
||||
|
||||
// write to buffer
|
||||
out[2*i] = sampleOut; // left
|
||||
@@ -113,6 +130,7 @@ void Synth::process(float* out, uint32_t nFrames, uint32_t sampleRate) {
|
||||
if(!triggered) {
|
||||
scope_->setTrigger(i); // this is where we consider the start of a waveform
|
||||
triggered = true;
|
||||
// TODO: investigate triggering accross buffers when a single wave period transcends a single audio buffer
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user