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 numStepsThisBlock = modifier.numStepsParam->getCurrentValue();
31 const float rateThisBlock = modifier.rateParam->getCurrentValue();
33 if (rateTypeThisBlock == ModifierCommon::hertz)
35 const float durationPerPattern = numStepsThisBlock * (1.0f / rateThisBlock);
36 ramp.setDuration (durationPerPattern);
38 if (syncTypeThisBlock == ModifierCommon::transport)
41 const int step =
static_cast<int> (
std::floor (numStepsThisBlock * ramp.getProportion()));
45 ramp.process ((
float) blockLength);
49 tempoSequence.
set (editTime);
50 const auto currentTempo = tempoSequence.
getTempo();
52 const auto proportionOfBar = ModifierCommon::getBarFraction (rateTypeThisBlock);
54 if (syncTypeThisBlock == ModifierCommon::transport)
57 const auto bars = (editTimeInBeats / currentTimeSig.numerator) * rateThisBlock;
59 if (rateTypeThisBlock >= ModifierCommon::fourBars && rateTypeThisBlock <= ModifierCommon::sixtyFourthD)
61 const double virtualBars = bars / proportionOfBar;
62 const int step =
static_cast<int> (
std::fmod (virtualBars, numStepsThisBlock));
68 const double bpm = (currentTempo * rateThisBlock) / proportionOfBar;
69 const double secondsPerBeat = 60.0 / bpm;
70 const float secondsPerStep =
static_cast<float> (secondsPerBeat * currentTimeSig.numerator);
71 const float secondsPerPattern = (numStepsThisBlock * secondsPerStep);
72 ramp.setDuration (secondsPerPattern);
74 const int step =
static_cast<int> (
std::floor (numStepsThisBlock * ramp.getProportion()));
78 ramp.process ((
float) blockLength);
83 void resync (
double duration)
85 const auto type =
juce::roundToInt (modifier.syncTypeParam->getCurrentValue());
87 if (type == ModifierCommon::note)
89 ramp.setPosition (0.0f);
93 ramp.process ((
float) duration);
106 auto um = &edit.getUndoManager();
108 restoreStepsFromProperty();
110 syncType.referTo (
state, IDs::syncType, um,
float (ModifierCommon::free));
111 numSteps.referTo (
state, IDs::numSteps, um, 16.0f);
112 rate.referTo (
state, IDs::rate, um, 1.0f);
113 rateType.referTo (
state, IDs::rateType, um,
float (ModifierCommon::bar));
114 depth.referTo (
state, IDs::depth, um, 1.0f);
121 addAutomatableParameter (p);
122 p->attachToCurrentValue (val);
131 valueRange.setSkewForCentre (centreVal);
133 addAutomatableParameter (p);
134 p->attachToCurrentValue (val);
139 using namespace ModifierCommon;
140 syncTypeParam = addDiscreteParam (
"syncType",
TRANS(
"Sync type"), { 0.0f, (
float) note }, syncType, getSyncTypeChoices());
141 numStepsParam = addParam (
"numSteps",
TRANS(
"Steps"), { 2.0f, 64.0f, 1.0f }, 31.0f, numSteps, {});
142 rateParam = addParam (
"rate",
TRANS(
"Rate"), { 0.01f, 50.0f }, 1.0f, rate, {});
143 rateTypeParam = addDiscreteParam (
"rateType",
TRANS(
"Rate Type"), { 0.0f, (
float) sixtyFourthD }, rateType, getRateTypeChoices());
144 depthParam = addParam (
"depth",
TRANS(
"Depth"), { -1.0f, 1.0f }, 0.0f, depth, {});
146 changedTimer.setCallback ([
this]
148 changedTimer.stopTimer();
155StepModifier::~StepModifier()
158 notifyListenersOfDeletion();
162 for (
auto p : getAutomatableParameters())
163 p->detachFromCurrentValue();
165 deleteAutomatableParameters();
179 return getStep (getCurrentStep()) * depthParam->getCurrentValue();
183float StepModifier::getStep (
int step)
const
189void StepModifier::setStep (
int step,
float value)
195 flushStepsToProperty();
198int StepModifier::getCurrentStep() const noexcept
221 stepModifierID (sm.
itemID)
225bool StepModifier::Assignment::isForModifierSource (
const ModifierSource& source)
const
227 if (
auto* mod =
dynamic_cast<const StepModifier*
> (&source))
228 return mod->itemID == stepModifierID;
233StepModifier::Ptr StepModifier::Assignment::getStepModifier()
const
235 if (
auto mod = findModifierTypeForID<StepModifier> (edit, stepModifierID))
244 return TRANS(
"Step Modifier");
248void StepModifier::flushStepsToProperty()
252 for (
int i = 0; i < maxNumSteps; ++i)
259void StepModifier::restoreStepsFromProperty()
263 if (
auto mb =
state[IDs::stepData].getBinaryData())
268 while (! stream.isExhausted())
269 steps[index++] = stream.readFloat();
274void StepModifier::valueTreeChanged()
282 if (v ==
state && i == IDs::stepData)
283 restoreStepsFromProperty();
285 ValueTreeAllEventListener::valueTreePropertyChanged (v, i);
MemoryBlock getMemoryBlock() const
virtual bool writeFloat(float value)
void startTimerHz(int timerFrequencyHz) noexcept
bool isTimerRunning() const noexcept
ValueTree & setProperty(const Identifier &name, const var &newValue, UndoManager *undoManager)
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.
juce::UndoManager & getUndoManager() noexcept
Returns the juce::UndoManager used for this Edit.
void addModifierTimer(ModifierTimer &)
Adds a ModifierTimer to be updated each block.
virtual void changed()
This should be called to send a change notification to any SelectableListeners that are registered wi...
void initialise() override
Call this once after construction to connect it to the audio graph.
void applyToBuffer(const PluginRenderContext &) override
Sub classes should implement this to process the Modifier.
float getCurrentValue() override
Must return the current value of the modifier.
AutomatableParameter::ModifierAssignment * createAssignment(const juce::ValueTree &) override
Must return a new ModifierAssignment for a given state.
juce::String getSelectableDescription() override
Subclasses must return a description of what they are.
#define TRANS(stringLiteral)
Type jlimit(Type lowerLimit, Type upperLimit, Type valueToConstrain) noexcept
bool isPositiveAndBelow(Type1 valueToTest, Type2 upperLimit) noexcept
int roundToInt(const FloatType value) noexcept
constexpr int numElementsInArray(Type(&)[N]) noexcept
tempo::Sequence::Position createPosition(const TempoSequence &s)
Creates a Position to iterate over the given TempoSequence.
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.