1 #pragma once 2 #include "StringOsc.h" 3 #include "StringFilters.h" 4 #include "SolinaChorus.h" 5 #include "dsp/ADSREnvelope.h" 6 #include "dsp/TriangleLFO.h" 7 #include <boost/intrusive/list.hpp> 8 #include <memory> 9 #include <cstdint> 10 11 class StringSynth { 12 public: 13 StringSynth(); 14 ~StringSynth(); 15 16 void init(double sampleRate); 17 18 void handleMessage(const uint8_t *msg); 19 void resetAllControllers(); 20 void generate(float *outputs[2], unsigned count); 21 getDetune()22 float getDetune() const { return fDetuneAmount; } setDetune(float amount)23 void setDetune(float amount) { fDetuneAmount = amount; } 24 getOscSettings()25 const StringOsc::Settings &getOscSettings() const { return fOscSettings; } getOscSettings()26 StringOsc::Settings &getOscSettings() { return fOscSettings; } 27 getEnvSettings()28 const ADSREnvelope::Settings &getEnvSettings() const { return fEnvSettings; } getEnvSettings()29 ADSREnvelope::Settings &getEnvSettings() { return fEnvSettings; } 30 getFltSettings()31 const StringFilters::Settings &getFltSettings() const { return fFltSettings; } getFltSettings()32 StringFilters::Settings &getFltSettings() { return fFltSettings; } 33 getMixGainUpper()34 float getMixGainUpper() const { return fMixGainUpper; } setMixGainUpper(float value)35 void setMixGainUpper(float value) { fMixGainUpper = value; } getMixGainLower()36 float getMixGainLower() const { return fMixGainLower; } setMixGainLower(float value)37 void setMixGainLower(float value) { fMixGainLower = value; } 38 getChorus()39 const SolinaChorus &getChorus() const { return fChorus; } getChorus()40 SolinaChorus &getChorus() { return fChorus; } 41 getMasterGain()42 float getMasterGain() const { return fMasterGain; } setMasterGain(float value)43 void setMasterGain(float value) { fMasterGain = value; } 44 getLastDetuneUpper()45 float getLastDetuneUpper() const { return fLastDetuneUpper; } getLastDetuneLower()46 float getLastDetuneLower() const { return fLastDetuneLower; } 47 48 private: 49 struct Voice : boost::intrusive::list_base_hook<> { 50 unsigned note; 51 float pitch; 52 float bend; 53 bool active; 54 ADSREnvelope env; 55 StringOsc osc; 56 StringFilters flt; 57 }; 58 59 private: 60 std::unique_ptr<Voice[]> fVoices; 61 boost::intrusive::list<Voice> fActiveVoices; 62 63 float fDetuneAmount; 64 TriangleLFO fDetuneLFO[2]; 65 66 float fLastDetuneUpper; 67 float fLastDetuneLower; 68 69 float fMixGainUpper; 70 float fMixGainLower; 71 72 StringOsc::Settings fOscSettings; 73 ADSREnvelope::Settings fEnvSettings; 74 StringFilters::Settings fFltSettings; 75 76 SolinaChorus fChorus; 77 78 float fMasterGain; 79 80 float fCtlPitchBend; 81 float fCtlPitchBendSensitivity; 82 83 struct RpnIdentifier { 84 unsigned registered : 1; 85 unsigned msb : 7; 86 unsigned lsb : 7; 87 }; 88 RpnIdentifier fCtlRpnIdentifier; 89 90 private: 91 void noteOn(unsigned note, unsigned vel); 92 void noteOff(unsigned note, unsigned vel); 93 void allNotesOff(); 94 void allSoundOff(); 95 bool generateVoiceAdding(Voice &voice, float *output, const float *const detune[2], float bend, unsigned count); 96 static void clearFinishedVoice(Voice &voice); 97 static bool voiceHasReleased(const Voice &voice); 98 static bool voiceHasFinished(const Voice &voice); 99 }; 100