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

« « « Anklang Documentation
Loading...
Searching...
No Matches
tracktion_MacroParameter.cpp
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
14MacroParameter::Assignment::Assignment (const juce::ValueTree& v, const MacroParameter& mp)
15 : AutomatableParameter::ModifierAssignment (mp.edit, v),
16 macroParamID (EditItemID::fromVar (mp.paramID))
17{
18}
19
20bool MacroParameter::Assignment::isForModifierSource (const AutomatableParameter::ModifierSource& source) const
21{
22 // NB: the paramID is a string that can be any format, but for macro params, we use it to hold an EditItemID
23 if (auto* mp = dynamic_cast<const MacroParameter*> (&source))
24 return mp->paramID == macroParamID.toString();
25
26 return false;
27}
28
29//==============================================================================
30MacroParameter::MacroParameter (AutomatableEditItem& automatable, Edit& e, const juce::ValueTree& v)
31 : AutomatableParameter (EditItemID::fromID (v).toString(),
32 EditItemID::fromID (v).toString(),
33 automatable, { 0.0f, 1.0f }),
34 edit (e), state (v)
35{
36 jassert (EditItemID::fromID (v).isValid());
37
38 auto um = &edit.getUndoManager();
39 value.referTo (state, IDs::value, um, 0.5f);
40 defaultValue.referTo (state, IDs::defaultValue, um);
41 macroName.referTo (state, IDs::name, um);
42
43 attachToCurrentValue (value);
44}
45
46MacroParameter::~MacroParameter()
47{
48 detachFromCurrentValue();
49}
50
51void MacroParameter::initialise()
52{
53 jassert (! edit.isLoading());
54}
55
56std::optional<float> MacroParameter::getDefaultValue() const
57{
58 return defaultValue;
59}
60
61void MacroParameter::parameterChanged (float, bool byAutomation)
62{
63 // Update any non-active parameters
64 if (byAutomation)
65 return;
66
67 TRACKTION_ASSERT_MESSAGE_THREAD
68 auto cursorPos = edit.getTransport().getPosition();
69
70 for (auto ap : getAllParametersBeingModifiedBy (edit, *this))
71 if (! ap->automatableEditElement.isBeingActivelyPlayed())
72 ap->updateFromAutomationSources (cursorPos);
73}
74
75//==============================================================================
77{
78 for (auto mpl : getAllMacroParameterLists (e))
79 for (auto mp : mpl->getMacroParameters())
80 if (EditItemID::fromVar (mp->paramID) == pid)
81 return mp;
82
83 return {};
84}
85
86//==============================================================================
87struct MacroParameterList::List : public ValueTreeObjectList<MacroParameter>
88{
91 macroParameterList (mpl), edit (mpl.edit)
92 {
93 jassert (v.hasType (IDs::MACROPARAMETERS));
94 rebuildObjects();
95 }
96
97 ~List() override
98 {
99 freeObjects();
100 }
101
102 juce::ReferenceCountedArray<MacroParameter> getMacroParameters() const
103 {
105
106 // This is verbose but directly returning macroParameters causes a
107 // crash in optimised gcc Linux builds, could be a compiler bug
108 {
109 const juce::ScopedLock sl (macroParameters.getLock());
110 params.ensureStorageAllocated (macroParameters.size());
111
112 for (auto& p : macroParameters)
113 params.add (p);
114 }
115
116 return params;
117 }
118
119 void visitMacroParameters (const std::function<void(AutomatableParameter&)>& visit) const
120 {
121 const juce::ScopedLock sl (macroParameters.getLock());
122
123 for (auto& p : macroParameters)
124 visit (*p);
125 }
126
127 MacroParameterList& macroParameterList;
128 Edit& edit;
129
130private:
132
133 bool isSuitableType (const juce::ValueTree& v) const override
134 {
135 return v.hasType (IDs::MACROPARAMETER);
136 }
137
138 MacroParameter* createNewObject (const juce::ValueTree& v) override
139 {
140 auto* mp = new MacroParameter (macroParameterList, edit, v);
141 macroParameters.add (mp);
142 macroParameterList.addAutomatableParameter (mp);
143 return mp;
144 }
145
146 void deleteObject (MacroParameter* mp) override
147 {
148 jassert (mp != nullptr);
149 macroParameterList.deleteParameter (mp);
150 macroParameters.removeObject (mp);
151 }
152
153 void newObjectAdded (MacroParameter*) override { macroParameterList.sendChangeMessage(); }
154
155 void objectRemoved (MacroParameter* mp) override
156 {
157 for (auto p : getAllParametersBeingModifiedBy (edit, *mp))
158 p->removeModifier (*mp);
159
160 for (auto t : getAllTracks (edit))
161 t->hideAutomatableParametersForSource (EditItemID::fromVar (mp->paramID));
162
163 macroParameterList.sendChangeMessage();
164 }
165
166 void objectOrderChanged() override { macroParameterList.sendChangeMessage(); }
167
168 void valueTreePropertyChanged (juce::ValueTree& v, const juce::Identifier& i) override
169 {
170 if (v.hasType (IDs::MACROPARAMETER) && i == IDs::name)
171 macroParameterList.rebuildParameterTree();
172
174 }
175};
176
177//==============================================================================
178MacroParameterList::MacroParameterList (Edit& e, const juce::ValueTree& v)
179 : AutomatableEditItem (e, v),
180 state (v)
181{
182 jassert (state.hasType (IDs::MACROPARAMETERS));
183 jassert (itemID.isValid());
184 list = std::make_unique<List> (*this, v);
185
187}
188
189MacroParameterList::~MacroParameterList()
190{
191 TRACKTION_ASSERT_MESSAGE_THREAD
192}
193
194MacroParameter* MacroParameterList::createMacroParameter()
195{
196 TRACKTION_ASSERT_MESSAGE_THREAD
197 auto* um = &edit.getUndoManager();
198
199 juce::ValueTree v (IDs::MACROPARAMETER);
200 edit.createNewItemID().writeID (v, nullptr);
201 state.addChild (v, -1, um);
202
203 auto mp = list->objects.getLast();
204 mp->macroName = TRANS("Macro") + " " + juce::String (list->objects.size());
205 jassert (mp != nullptr);
206 jassert (mp->state == v);
208
209 return mp;
210}
211
212void MacroParameterList::removeMacroParameter (MacroParameter& mp)
213{
214 TRACKTION_ASSERT_MESSAGE_THREAD
215 jassert (list != nullptr);
216 auto* um = &edit.getUndoManager();
217
218 // Remove any tracks which might be showing automation for this param
219 {
220 auto paramID = EditItemID::fromVar (mp.paramID);
221
222 for (auto t : getAllTracks (edit))
223 t->hideAutomatableParametersForSource (paramID);
224 }
225
226 // Remove the child from the parent
227 if (mp.state.getParent() == state)
228 state.removeChild (mp.state, um);
229 else
231
233}
234
235void MacroParameterList::hideMacroParametersFromTracks() const
236{
237 if (! edit.isLoading())
238 {
239 TRACKTION_ASSERT_MESSAGE_THREAD
240 }
241
242 for (auto mp : getMacroParameters())
243 {
244 auto paramID = EditItemID::fromVar (mp->paramID);
245
246 for (auto t : getAllTracks (edit))
247 t->hideAutomatableParametersForSource (paramID);
248 }
249}
250
251juce::ReferenceCountedArray<MacroParameter> MacroParameterList::getMacroParameters() const
252{
253 return list->getMacroParameters();
254}
255
256void MacroParameterList::visitMacroParameters (const std::function<void(AutomatableParameter&)>& visit) const
257{
258 list->visitMacroParameters (visit);
259}
260
261Track* MacroParameterList::getTrack() const
262{
263 TRACKTION_ASSERT_MESSAGE_THREAD
264
265 for (auto p (state.getParent()); p.isValid(); p = p.getParent())
266 if (TrackList::isTrack (p))
267 return findTrackForState (edit, p);
268
269 return {};
270}
271
273{
274 if (mpl == nullptr)
275 return {};
276
277 for (auto p : getAllPlugins (mpl->edit, false))
278 if (p->getMacroParameterList() == mpl)
279 return p;
280
281 return {};
282}
283
284//==============================================================================
286 : ownerEdit (e), parentStateForList (p)
287{
288 auto existing = parentStateForList.getChildWithName (IDs::MACROPARAMETERS);
289
290 if (existing.isValid())
291 macroParameterList = std::make_unique<MacroParameterList> (ownerEdit, existing);
292}
293
295{
296 return macroParameterList.get();
297}
298
300{
301 if (macroParameterList == nullptr)
302 macroParameterList = std::make_unique<MacroParameterList> (ownerEdit, parentStateForList.getOrCreateChildWithName (IDs::MACROPARAMETERS, &ownerEdit.getUndoManager()));
303
304 return *macroParameterList;
305}
306
307juce::ReferenceCountedArray<MacroParameter> MacroParameterElement::getMacroParameters() const
308{
309 if (macroParameterList != nullptr)
310 return macroParameterList->getMacroParameters();
311
312 return {};
313}
314
315
316}} // namespace tracktion { inline namespace engine
void referTo(ValueTree &tree, const Identifier &property, UndoManager *um)
bool isValid() const noexcept
void removeObject(ObjectClass *objectToRemove)
void ensureStorageAllocated(const int minNumElements)
ObjectClass * add(ObjectClass *newObject)
void removeChild(const ValueTree &child, UndoManager *undoManager)
void addChild(const ValueTree &child, int index, UndoManager *undoManager)
ValueTree getParent() const noexcept
ValueTree getChildWithName(const Identifier &type) const
ValueTree getOrCreateChildWithName(const Identifier &type, UndoManager *undoManager)
Base class for elements that have some kind of automatable parameters.
void restoreChangedParametersFromState()
Restores the value of any explicitly set parameters.
void updateFromAutomationSources(TimePosition)
Updates the parameter and modifier values from its current automation sources.
const EditItemID itemID
Every EditItem has an ID which is unique within the edit.
The Tracktion Edit class!
TransportControl & getTransport() const noexcept
Returns the TransportControl which is used to stop/stop/position playback and recording.
bool isLoading() const
Returns true if the Edit's not yet fully loaded.
juce::UndoManager & getUndoManager() noexcept
Returns the juce::UndoManager used for this Edit.
EditItemID createNewItemID() const
Returns a new EditItemID to use for a new EditItem.
MacroParameterList * getMacroParameterList()
If no parameters have been created, this may return nullptr.
MacroParameterList & getMacroParameterListForWriting()
This ensures that the list has been created.
MacroParameterElement(Edit &, const juce::ValueTree &)
Constructor.
A MacroParameter is an AutomatableParameter which is a collection of Mappings.
TimePosition getPosition() const
Returns the current transport position.
T is_pointer_v
#define TRANS(stringLiteral)
#define jassert(expression)
#define jassertfalse
Track * findTrackForState(const Edit &edit, const juce::ValueTree &v)
Returns the Track with a given state if contained in the Edit.
juce::ReferenceCountedArray< AutomatableParameter > getAllParametersBeingModifiedBy(Edit &edit, AutomatableParameter::ModifierSource &m)
Iterates an Edit looking for all parameters that are being modified by the given ModifierSource.
juce::Array< MacroParameterList * > getAllMacroParameterLists(const Edit &edit)
Returns all the MacroParameterLists in an Edit.
juce::Array< Track * > getAllTracks(const Edit &edit)
Returns all the tracks in an Edit.
MacroParameter::Ptr getMacroParameterForID(Edit &e, EditItemID pid)
Searched the Edit for a MacroParameter with this ID.
Plugin::Array getAllPlugins(const Edit &edit, bool includeMasterVolume)
Returns all the plugins in a given Edit.
Plugin::Ptr getOwnerPlugin(MacroParameterList *mpl)
If this MacroParameterList belongs to an Plugin, this will return it.
Base class for things that can be used to modify parameters.
ID for objects of type EditElement - e.g.
static bool isTrack(const juce::ValueTree &) noexcept
Returns true if the given ValeTree is for a known Track type.