sm-26/Source/SynthEngine.h

113 lines
No EOL
3 KiB
C++

#pragma once
#include <JuceHeader.h>
#include <array>
#include "SynthParams.h"
#include "Presets.h"
namespace sm26 {
class SynthEngine
{
public:
static constexpr int kNumVoices = 12;
SynthEngine();
void prepare (double sampleRate, int maxBlockSize);
void reset();
void loadPreset (const Preset& p);
int presetIndex() const { return currentPresetIndex; }
void setPresetIndex (int i);
void setParam (int id, float n01);
float getParam (int id) const;
struct KnobView {
const char* name;
int param;
float value01;
float lo;
float hi;
};
KnobView knobView (int knob) const;
float knobValue (int knob) const;
void process (AudioBuffer<float>& buffer, MidiBuffer& midi, int n,
double bpm, bool transportPlaying);
int notesPlaying() const { return activeNotes; }
float lastBpm() const { return lastBpmValue; }
bool transport() const { return wasPlaying; }
int delayTimeSamples() const { return lastDelaySamples; }
double delayTimeMs() const;
const char* waveNameFor (int index) const;
private:
struct Voice {
bool active = false;
int note = 60;
double velocity = 0.8;
double ph1 = 0.0, ph2 = 0.0;
double inc1 = 0.0, inc2 = 0.0, glidedInc1 = 0.0;
double env = 0.0;
int envState = 0;
int age = 0;
int fadeLen = 32;
double ic1eq = 0.0, ic2eq = 0.0;
};
void noteOn (int note, float vel);
void noteOff (int note);
void allNotesOff();
Voice* findFreeOrSteal();
void resetVoice (Voice& v, int note, float vel);
float oscWave (int wave, double phase);
float computeSingleSample (Voice& v, float& outL, float& outR,
double fad, double frel, double fsus, double fcut,
double fq, double drive, double glideCoef, double bpm);
double cutoffFor (const Voice& v, double baseCutoff, double envAmt, double env);
double sampleRate = 48000.0;
int maxBlock = 512;
float params[kNumParams];
int knobParams[kNumKnobs];
const char* knobNames[kNumKnobs];
float knobLows[kNumKnobs];
float knobHighs[kNumKnobs];
Voice voices[kNumVoices];
int activeNotes = 0;
struct DelayLine
{
std::vector<std::vector<float>> buf;
std::vector<int> writePos;
int maxLen = 1;
void prepare (double sr)
{
maxLen = (int) (sr * 18.0) + 4;
buf.assign (2, std::vector<float> (maxLen, 0.0f));
writePos.assign (2, 0);
}
void clear() { for (auto& c : buf) std::fill (c.begin(), c.end(), 0.0f); }
};
DelayLine delay;
double lastDelaySamples = 0.0;
double lastBpmValue = 120.0;
bool wasPlaying = false;
int currentPresetIndex = 0;
mutable juce::SpinLock paramLock;
std::array<float, kNumParams> smooth;
float smCoef = 1.0f;
float ftA = 1.0f, ftB = 0.0f, ftC = 0.0f;
};
} // namespace sm26