tracktion-engine 3.0-10-g034fdde4aa5
Tracktion Engine — High level data model for audio applications

« « « Anklang Documentation
Loading...
Searching...
No Matches
tracktion_AutomatableParameter.h
Go to the documentation of this file.
1 /*
2 ,--. ,--. ,--. ,--.
3 ,-' '-.,--.--.,--,--.,---.| |,-.,-' '-.`--' ,---. ,--,--, Copyright 2024
4 '-. .-'| .--' ,-. | .--'| /'-. .-',--.| .-. || \ Tracktion Software
5 | | | | \ '-' \ `--.| \ \ | | | |' '-' '| || | Corporation
6 `---' `--' `--`--'`---'`--'`--' `---' `--' `---' `--''--' www.tracktion.com
7
8 Tracktion Engine uses a GPL/commercial licence - see LICENCE.md for details.
9*/
10
11namespace tracktion { inline namespace engine
12{
13
15 public Selectable,
17{
18public:
19 AutomatableParameter (const juce::String& paramID,
20 const juce::String& name,
23
24 ~AutomatableParameter() override;
25
28
29 const juce::String paramID;
30 const juce::NormalisableRange<float> valueRange;
31 AutomatableEditItem& automatableEditElement;
32
33 juce::Range<float> getValueRange() const { return valueRange.getRange(); }
34 Plugin* getPlugin() const { return plugin; }
35
36 Engine& getEngine() const noexcept;
37 Edit& getEdit() const noexcept;
38 Track* getTrack() const noexcept;
39
40 AutomationCurve& getCurve() const noexcept;
41
42 void attachToCurrentValue (juce::CachedValue<float>&);
43 void attachToCurrentValue (juce::CachedValue<int>&);
44 void attachToCurrentValue (juce::CachedValue<bool>&);
45 void updateFromAttachedValue();
46 void detachFromCurrentValue();
47
48 //==============================================================================
49 virtual juce::String getParameterName() const { return paramName; }
50 virtual juce::String getParameterShortName (int) const { return paramName; }
51 virtual juce::String getLabel() { return {}; }
52
53 // returns a string "pluginname / paramname"
54 virtual juce::String getPluginAndParamName() const;
55
56 // returns "track / pluginname / paramname"
57 virtual juce::String getFullName() const;
58
61
63 EditItemID getOwnerID() const;
64
65 //==============================================================================
66 float getCurrentValue() const noexcept { return currentValue; }
67 float getCurrentNormalisedValue() const noexcept { return valueRange.convertTo0to1 (currentValue); }
68
69 virtual juce::String valueToString (float value) { return valueToStringFunction (value); }
70 virtual float stringToValue (const juce::String& s) { return stringToValueFunction (s); }
71
72 virtual juce::String getCurrentValueAsString() { return valueToString (getCurrentValue()); }
73 juce::String getCurrentValueAsStringWithLabel();
74
75 std::function<juce::String(float)> valueToStringFunction;
76 std::function<float(const juce::String&)> stringToValueFunction;
77
78 virtual void beginParameterChangeGesture() {}
79 virtual void endParameterChangeGesture() {}
80
81 // should be called to change a parameter when a user is actively moving it
82 void setParameter (float value, juce::NotificationType);
83 void setNormalisedParameter (float value, juce::NotificationType);
84 void updateToFollowCurve (TimePosition);
85
88
91
92 bool hasAutomationPoints() const noexcept { return getCurve().getNumPoints() > 0; }
93
94 //==============================================================================
97 {
98 ModifierSource() = default;
99 virtual ~ModifierSource();
100
101 private:
104 };
105
108 {
110
112
114 virtual bool isForModifierSource (const ModifierSource&) const = 0;
115
116 Edit& edit;
117 juce::ValueTree state;
118 juce::CachedValue<float> value, offset, curve;
119 juce::CachedValue<float> inputStart, inputEnd;
120 };
121
127 ModifierAssignment::Ptr addModifier (ModifierSource&, float value = 1.0f, float offset = 0.0f, float curve = 0.5f);
128
131
134
136 bool hasActiveModifierAssignments() const;
137
140
143
144 //==============================================================================
148 float getCurrentExplicitValue() const { return currentParameterValue; }
149
153 float getCurrentBaseValue() const { return currentBaseValue; }
154
158 float getCurrentModifierValue() const { return currentModifierValue; }
159
160 //==============================================================================
164 bool isAutomationActive() const;
165
167 void updateStream();
168
171
172 //==============================================================================
173 virtual bool isParameterActive() const { return true; }
174 virtual bool isDiscrete() const { return false; }
175 virtual int getNumberOfStates() const { return 0; }
176 virtual float getValueForState (int) const { return 0; }
177 virtual int getStateForValue (float) const { return 0; }
178 virtual std::optional<float> getDefaultValue() const;
179
180 virtual bool hasLabels() const { return false; }
181 virtual juce::String getLabelForValue (float) const { return {}; }
182 virtual float snapToState (float val) const { return val; }
183 virtual juce::StringArray getAllLabels() const { return {}; }
184
185 //==============================================================================
187 bool isCurrentlyRecording() const { return isRecording; }
188
191
192 //==============================================================================
193 // called by ParameterControlMappings
194 void midiControllerMoved (float newPosition);
195 void midiControllerPressed();
196
197 //==============================================================================
198 void curveHasChanged();
199
200 //==============================================================================
201 juce::String getSelectableDescription() override { return TRANS("Automation Parameter"); }
202
203 const juce::String paramName;
204 juce::ValueTree parentState;
205
206 //==============================================================================
207 struct Listener
208 {
209 virtual ~Listener() {}
210
213
219
221 virtual void parameterChanged (AutomatableParameter&, float /*newValue*/) {}
224 };
225
226 void addListener (Listener* l) { listeners.add (l); }
227 void removeListener (Listener* l) { listeners.remove (l); }
228
229protected:
230 struct AttachedValue;
231 struct AttachedFloatValue;
232 struct AttachedIntValue;
233 struct AttachedBoolValue;
234 std::unique_ptr<AttachedValue> attachedValue;
236
237 SafeSelectable<Edit> editRef;
238 Plugin* plugin = nullptr;
239 Modifier* modifierOwner = nullptr;
240 MacroParameterList* macroOwner = nullptr;
242 std::atomic<float> currentValue { 0.0f }, currentParameterValue { 0.0f }, currentBaseValue { 0.0f }, currentModifierValue { 0.0f };
243 std::atomic<bool> isRecording { false };
244 bool updateParametersRecursionCheck = false;
245 AsyncCaller parameterChangedCaller { [this] { listeners.call (&Listener::currentValueChanged, *this); } };
246
247 juce::ValueTree modifiersState;
248 struct AutomationSourceList;
249 mutable std::unique_ptr<AutomationSourceList> automationSourceList;
250
251 AutomationSourceList& getAutomationSourceList() const;
252
253 void setParameterValue (float value, bool isFollowingCurve);
254
255 void valueTreePropertyChanged (juce::ValueTree&, const juce::Identifier&) override;
256 void valueTreeChildAdded (juce::ValueTree&, juce::ValueTree&) override;
257 void valueTreeChildRemoved (juce::ValueTree&, juce::ValueTree&, int) override;
258 void valueTreeChildOrderChanged (juce::ValueTree&, int, int) override;
259 void valueTreeParentChanged (juce::ValueTree&) override;
260 void valueTreeRedirected (juce::ValueTree&) override;
261
262 virtual void parameterChanged (float, bool /*byAutomation*/) {}
263
265};
266
267
268//==============================================================================
270template<typename AssignmentType>
272{
274
275 for (auto ass : ap.getAssignments())
276 if (auto type = dynamic_cast<AssignmentType*> (ass))
277 assignments.add (type);
278
279 return assignments;
280}
281
283template<typename ModifierType>
285{
287
288 for (auto mod : ap.getModifiers())
289 if (auto type = dynamic_cast<ModifierType*> (mod))
290 mods.add (type);
291
292 return mods;
293}
294
296template<typename AssignmentType, typename ModifierSourceType, typename EditType>
297juce::ReferenceCountedArray<AssignmentType> getAssignmentsForSource (EditType& edit, const ModifierSourceType& source)
298{
299 TRACKTION_ASSERT_MESSAGE_THREAD
301
302 edit.visitAllAutomatableParams (true, [&] (AutomatableParameter& param)
303 {
304 for (auto* ass : param.getAssignments())
305 if (auto* m = dynamic_cast<AssignmentType*> (ass))
306 if (m->isForModifierSource (source))
307 assignments.add (m);
308 });
309
310 return assignments;
311}
312
314AutomatableParameter::ModifierSource* getSourceForAssignment (const AutomatableParameter::ModifierAssignment&);
315
318
320AutomatableParameter* getParameter (AutomatableParameter::ModifierAssignment&);
321
322//==============================================================================
325{
326 return juce::roundToInt (ap.getCurrentValue());
327}
328
331{
332 return getIntParamValue (ap) == 1;
333}
334
336template<typename Type>
338{
339 return static_cast<Type> (getIntParamValue (ap));
340}
341
342//==============================================================================
348{
349public:
351 ~AutomationDragDropTarget() override;
352
353 //==============================================================================
354 virtual bool hasAnAutomatableParameter() = 0;
355
356 // this will only be called when actually dropped, so if there are multiple params,
357 // it should show UI to choose one and then invoke the callback asynchronously
358 virtual void chooseAutomatableParameter (std::function<void(AutomatableParameter::Ptr)> handleChosenParam,
359 std::function<void()> startLearnMode) = 0;
360
361 // start the process for learning a parameter and call the callback when one is chosen
362 virtual void startParameterLearn (std::function<void(AutomatableParameter::Ptr)>) {}
363
364 // the subclass can call this so it knows to draw itself differently when dragging over
365 bool isAutomatableParameterBeingDraggedOver() const;
366
367 bool isInterestedInDragSource (const SourceDetails& details) override;
368 void itemDragEnter (const SourceDetails& dragSourceDetails) override;
369 void itemDragExit (const SourceDetails& dragSourceDetails) override;
370 void itemDropped (const SourceDetails& dragSourceDetails) override;
371
372 static const char* automatableDragString;
373
374private:
375 bool isAutoParamCurrentlyOver = false;
376};
377
378
379//==============================================================================
381{
382public:
385
386 // just to say that the user has used the drag function
387 virtual void draggedOntoAutomatableParameterTargetBeforeParamSelection() = 0;
388
389 // this is called if they actually choose a param
390 virtual void draggedOntoAutomatableParameterTarget (const AutomatableParameter::Ptr& param) = 0;
391};
392
393
394//==============================================================================
395// A pre-rendered set of interpolated points along a curve, with a cursor which moves through it.
397{
399
400 bool isEmpty() const noexcept { return points.size() <= 1; }
401
402 void setPosition (TimePosition) noexcept;
403 float getCurrentValue() noexcept { return currentValue; }
404
405private:
406 void interpolate (const AutomatableParameter&);
407 void copy (const AutomatableParameter&);
408 int updateIndex (TimePosition newTime);
409
410 void setPositionHiRes (TimePosition newTime) noexcept;
411 void setPositionInterpolated (TimePosition newTime) noexcept;
412
413 struct AutoPoint
414 {
415 TimePosition time = 0_tp;
416 float value = 0.0f;
417 float curve = 0.0f;
418 };
419
421 int currentIndex = -1;
422 float currentValue = 0.0f;
423 bool hiRes = false;
424
426};
427
428}} // namespace tracktion { inline namespace engine
int size() const noexcept
void add(const ElementType &newElement)
void call(Callback &&callback)
Range< ValueType > getRange() const noexcept
ValueType convertTo0to1(ValueType v) const noexcept
ObjectClass * add(ObjectClass *newObject)
Base class for elements that have some kind of automatable parameters.
juce::Array< ModifierSource * > getModifiers() const
Returns all the current ModifierSources currently in use by assignments.
Selectable * getOwnerSelectable() const
Returns the thing that you'd select if you wanted to show this param.
void removeModifier(ModifierAssignment &)
Removes an assignment.
void parameterChangeGestureBegin()
Call to indicate this parameter is about to be changed.
bool isCurrentlyRecording() const
true if the parameter been moved while in an automation record mode.
ModifierAssignment::Ptr addModifier(ModifierSource &, float value=1.0f, float offset=0.0f, float curve=0.5f)
Creates an assignment for a given source.
juce::ReferenceCountedArray< ModifierAssignment > getAssignments() const
Returns all the current ModifierAssignments.
bool hasActiveModifierAssignments() const
Returns true if any ModifierSources are currently in use by assignments.
juce::String getSelectableDescription() override
Subclasses must return a description of what they are.
void resetRecordingStatus()
this is called before and after playback or recording.
float getCurrentExplicitValue() const
This is the value that has been set explicity, either by calling setParameter or the plugin telling u...
void updateStream()
Forces the parameter to update its automation stream for reading automation.
void updateFromAutomationSources(TimePosition)
Updates the parameter and modifier values from its current automation sources.
bool isAutomationActive() const
Returns true if the parameter is being dynamically changed somehow, either through automation or a Mo...
float getCurrentBaseValue() const
This is the current base value of the parameter i.e.
float getCurrentModifierValue() const
This is the ammount of the modifier that has been applied to the base value to give the current param...
EditItemID getOwnerID() const
Returns the thing that you'd select if you wanted to show this param.
void parameterChangeGestureEnd()
Call to indicate this parameter has stopped being to be changed.
Components can implement this to let things know which automatable parameter they control.
The Tracktion Edit class!
The Engine is the central class for all tracktion sessions.
Base class for things that can be selected, and whose properties can appear in the properties panel.
Base class for tracks which contain clips and plugins and can be added to Edit[s].
#define TRANS(stringLiteral)
#define JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(className)
typedef float
NotificationType
int roundToInt(const FloatType value) noexcept
Type getTypedParamValue(const AutomatableParameter &ap)
Returns an int version of an AutomatableParameter cast to a enum type.
juce::ReferenceCountedArray< AssignmentType > getAssignmentsForSource(EditType &edit, const ModifierSourceType &source)
Iterates an Edit looking for all parameters that assigned to a given parameter.
AutomatableParameter::ModifierSource * getSourceForAssignment(const AutomatableParameter::ModifierAssignment &ass)
Iterates an Edit looking for the source of this assignment.
juce::ReferenceCountedArray< AutomatableParameter > getAllParametersBeingModifiedBy(Edit &edit, AutomatableParameter::ModifierSource &m)
Iterates an Edit looking for all parameters that are being modified by the given ModifierSource.
bool getBoolParamValue(const AutomatableParameter &ap)
Returns a bool version of an AutomatableParameter.
AutomatableParameter * getParameter(AutomatableParameter::ModifierAssignment &assignment)
Iterates an Edit looking for the parameter that this ModifierAssignment has been made from.
juce::ReferenceCountedArray< AssignmentType > getAssignmentsOfType(const AutomatableParameter &ap)
Returns all the Assignments of a specific type.
juce::Array< ModifierType * > getModifiersOfType(const AutomatableParameter &ap)
Returns all the modifers in use of a specific type.
int getIntParamValue(const AutomatableParameter &ap)
Returns an int version of an AutomatableParameter.
Represents a position in real-life time.
virtual void currentValueChanged(AutomatableParameter &)
Called when the current value of the parameter changed, either from setting the parameter,...
virtual void parameterChanged(AutomatableParameter &, float)
Called when the parameter is changed by the plugin or host, not from automation.
virtual void curveHasChanged(AutomatableParameter &)=0
Called when the automation curve has changed, point time, value or curve.
Connects a modifier source to an AutomatableParameter.
virtual bool isForModifierSource(const ModifierSource &) const =0
Must return true if this assigment is for the given source.
Base class for things that can be used to modify parameters.
ID for objects of type EditElement - e.g.
time