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

« « « Anklang Documentation
Loading...
Searching...
No Matches
tracktion_Plugin.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{
16 PluginCreationInfo (const PluginCreationInfo&) = default;
18 PluginCreationInfo& operator= (PluginCreationInfo&&) = delete;
19
20 PluginCreationInfo (Edit& ed, const juce::ValueTree& s, bool isNew) noexcept
21 : edit (ed), state (s), isNewPlugin (isNew) {}
22
23 PluginCreationInfo() = delete;
24 PluginCreationInfo& operator= (const PluginCreationInfo&) = delete;
25
26 Edit& edit;
27 juce::ValueTree state;
28 bool isNewPlugin = false;
29};
30
31//==============================================================================
36{
37 TimePosition startTime;
38 double sampleRate;
39 int blockSizeSamples;
40};
41
42//==============================================================================
43//==============================================================================
48{
50 const juce::AudioChannelSet& bufferChannels,
51 int bufferStart, int bufferSize,
52 MidiMessageArray* midiBuffer, double midiOffset,
53 TimeRange editTime, bool playing, bool scrubbing, bool rendering,
54 bool allowBypassedProcessing) noexcept;
55
59
63
68
71
74
77
82
84 double midiBufferOffset = 0.0;
85
87 TimeRange editTime;
88
90 bool isPlaying = false;
91
93 bool isScrubbing = false;
94
96 bool isRendering = false;
97
103};
104
105
106//==============================================================================
107//==============================================================================
108class Plugin : public Selectable,
110 public Exportable,
111 public AutomatableEditItem,
114{
115public:
117 ~Plugin() override;
118
119 void selectableAboutToBeDeleted() override;
120
121 //==============================================================================
124
127
131 virtual void initialiseFully();
132
133 virtual void flushPluginStateToValueTree() override;
134
135 //==============================================================================
137 virtual juce::String getName() const override = 0;
138 virtual juce::String getPluginType() = 0;
139
140 virtual juce::String getVendor() { return "Tracktion"; }
141 virtual juce::String getShortName (int /*suggestedLength*/) { return getName(); }
142
144 virtual juce::String getIdentifierString() { return getPluginType(); }
145
147 virtual juce::String getTooltip();
148
149 //==============================================================================
151 virtual void setEnabled (bool);
152 bool isEnabled() const noexcept { return enabled.get(); }
153
155 void setFrozen (bool shouldBeFrozen);
156 bool isFrozen() const noexcept { return frozen; }
157
160 void setProcessingEnabled (bool p) { processing = p; }
161 bool isProcessingEnabled() const noexcept { return processing; }
162
163 //==============================================================================
174 virtual void initialise (const PluginInitialisationInfo&) = 0;
175
184
185 bool isInitialising() const { return isInitialisingFlag; }
186
191 virtual void deinitialise() = 0;
192
194 virtual void reset();
195
197 virtual void trackPropertiesChanged() {}
198
199 //==============================================================================
209 virtual void applyToBuffer (const PluginRenderContext&) = 0;
210
212 virtual void prepareForNextBlock (TimePosition /*editTime*/) {}
213
214 // wrapper on applyTobuffer, called by the node
215 void applyToBufferWithAutomation (const PluginRenderContext&);
216
220 virtual bool shoulMeasureCpuUsage() const noexcept { return true; }
221
223 double getCpuUsage() const noexcept { return juce::jlimit (0.0, 1.0, timeToCpuScale * cpuUsageMs.load()); }
224
225 //==============================================================================
233 virtual int getNumOutputChannelsGivenInputs (int numInputChannels);
234
235 virtual bool producesAudioWhenNoAudioInput() { return isAutomationNeeded(); }
236 virtual bool noTail() { return true; }
237
238 virtual void getChannelNames (juce::StringArray* ins, juce::StringArray* outs);
239 virtual bool takesAudioInput() { return ! isSynth(); }
240 virtual bool takesMidiInput() { return false; }
241 virtual bool isSynth() { return false; }
242 virtual double getLatencySeconds() { return 0.0; }
243 virtual double getTailLength() const { return 0.0; }
244 virtual bool canSidechain();
245
246 juce::StringArray getInputChannelNames();
247 juce::StringArray getSidechainSourceNames (bool allowNone);
248 void setSidechainSourceByName (const juce::String& name);
249 juce::String getSidechainSourceName();
250 void guessSidechainRouting();
251
252 //==============================================================================
253 struct Wire
254 {
256
257 juce::ValueTree state;
258 juce::CachedValue<int> sourceChannelIndex, destChannelIndex;
259 };
260
261 //==============================================================================
262 int getNumWires() const;
263 Wire* getWire (int index) const;
264
265 void makeConnection (int srcChannel, int dstChannel, juce::UndoManager*);
266 void breakConnection (int srcChannel, int dstChannel);
267
268 //==============================================================================
272 virtual bool hasNameForMidiNoteNumber (int note, int midiChannel, juce::String& name);
273
277 virtual bool hasNameForMidiProgram (int programNum, int bank, juce::String& name);
278 virtual bool hasNameForMidiBank (int bank, juce::String& name);
279
280 //==============================================================================
281 virtual bool canBeAddedToClip() { return true; }
282 virtual bool canBeAddedToRack() { return true; }
283 virtual bool canBeAddedToFolderTrack() { return false; }
284 virtual bool canBeAddedToMaster() { return true; }
285 virtual bool canBeDisabled() { return true; }
286 virtual bool canBeMoved() { return true; }
287 virtual bool needsConstantBufferSize() = 0;
288
290 virtual bool isMissing() { return false; }
291
293 virtual bool isDisabled() { return false; }
294
295 bool isInRack() const;
296 juce::ReferenceCountedObjectPtr<RackType> getOwnerRackType() const;
297
298 bool isClipEffectPlugin() const;
299
300 virtual juce::AudioProcessor* getWrappedAudioProcessor() const { return {}; }
301
302 //==============================================================================
303 AutomatableParameter::Ptr getQuickControlParameter() const;
304 void setQuickControlParameter (AutomatableParameter*);
305
306 //==============================================================================
312 virtual void deleteFromParent();
313
318 void removeFromParent();
319
320 //==============================================================================
322 Track* getOwnerTrack() const;
323
325 Clip* getOwnerClip() const;
326
327 PluginList* getOwnerList() const;
328
329 Ptr findPluginThatFeedsIntoThis() const;
330 Ptr findPluginThatThisFeedsInto() const;
331
333 void changed() override;
334
335 //==============================================================================
336 juce::Array<ReferencedItem> getReferencedItems() override;
337 void reassignReferencedItem (const ReferencedItem&, ProjectItemID newID, double newStartTime) override;
338
340 virtual void sourceMediaChanged() {}
341
342 //==============================================================================
343 static bool areSelectedPluginsRackable (SelectionManager&);
344 static RackInstance* wrapSelectedPluginsInRack (SelectionManager&);
345 static void sortPlugins (Plugin::Array&);
346 static void sortPlugins (std::vector<Plugin*>&);
347
348 //==============================================================================
349 // setting a master plugin whose settings will be mirrored
350 bool setPluginToMirror (const Plugin::Ptr&); // fails if type is wrong
351 virtual void updateFromMirroredPluginIfNeeded (Plugin&) {}
352 Plugin::Ptr getMirroredPlugin() const;
353
354 //==============================================================================
355 enum class Type
356 {
357 allPlugins,
358 folderTrackPlugins,
359 effectPlugins,
360 };
361
362 //==============================================================================
363 bool baseClassNeedsInitialising() const noexcept { return initialiseCount == 0; }
364 void baseClassInitialise (const PluginInitialisationInfo&);
365 void baseClassDeinitialise();
366
367 //==============================================================================
368 void setSidechainSourceID (EditItemID newID) { sidechainSourceID = newID; }
369 EditItemID getSidechainSourceID() const { return sidechainSourceID; }
370
371 //==============================================================================
373 {
374 virtual bool allowWindowResizing() = 0;
375 virtual juce::ComponentBoundsConstrainer* getBoundsConstrainer() = 0;
376 };
377
378 virtual std::unique_ptr<EditorComponent> createEditor() { return {}; }
379
380 //==============================================================================
382 {
384
385 Plugin& plugin;
386
387 private:
388 WindowState() = delete;
390 };
391
393
394 void showWindowExplicitly();
395 void hideWindowForShutdown();
396
397 //==============================================================================
398 Engine& engine;
399 juce::ValueTree state;
400
401 juce::UndoManager* getUndoManager() const noexcept;
402
403protected:
404 //==============================================================================
405 juce::CachedValue<AtomicWrapper<bool>> enabled;
406 juce::CachedValue<bool> frozen, processing;
407 juce::CachedValue<juce::String> quickParamName;
408 juce::CachedValue<EditItemID> masterPluginID, sidechainSourceID;
409
410 double sampleRate = 44100.0;
411 int blockSizeSamples = 512;
412
413 void valueTreePropertyChanged (juce::ValueTree&, const juce::Identifier&) override;
414 void valueTreeChanged() override;
415
416 void valueTreeChildAdded (juce::ValueTree&, juce::ValueTree&) override;
417 void valueTreeChildRemoved (juce::ValueTree&, juce::ValueTree&, int) override;
418 void valueTreeParentChanged (juce::ValueTree&) override;
419
420 virtual void processingChanged();
421
422 //==============================================================================
423 AutomatableParameter* addParam (const juce::String& paramID, const juce::String& name, juce::NormalisableRange<float> valueRange);
424 AutomatableParameter* addParam (const juce::String& paramID, const juce::String& name, juce::NormalisableRange<float> valueRange,
425 std::function<juce::String(float)> valueToStringFunction,
426 std::function<float(const juce::String&)> stringToValueFunction);
427
428 //==============================================================================
429 static void getLeftRightChannelNames (juce::StringArray* ins, juce::StringArray* outs);
430 static void getLeftRightChannelNames (juce::StringArray* chans);
431
432private:
433 mutable AutomatableParameter::Ptr quickControlParameter;
434
435 std::atomic<int> initialiseCount { 0 };
436 double timeToCpuScale = 0;
437 std::atomic<double> cpuUsageMs { 0 };
438 std::atomic<bool> isClipEffect { false };
439
440 juce::ValueTree getConnectionsTree();
441 struct WireList;
442 std::unique_ptr<WireList> sidechainWireList;
443 std::atomic<bool> isInitialisingFlag { false };
444
446};
447
448}} // namespace tracktion { inline namespace engine
Base class for elements that have some kind of automatable parameters.
The Tracktion Edit class!
The Engine is the central class for all tracktion sessions.
An interface for objects within an edit that can be exported.
Base class for elements which can contain macro parameters.
void changed() override
method from Selectable, that's been overridden here to also tell the edit that it's changed.
virtual void reset()
Should reset synth voices, tails, clear delay buffers, etc.
virtual void deinitialise()=0
Called after play stops to release resources.
virtual juce::String getName() const override=0
The name of the type, e.g.
virtual bool hasNameForMidiNoteNumber(int note, int midiChannel, juce::String &name)
If it's a synth that names its notes, this can return the name it uses for this note 0-127.
virtual juce::String getTooltip()
default returns the name, others can return special stuff if needed
virtual void prepareForNextBlock(TimePosition)
Called between successive rendering blocks.
virtual void initialiseWithoutStopping(const PluginInitialisationInfo &)
Tells the plugin that the audio graph has changed but the plugin isn't being re-initialised - i....
void setFrozen(bool shouldBeFrozen)
This is a bit different to being enabled as when frozen a plugin can't be interacted with.
virtual bool shoulMeasureCpuUsage() const noexcept
Plugins can return false if they want to avoid the overhead of measuring the CPU usage.
void setProcessingEnabled(bool p)
Enable/Disable processing.
virtual bool isDisabled()
Plugins can be disabled to avoid them crashing Edits.
virtual bool isMissing()
for things like VSTs where the DLL is missing.
virtual int getNumOutputChannelsGivenInputs(int numInputChannels)
This must return the number of output channels that the plugin will produce, given a number of input ...
void removeFromParent()
Detaches the plugin from any parent it might be in.
Clip * getOwnerClip() const
Returns the clip if that's what it's in.
virtual void sourceMediaChanged()
Called when ProjectItem sources are re-assigned so you can reload from the new source.
virtual juce::String getIdentifierString()
A unique string to idenitify plugin independant of install location.
void playStartedOrStopped()
called by the system to let the plugin manage its automation stuff
virtual void setEnabled(bool)
Enable/disable the plugin.
double getCpuUsage() const noexcept
Returns the proportion of the current buffer size spent processing this plugin.
virtual void trackPropertiesChanged()
Track name or colour has changed.
virtual void initialiseFully()
Gives the plugin a chance to do extra initialisation when it's been added to an edit.
void selectableAboutToBeDeleted() override
Called just before the selectable is about to be deleted so any subclasses should still be valid at t...
virtual void applyToBuffer(const PluginRenderContext &)=0
Process the next block of data.
virtual bool hasNameForMidiProgram(int programNum, int bank, juce::String &name)
Returns the name for a midi program, if there is one.
Track * getOwnerTrack() const
Returns the track if it's a track or clip plugin.
virtual void deleteFromParent()
Attempts to delete this plugin, whether it's a master plugin, track plugin, etc.
virtual void initialise(const PluginInitialisationInfo &)=0
Gives the plugin a chance to set itself up before being played.
Base class for things that can be selected, and whose properties can appear in the properties panel.
Manages a list of items that are currently selected.
#define JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(className)
T load(T... args)
Type jlimit(Type lowerLimit, Type upperLimit, Type valueToConstrain) noexcept
Passed into Plugins when they are being initialised, to give them useful contextual information that ...
Represents a position in real-life time.
Wraps an atomic with an interface compatible with var so it can be used within CachedValues in a thre...
ID for objects of type EditElement - e.g.
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.
bool isScrubbing
True if the the audio is currently being scrubbed.
MidiMessageArray * bufferForMidiMessages
A buffer of MIDI events to process.
juce::AudioBuffer< float > * destBuffer
The target audio buffer which needs to be filled.
PluginRenderContext & operator=(const PluginRenderContext &)=delete
Deleted assignment operators.
int bufferStartSample
The index of the start point in the audio buffer from which data must be written.
double midiBufferOffset
A time offset to add to the timestamp of any events in the MIDI buffer.
bool allowBypassedProcessing
If this is true and the plugin supports it, this will call the bypassed processing method of the plug...
bool isRendering
True if the rendering is happening as part of an offline render rather than live playback.
bool isPlaying
True if the the playhead is currently playing.
PluginRenderContext(const PluginRenderContext &)=default
Creates a copy of another PluginRenderContext.
TimeRange editTime
The edit time range this context represents.
juce::AudioChannelSet destBufferChannels
A description of the type of channels in each of the channels in destBuffer.