11namespace tracktion {
inline namespace engine
21 void updateStreamTime (
TimePosition editTime,
int numSamples)
override
23 const double blockLength = numSamples / modifier.
getSampleRate();
27 const auto syncTypeThisBlock =
juce::roundToInt (modifier.syncTypeParam->getCurrentValue());
28 const auto rateTypeThisBlock = getTypedParamValue<ModifierCommon::RateType> (*modifier.rateTypeParam);
30 const float rateThisBlock = modifier.rateParam->getCurrentValue();
32 if (rateTypeThisBlock == ModifierCommon::hertz)
34 const float durationPerPattern = 1.0f / rateThisBlock;
35 ramp.setDuration (durationPerPattern);
37 if (syncTypeThisBlock == ModifierCommon::transport)
40 setPhase (ramp.getProportion());
43 ramp.process ((
float) blockLength);
47 tempoSequence.
set (editTime);
48 const auto currentTempo = tempoSequence.
getTempo();
50 const auto proportionOfBar = ModifierCommon::getBarFraction (rateTypeThisBlock);
52 if (syncTypeThisBlock == ModifierCommon::transport)
55 const auto bars = (editTimeInBeats / currentTimeSig.numerator) * rateThisBlock;
57 if (rateTypeThisBlock >= ModifierCommon::fourBars && rateTypeThisBlock <= ModifierCommon::sixtyFourthD)
59 const double virtualBars = bars / proportionOfBar;
60 setPhase ((
float)
std::fmod (virtualBars, 1.0f));
65 const double bpm = (currentTempo * rateThisBlock) / proportionOfBar;
66 const double secondsPerBeat = 60.0 / bpm;
67 const float secondsPerStep =
static_cast<float> (secondsPerBeat * currentTimeSig.numerator);
68 const float secondsPerPattern = secondsPerStep;
69 ramp.setDuration (secondsPerPattern);
71 setPhase (ramp.getProportion());
74 ramp.process ((
float) blockLength);
79 void setPhase (
float newPhase)
81 newPhase += modifier.phaseParam->getCurrentValue();
83 while (newPhase >= 1.0f) newPhase -= 1.0f;
84 while (newPhase < 0.0f) newPhase += 1.0f;
88 previousRandom = currentRandom;
90 randomDifference = currentRandom - previousRandom;
96 auto getValue = [
this, newPhase]
98 using namespace PredefinedWavetable;
99 switch (getTypedParamValue<LFOModifier::Wave> (*modifier.waveParam))
101 case waveSine:
return getSinSample (newPhase);
102 case waveTriangle:
return getTriangleSample (newPhase);
103 case waveSawUp:
return getSawUpSample (newPhase);
104 case waveSawDown:
return getSawDownSample (newPhase);
105 case waveSquare:
return getSquareSample (newPhase);
106 case fourStepsUp:
return getStepsUpSample (newPhase, 4);
107 case fourStepsDown:
return getStepsDownSample (newPhase, 4);
108 case eightStepsUp:
return getStepsUpSample (newPhase, 8);
109 case eightStepsDown:
return getStepsDownSample (newPhase, 8);
110 case random:
return currentRandom;
111 case noise:
return (randomDifference * newPhase) + previousRandom;
117 float newValue = getValue();
118 newValue *= modifier.depthParam->getCurrentValue();
119 newValue += modifier.offsetParam->getCurrentValue();
122 newValue = (newValue * 2.0f) - 1.0f;
127 void resync (
double duration)
129 const auto type =
juce::roundToInt (modifier.syncTypeParam->getCurrentValue());
131 if (type == ModifierCommon::note)
133 ramp.setPosition (0.0f);
137 ramp.process ((
float) duration);
146 float previousRandom = 0.0f, currentRandom = 0.0f, randomDifference = 0.0f;
155 auto um = &edit.getUndoManager();
157 wave.referTo (
state, IDs::wave, um, waveSine);
158 syncType.referTo (
state, IDs::syncType, um,
float (ModifierCommon::free));
159 rate.referTo (
state, IDs::rate, um, 1.0f);
160 rateType.referTo (
state, IDs::rateType, um,
float (ModifierCommon::bar));
161 depth.referTo (
state, IDs::depth, um, 1.0f);
162 bipolar.referTo (
state, IDs::bipolar, um);
163 phase.referTo (
state, IDs::phase, um);
164 offset.referTo (
state, IDs::offset, um);
171 addAutomatableParameter (p);
172 p->attachToCurrentValue (val);
183 valueRange.setSkewForCentre (centreVal);
185 addAutomatableParameter (p);
186 p->attachToCurrentValue (val);
191 using namespace ModifierCommon;
192 waveParam = addDiscreteParam (
"wave",
TRANS(
"Wave"), { 0.0f, (
float) getWaveNames().size() - 1 }, wave, getWaveNames());
193 syncTypeParam = addDiscreteParam (
"syncType",
TRANS(
"Sync type"), { 0.0f, (
float) getSyncTypeChoices().
size() - 1 }, syncType, getSyncTypeChoices());
194 rateParam = addParam (
"rate",
TRANS(
"Rate"), { 0.01f, 50.0f }, 1.0f, rate, {});
195 rateTypeParam = addDiscreteParam (
"rateType",
TRANS(
"Rate Type"), { 0.0f, (
float) getRateTypeChoices().
size() - 1 }, rateType, getRateTypeChoices());
196 depthParam = addParam (
"depth",
TRANS(
"Depth"), { 0.0f, 1.0f }, 0.5f, depth, {});
197 bipolarParam = addDiscreteParam (
"biopolar",
TRANS(
"Bipoloar"), { 0.0f, 1.0f }, bipolar, {
NEEDS_TRANS(
"Uni-polar"),
NEEDS_TRANS(
"Bi-polar") });
198 phaseParam = addParam (
"phase",
TRANS(
"Phase"), { 0.0f, 1.0f }, 0.5f, phase, {});
199 offsetParam = addParam (
"offset",
TRANS(
"Offset"), { 0.0f, 1.0f }, 0.5f, offset, {});
201 changedTimer.setCallback ([
this]
203 changedTimer.stopTimer();
210LFOModifier::~LFOModifier()
213 notifyListenersOfDeletion();
217 for (
auto p : getAutomatableParameters())
218 p->detachFromCurrentValue();
220 deleteAutomatableParameters();
254 lfoModifierID (lfo.
itemID)
258bool LFOModifier::Assignment::isForModifierSource (
const ModifierSource& source)
const
260 if (
auto* mod =
dynamic_cast<const LFOModifier*
> (&source))
261 return mod->itemID == lfoModifierID;
266LFOModifier::Ptr LFOModifier::Assignment::getLFOModifier()
const
268 if (
auto mod = findModifierTypeForID<LFOModifier> (edit, lfoModifierID))
294void LFOModifier::valueTreeChanged()
float nextFloat() noexcept
int size() const noexcept
void startTimerHz(int timerFrequencyHz) noexcept
bool isTimerRunning() const noexcept
void addListener(Listener *listener)
void removeListener(Listener *listener)
void restoreChangedParametersFromState()
Restores the value of any explicitly set parameters.
void updateParameterStreams(TimePosition)
Updates all the parameter streams to their positions at this time.
const EditItemID itemID
Every EditItem has an ID which is unique within the edit.
The Tracktion Edit class!
void removeModifierTimer(ModifierTimer &)
Removes a ModifierTimer previously added.
TempoSequence tempoSequence
The global TempoSequence of this Edit.
void addModifierTimer(ModifierTimer &)
Adds a ModifierTimer to be updated each block.
float getCurrentValue() override
Returns the current value of the LFO.
void applyToBuffer(const PluginRenderContext &) override
Sub classes should implement this to process the Modifier.
float getCurrentPhase() const
Returns the current phase between 0 & 1.
void initialise() override
Call this once after construction to connect it to the audio graph.
AutomatableParameter::ModifierAssignment * createAssignment(const juce::ValueTree &) override
Must return a new ModifierAssignment for a given state.
virtual void changed()
This should be called to send a change notification to any SelectableListeners that are registered wi...
#define TRANS(stringLiteral)
#define NEEDS_TRANS(stringLiteral)
bool isPositiveAndBelow(Type1 valueToTest, Type2 upperLimit) noexcept
int roundToInt(const FloatType value) noexcept
tempo::Sequence::Position createPosition(const TempoSequence &s)
Creates a Position to iterate over the given TempoSequence.
bool getBoolParamValue(const AutomatableParameter &ap)
Returns a bool version of an AutomatableParameter.
constexpr double inBeats() const
Returns the position as a number of beats.
Represents a position in real-life time.
constexpr double inSeconds() const
Returns the TimePosition as a number of seconds.
A Sequence::Position is an iterator through a Sequence.
TimeSignature getTimeSignature() const
Returns the current TimeSignature of the Position.
BeatPosition getBeats() const
Returns the current beats of the Position.
void set(TimePosition)
Sets the Position to a new time.
double getTempo() const
Returns the current tempo of the Position.
Connects a modifier source to an AutomatableParameter.
Base class for objects which need to know about the global Edit time every block.
Bass class for parameter Modifiers.
juce::ValueTree state
Modifier internal state.
void setEditTime(TimePosition newEditTime)
Subclasses can call this to update the edit time of the current value.
double getSampleRate() const
Returns the sample rate the Modifier has been initialised with.
The context passed to plugin render methods to provide it with buffers to fill.
int bufferNumSamples
The number of samples to write into the audio buffer.
MidiMessageArray * bufferForMidiMessages
A buffer of MIDI events to process.
A ramp which goes between 0 and 1 over a set duration.