Skip to content

Commit

Permalink
Switcher, some tiny works.
Browse files Browse the repository at this point in the history
  • Loading branch information
BLumia committed Aug 24, 2016
1 parent fa94411 commit 18e9dc0
Show file tree
Hide file tree
Showing 10 changed files with 79 additions and 21 deletions.
12 changes: 8 additions & 4 deletions Oscillator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,25 +24,29 @@ void Oscillator::updateIncrement() {
double Oscillator::nextSample() {
double value = 0.0;

const float segLength = twoPI / mSegCount;
float calcPhase = isBitCrusherOn ? int(mPhase / segLength) * segLength : mPhase;

switch (mOscillatorMode) {
case OSCILLATOR_MODE_SINE:
value = sin(mPhase);
value = sin(calcPhase);
break;
case OSCILLATOR_MODE_SAW:
value = 1.0 - (2.0 * mPhase / twoPI);
value = 1.0 - (2.0 * calcPhase / twoPI);
break;
case OSCILLATOR_MODE_SQUARE:
if (mPhase <= mPI) {
if (calcPhase <= mPI) {
value = 1.0;
} else {
value = -1.0;
}
break;
case OSCILLATOR_MODE_TRIANGLE:
value = -1.0 + (2.0 * mPhase / twoPI);
value = -1.0 + (2.0 * calcPhase / twoPI);
value = 2.0 * (fabs(value) - 0.5);
break;
case OSCILLATOR_MODE_NOISE:
// TODO: if using Bit Crusher, generate noise only at new seg.
value = ((double)(std::rand()) / RAND_MAX) * 2.0 - 1.0;
break;
}
Expand Down
15 changes: 11 additions & 4 deletions Oscillator.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@ class Oscillator {
};
private:
OscillatorMode mOscillatorMode;
bool isBitCrusherOn;
bool mPhaseStart;
const double mPI;
const double twoPI;
int mSegCount;
double mFrequency;
double mPhase;
static double mSampleRate;
Expand All @@ -27,16 +30,20 @@ class Oscillator {
void setMode(OscillatorMode mode);
void setFrequency(double frequency);
void setSampleRate(double sampleRate);
//void generate(double* buffer, int nFrames);
void setBitCrusher(bool on) { isBitCrusherOn = on; };
void setPhaseStart(bool on) { mPhaseStart = on; };
double nextSample();
void reset() { mPhase = 0.0; } // Lets the waveform start from the beginning everytime a voice starts to play.
void reset() { if (mPhaseStart) mPhase = 0.0; } // Lets the waveform start from the beginning everytime a voice starts to play.
Oscillator() :
mOscillatorMode(OSCILLATOR_MODE_SINE),
mSegCount(32), // Thanks UN1C0DE for this idea and impl.
mPI(2 * acos(0.0)),
twoPI(2 * mPI), // This line is new
twoPI(2 * mPI),
isBitCrusherOn(false),
mPhaseStart(true),
mFrequency(440.0),
mPhase(0.0) {
updateIncrement();
std::srand(std::time(0));
std::srand(std::time(0)); // RNG may need a better effectice impl
};
};
41 changes: 34 additions & 7 deletions Synthesis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ enum EParams
mOsc2Coarse,
mOsc2Fine,
mOscillatorMix,
mPhaseStart,
mBitCrusher,
mTejiBooster,
mAmpAmount,
mAttack,
mDecay,
Expand Down Expand Up @@ -68,17 +71,19 @@ Synthesis::Synthesis(IPlugInstanceInfo instanceInfo)

pGraphics->AttachControl(mVirtualKeyboard);

// Knob bitmap for ADSR
// Bitmaps
IBitmap greenKnobBitmap = pGraphics->LoadIBitmap(GREEN_KNOB_ID, GREEN_KNOB_FN, 31);
IBitmap greenKnobCenterBitmap = pGraphics->LoadIBitmap(GREEN_KNOB_CENTER_ID, GREEN_KNOB_CENTER_FN, 31);
IBitmap blueKnobBitmap = pGraphics->LoadIBitmap(BLUE_KNOB_ID, BLUE_KNOB_FN, 31);
IBitmap blueKnobCenterBitmap = pGraphics->LoadIBitmap(BLUE_KNOB_CENTER_ID, BLUE_KNOB_CENTER_FN, 31);
IBitmap orangeKnobBitmap = pGraphics->LoadIBitmap(ORANGE_KNOB_ID, ORANGE_KNOB_FN, 31);
IBitmap waveformBitmap = pGraphics->LoadIBitmap(WAVEFORM_ID, WAVEFORM_FN, 5);
IBitmap filtermodeBitmap = pGraphics->LoadIBitmap(FILTERMODE_ID, FILTERMODE_FN, 3);
IBitmap switcherLightBitmap = pGraphics->LoadIBitmap(SWITCHER_LIGHT_ID, SWITCHER_LIGHT_FN, 2);

// OSC1 Waveform switch
GetParam(mOsc1Waveform)->InitEnum("Waveform1", Oscillator::OSCILLATOR_MODE_SINE, Oscillator::kNumOscillatorModes);
GetParam(mOsc1Waveform)->SetDisplayText(0, "Sine"); // Needed for VST3, thanks plunntic
IBitmap waveformBitmap = pGraphics->LoadIBitmap(WAVEFORM_ID, WAVEFORM_FN, 5);
GetParam(mOsc1Waveform)->SetDisplayText(0, "Sine");
pGraphics->AttachControl(new ISwitchControl(this, 42, kGreenRow + kSwitcherTopPadding, mOsc1Waveform, &waveformBitmap));

// OSC1 Coarse knob:
Expand All @@ -93,7 +98,7 @@ Synthesis::Synthesis(IPlugInstanceInfo instanceInfo)

// OSC2 Waveform switch
GetParam(mOsc2Waveform)->InitEnum("Waveform2", Oscillator::OSCILLATOR_MODE_SINE, Oscillator::kNumOscillatorModes);
GetParam(mOsc2Waveform)->SetDisplayText(0, "Sine"); // Needed for VST3, thanks plunntic
GetParam(mOsc2Waveform)->SetDisplayText(0, "Sine");
pGraphics->AttachControl(new ISwitchControl(this, 346, kGreenRow + kSwitcherTopPadding, mOsc2Waveform, &waveformBitmap));

// OSC2 Coarse knob:
Expand All @@ -111,6 +116,21 @@ Synthesis::Synthesis(IPlugInstanceInfo instanceInfo)
GetParam(mOscillatorMix)->SetShape(1);
pGraphics->AttachControl(new IKnobMultiControl(this, 275, kGreenRow, mOscillatorMix, &greenKnobCenterBitmap));

// OSC Phase Start switch
GetParam(mPhaseStart)->InitEnum("Start", 1, 2);
GetParam(mPhaseStart)->SetDisplayText(0, "Start");
pGraphics->AttachControl(new ISwitchControl(this, 564, kGreenRow + 7, mPhaseStart, &switcherLightBitmap));

// OSC1 Waveform switch
GetParam(mBitCrusher)->InitEnum("Bit Crusher", 0, 2);
GetParam(mBitCrusher)->SetDisplayText(0, "Bit Crusher");
pGraphics->AttachControl(new ISwitchControl(this, 564, kGreenRow + 25, mBitCrusher, &switcherLightBitmap));

// OSC1 Waveform switch
GetParam(mTejiBooster)->InitEnum("Mono/Poly", 0, 2);
GetParam(mTejiBooster)->SetDisplayText(0, "Teji Booster");
pGraphics->AttachControl(new ISwitchControl(this, 564, kGreenRow + 43 + 1, mTejiBooster, &switcherLightBitmap));

// Amp amount knob:
GetParam(mAmpAmount)->InitDouble("Amp Amount", 50., 0., 100.0, 0.01, "%");
GetParam(mAmpAmount)->SetShape(2);
Expand Down Expand Up @@ -145,7 +165,6 @@ Synthesis::Synthesis(IPlugInstanceInfo instanceInfo)
// Filter switch
GetParam(mFilterMode)->InitEnum("Filter Mode", Filter::FILTER_MODE_LOWPASS, Filter::kNumFilterModes);
GetParam(mFilterMode)->SetDisplayText(0, "LP"); // Needed for VST3, thanks plunntic
IBitmap filtermodeBitmap = pGraphics->LoadIBitmap(FILTERMODE_ID, FILTERMODE_FN, 3);
pGraphics->AttachControl(new ISwitchControl(this, 42, kBlueRow + kSwitcherTopPadding, mFilterMode, &filtermodeBitmap));

// Filter options
Expand Down Expand Up @@ -193,7 +212,7 @@ Synthesis::Synthesis(IPlugInstanceInfo instanceInfo)
mMIDIReceiver.noteOn.Connect(&voiceManager, &VoiceManager::onNoteOn);
mMIDIReceiver.noteOff.Connect(&voiceManager, &VoiceManager::onNoteOff);

// some host will not auto-reset the params so it will not set the adsr value, do it here.
// Some host will not auto-reset the params so it will not set the adsr value, do it here.
ampAdsrVisualization->setADSR(ampAdsrKnobs[E_Att]->GetValue(), ampAdsrKnobs[E_Dec]->GetValue(),
ampAdsrKnobs[E_Sus]->GetValue(), ampAdsrKnobs[E_Rel]->GetValue());
filterEnvAdsrVisualization->setADSR(filterAdsrKnobs[E_Att]->GetValue(), filterAdsrKnobs[E_Dec]->GetValue(),
Expand Down Expand Up @@ -256,6 +275,15 @@ void Synthesis::OnParamChange(int paramIdx)
case mOscillatorMix:
voiceManager.setOscillatorMixForEachVoice(GetParam(paramIdx)->Value());
break;
case mPhaseStart:
voiceManager.setPhaseStartForEachVoice(static_cast<bool>(GetParam(paramIdx)->Int()));
break;
case mBitCrusher:
voiceManager.setBitCrusherEnabledForEachVoice(static_cast<bool>(GetParam(paramIdx)->Int()));
break;
case mTejiBooster:
voiceManager.setNumberOfVoices(GetParam(paramIdx)->Int() == 0 ? 64 : 32);
break;
case mAmpAmount:
voiceManager.setAmpAmountForEachVoice(GetParam(paramIdx)->Value());
break;
Expand All @@ -266,7 +294,6 @@ void Synthesis::OnParamChange(int paramIdx)
voiceManager.setAmpEnvStageValueForEachVoice(static_cast<EnvelopeGenerator::EnvelopeStage>(paramIdx - mAttack + 1), GetParam(paramIdx)->Value());
ampAdsrVisualization->setADSR(ampAdsrKnobs[E_Att]->GetValue(), ampAdsrKnobs[E_Dec]->GetValue(),
ampAdsrKnobs[E_Sus]->GetValue(), ampAdsrKnobs[E_Rel]->GetValue());
//ampAdsrVisualization->setADSR(ampAdsrKnobs[E_Att]->GetValue, ampAdsrKnobs[E_Dec]->GetValue, ampAdsrKnobs[E_Sus]->GetValue, ampAdsrKnobs[E_Rel]->GetValue);
break;
case mFilterCutoff:
voiceManager.setFilterCutoffForEachVoice(GetParam(paramIdx)->Value());
Expand Down
1 change: 1 addition & 0 deletions Synthesis.rc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ BLUE_KNOB_ID PNG BLUE_KNOB_FN
BLUE_KNOB_CENTER_ID PNG BLUE_KNOB_CENTER_FN
FILTERMODE_ID PNG FILTERMODE_FN
ORANGE_KNOB_ID PNG ORANGE_KNOB_FN
SWITCHER_LIGHT_ID PNG SWITCHER_LIGHT_FN

#ifdef SA_API
//Standalone stuff
Expand Down
2 changes: 2 additions & 0 deletions Voice.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ class Voice {
inline void setSemiOffset2(int semi) { mSemiOffset2 = semi; }
inline void setCentOffset1(int cent) { mCentOffset1 = cent; }
inline void setCentOffset2(int cent) { mCentOffset2 = cent; }
inline void setOscillatorBitCrusher(bool enabled) { mOscillator1.setBitCrusher(enabled); mOscillator2.setBitCrusher(enabled); };
inline void setPhaseStart(bool enabled) { mOscillator1.setPhaseStart(enabled); mOscillator2.setPhaseStart(enabled); };
inline void setOscillatorMix(double mix) { mOscillatorMix = mix; }
inline void setNoteNumber(int noteNumber) {
mNoteNumber = noteNumber;
Expand Down
12 changes: 12 additions & 0 deletions VoiceManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,4 +128,16 @@ void VoiceManager::setCentOffsetForEachVoice(int oscID, int cent) {
voices[i].mCentOffset2 = cent;
}
}
}

void VoiceManager::setBitCrusherEnabledForEachVoice(bool enabled) {
for (int i = 0; i < NumberOfVoices; i++) {
voices[i].setOscillatorBitCrusher(enabled);
}
}

void VoiceManager::setPhaseStartForEachVoice(bool enabled) {
for (int i = 0; i < NumberOfVoices; i++) {
voices[i].setPhaseStart(enabled);
}
}
7 changes: 5 additions & 2 deletions VoiceManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

class VoiceManager {
private:
static const int NumberOfVoices = 64;
Voice voices[NumberOfVoices];
int NumberOfVoices = 64; // need a static const?
Voice voices[64]; // Max voice count: 64
Voice* findFreeVoice();
public:
void onNoteOn(int noteNumber, int velocity);
Expand All @@ -19,6 +19,7 @@ class VoiceManager {
voice.mOscillator2.setSampleRate(sampleRate);
}
}
void setNumberOfVoices(int num) { NumberOfVoices = num; };
void setOscillatorMixForEachVoice(double mix);
void setOscillatorModeForEachVoice(int oscID, Oscillator::OscillatorMode mode);
void setFilterModeForEachVoice(Filter::FilterMode mode);
Expand All @@ -30,5 +31,7 @@ class VoiceManager {
void setAmpAmountForEachVoice(double amount);
void setSemiOffsetForEachVoice(int oscID, int semi);
void setCentOffsetForEachVoice(int oscID, int cent);
void setBitCrusherEnabledForEachVoice(bool enabled);
void setPhaseStartForEachVoice(bool enabled);
};

10 changes: 6 additions & 4 deletions resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,20 +66,22 @@ instrument determined by PLUG _IS _INST
#define GREEN_KNOB_ID 104
#define BLUE_KNOB_ID 105
#define FILTERMODE_ID 106
#define BLUE_KNOB_CENTER_ID 107
#define ORANGE_KNOB_ID 108
#define BLUE_KNOB_CENTER_ID 107
#define ORANGE_KNOB_ID 108
#define GREEN_KNOB_CENTER_ID 109
#define SWITCHER_LIGHT_ID 110

// Image resource locations for this plug.
#define BG_FN "resources/img/bg.png"
#define PIANO_KEY_FN "resources/img/key.png"
#define WAVEFORM_FN "resources/img/waveform.png"
#define GREEN_KNOB_FN "resources/img/greenknob.png"
#define GREEN_KNOB_CENTER_FN "resources/img/greenknob-center0.png"
#define BLUE_KNOB_FN "resources/img/blueknob.png"
#define BLUE_KNOB_CENTER_FN "resources/img/blueknob-center0.png"
#define FILTERMODE_FN "resources/img/filtermode.png"
#define GREEN_KNOB_CENTER_FN "resources/img/greenknob-center0.png"
#define BLUE_KNOB_CENTER_FN "resources/img/blueknob-center0.png"
#define ORANGE_KNOB_FN "resources/img/orangeknob.png"
#define SWITCHER_LIGHT_FN "resources/img/switcherlight.png"

// GUI default dimensions
#define GUI_WIDTH 665
Expand Down
Binary file modified resources/img/bg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/img/switcherlight.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 18e9dc0

Please sign in to comment.