22 void reset (
double sr,
double time) { delta = 1.0f / T (sr *
time); }
23 T getCurrentValue() {
return currentValue; }
24 void setValue (T v) { targetValue = v; }
25 void snapToValue() { currentValue = targetValue; }
29 if (targetValue != currentValue)
30 for (
int i = 0; i < n; i++)
36 if (currentValue < targetValue)
37 currentValue =
juce::jmin (targetValue, currentValue + delta);
38 else if (currentValue > targetValue)
39 currentValue =
juce::jmax (targetValue, currentValue - delta);
43 void setValueUnsmoothed (T v)
50 T delta = 0, targetValue = 0, currentValue = 0;
73 Parameters (
float frequencyIn,
float phaseOffsetIn,
float offsetIn,
float depthIn,
74 WaveShape waveShapeIn,
float pulseWidthIn) :
75 waveShape (waveShapeIn), frequency (frequencyIn), phaseOffset (phaseOffsetIn),
76 offset (offsetIn), depth (depthIn), pulseWidth (pulseWidthIn) {}
78 WaveShape waveShape = sine;
79 float frequency = 0, phaseOffset = 0, offset = 0, depth = 0, pulseWidth = 0;
83 void setSampleRate (
double newSampleRate) { sampleRate = newSampleRate; }
84 void setParameters (Parameters newParameters) { parameters = newParameters; }
85 void reset() { phase = 0; }
87 void process (
int numSamples)
90 if (parameters.frequency > 0.001f)
91 step = parameters.frequency / sampleRate;
93 for (
int i = 0; i < numSamples; i++)
99 float localPhase = 0.0f;
101 if (parameters.phaseOffset != 0)
102 localPhase = wrapValue ((
float)
std::fmod (phase + parameters.phaseOffset, 1.0f), 1.0f);
104 localPhase = wrapValue ((
float) phase, 1.0f);
106 jassert (localPhase >= 0.0f && localPhase <= 1.0f);
108 if (parameters.waveShape == random)
110 if (localPhase < lastLocalPhase)
111 lastRandomVal = randomSource.
nextFloat() * 2.0f - 1.0f;
113 lastLocalPhase = localPhase;
118 float getCurrentValue()
120 float val = 0.0f, localPhase = 0.0f;
122 if (parameters.phaseOffset != 0)
123 localPhase = wrapValue ((
float)
std::fmod (phase + parameters.phaseOffset, 1.0f), 1.0f);
125 localPhase = wrapValue ((
float) phase, 1.0f);
127 jassert (localPhase >= 0.0f && localPhase <= 1.0f);
129 switch (parameters.waveShape)
131 case none: val = 0;
break;
133 case triangle: val = (localPhase < 0.5f) ? (4.0f * localPhase - 1.0f) : (-4.0f * localPhase + 3.0f);
break;
134 case sawUp: val = localPhase * 2.0f - 1.0f;
break;
135 case sawDown: val = (1.0f - localPhase) * 2.0f - 1.0f;
break;
136 case square: val = (localPhase < parameters.pulseWidth) ? 1.0f : -1.0f;
break;
137 case random: val = lastRandomVal;
break;
140 return (val * parameters.depth + parameters.offset);
144 Parameters parameters;
146 double phase = 0, lastLocalPhase = 1, sampleRate = 0;
147 float lastRandomVal = 0;
151 inline float wrapValue (
float v,
float range)
153 while (v >= range) v -= range;
154 while (v < 0) v += range;
169 bool isMono()
const {
return voiceModeValue.
get() == 0; }
170 bool isLegato()
const {
return voiceModeValue.
get() == 1; }
171 bool isPoly()
const {
return voiceModeValue.
get() == 2; }
174 static const char* getPluginName() {
return NEEDS_TRANS(
"4OSC"); }
175 static const char* xmlTypeName;
178 juce::String getPluginType()
override {
return xmlTypeName; }
179 juce::String getShortName (
int)
override {
return "4OSC"; }
181 bool needsConstantBufferSize()
override {
return false; }
188 void reset()
override;
193 bool takesMidiInput()
override {
return true; }
194 bool takesAudioInput()
override {
return false; }
195 bool isSynth()
override {
return true; }
196 bool producesAudioWhenNoAudioInput()
override {
return true; }
197 double getTailLength()
const override {
return ampRelease->getCurrentValue(); }
199 void restorePluginStateFromValueTree (
const juce::ValueTree&)
override;
201 float getCurrentTempo() {
return currentTempo; }
216 detuneValue, spreadValue, panValue;
222 copyPropertiesToCachedValues (v, tuneValue, fineTuneValue, levelValue, pulseWidthValue,
223 detuneValue, spreadValue, panValue, waveShapeValue, voicesValue);
244 copyPropertiesToCachedValues (v, rateValue, beatValue, depthValue, waveShapeValue, syncValue);
262 copyPropertiesToCachedValues (v, modAttackValue, modDecayValue, modSustainValue, modReleaseValue);
270 juce::CachedValue<float> filterAttackValue, filterDecayValue, filterSustainValue, filterReleaseValue, filterFreqValue,
271 filterResonanceValue, filterAmountValue, filterKeyValue, filterVelocityValue;
276 AutomatableParameter::Ptr filterAttack, filterDecay, filterSustain, filterRelease, filterFreq, filterResonance, filterAmount, filterKey, filterVelocity;
310 ccPolyMode = ccBankSelect + 127,
329 for (
auto& d : depths)
333 inline void updateCachedInfo()
338 if (depths[i] >= -1.0f && f == -1) f = i;
339 if (depths[i] >= -1.0) l = i;
346 inline bool isModulated()
348 return firstModIndex != -1 && lastModIndex != -1;
351 int firstModIndex = -1, lastModIndex = -1;
352 float depths[numModSources] = {};
356 float controllerValues[128] = {0};
358 float getLevel (
int channel);
362 void valueTreeChanged()
override;
366 void handleAsyncUpdate()
override;
367 void handleController (
int midiChannel,
int controllerNumber,
int controllerValue)
override;
369 void flushPluginStateToValueTree()
override;
371 void loadModMatrix();
372 void setupTextFunctions();
378 float paramValue (AutomatableParameter::Ptr param);
386 bool flushingState =
false;
387 float currentTempo = 0.0f;
388 LevelMeasurer levelMeasurer;
389 DbTimePair levels[2];
The context passed to plugin render methods to provide it with buffers to fill.