Hi everyone,
I’m trying to create an internal plugin that can be used in tracktion engine.
I create a very simple one:
This is JPSamplerFxPlugin.h
#include <JuceHeader.h>
#include <tracktion_engine/tracktion_engine.h>
namespace tracktion {
inline namespace engine
{
//==============================================================================
class JPSamplerFxPlugin : public tracktion::engine::Plugin
{
public:
//==============================================================================
JPSamplerFxPlugin(PluginCreationInfo);
~JPSamplerFxPlugin() override;
//==============================================================================
static const char* getPluginName() { return "JP Sampler FX"; }
static const char* xmlTypeName; // XML type identifier for the plugin
//==============================================================================
// Plugin interface methods
juce::String getName() const override { return "JPSamplerFx"; }
juce::String getPluginType() override { return xmlTypeName; }
juce::String getVendor() override { return "Juicy Pads"; }
juce::String getShortName(int) override { return "JPSamplerFx"; }
juce::String getSelectableDescription() override { return "JP Sampler FX"; }
//==============================================================================
// Audio processing
void initialise(const PluginInitialisationInfo&) override;
void deinitialise() override;
void applyToBuffer(const tracktion::engine::PluginRenderContext& context) override;
//==============================================================================
// Parameter management
void initialiseFully() override;
void restorePluginStateFromValueTree(const juce::ValueTree&) override;
//==============================================================================
AutomatableParameter::Ptr getGainParam() const;
void setGainParam(float newGain);
//==============================================================================
// Plugin parameters
AutomatableParameter::Ptr gainParam;
juce::CachedValue<float> gainValue;
private:
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(JPSamplerFxPlugin)
};
}
}
Then I have JPSamplerFxPlugin.cpp
#include "JPSamplerFxPlugin.h"
namespace tracktion {
inline namespace engine
{
//==============================================================================
JPSamplerFxPlugin::JPSamplerFxPlugin(PluginCreationInfo info)
: Plugin(info)
{
auto um = getUndoManager();
gainValue.referTo(state, IDs::gain, um, 0.0f);
// Initialize the gain parameter
gainParam = addParam("gain", "Gain", { 0.0f, 2.0f },
[](float value) { return juce::String(value, 2); },
[](const juce::String& s) { return s.getFloatValue(); });
gainParam->attachToCurrentValue(gainValue);
}
JPSamplerFxPlugin::~JPSamplerFxPlugin()
{
notifyListenersOfDeletion();
gainParam->detachFromCurrentValue();
}
//==============================================================================
const char* JPSamplerFxPlugin::xmlTypeName = "JPSamplerFxPlugin";
//==============================================================================
void JPSamplerFxPlugin::initialiseFully()
{
// Ensure parameters are fully initialized
Plugin::initialiseFully();
}
//==============================================================================
void JPSamplerFxPlugin::restorePluginStateFromValueTree(const juce::ValueTree& v)
{
copyValueTree(state, v, nullptr);
}
//==============================================================================
void JPSamplerFxPlugin::initialise(const PluginInitialisationInfo&)
{
}
//==============================================================================
void JPSamplerFxPlugin::deinitialise()
{
}
//==============================================================================
void JPSamplerFxPlugin::applyToBuffer(const PluginRenderContext& context)
{
if (context.destBuffer == nullptr)
return;
// Get the current gain value
float gain = gainParam->getCurrentValue();
// Apply gain to each channel in the audio buffer
for (int channel = 0; channel < context.destBuffer->getNumChannels(); ++channel)
{
auto* buffer = context.destBuffer->getWritePointer(channel);
for (int i = 0; i < context.bufferNumSamples; ++i)
{
buffer[i] *= gain;
}
}
}
//==============================================================================
AutomatableParameter::Ptr JPSamplerFxPlugin::getGainParam() const
{
return gainParam;
}
//==============================================================================
void JPSamplerFxPlugin::setGainParam(float newGain)
{
if (gainParam != nullptr)
gainParam->setParameter(newGain, juce::NotificationType::sendNotification);
}
}
}
all this file are inside a folder called “Plugins” inside my “Source” folder.
Then in my App I try this:
In App.h:
tracktion::PluginManager pluginManager;
And in App.cpp I have this:
pluginManager.initialise();
pluginManager.createBuiltInType<tracktion::engine::JPSamplerFxPlugin>();
Then after my edit initialization I have:
juce::ValueTree pluginState(tracktion_engine::IDs::PLUGIN);
pluginState.setProperty(tracktion_engine::IDs::type, tracktion_engine::JPSamplerFxPlugin::xmlTypeName, nullptr);
auto jPSamplerFxPlugin = pluginManager.createNewPlugin(*edit, pluginState);
DBG("Plugin created? " + juce::String(jPSamplerFxPlugin != nullptr ? "true" : "false"));
if (jPSamplerFxPlugin == nullptr) {
DBG("ERROR: jPSamplerFxPlugin is NULL after creation attempt. Aborting insertion.");
return;
}
else {
DBG("Is not null");
}
if (jPSamplerFxPlugin != nullptr)
{
auto tracks = tracktion::getAudioTracks(*edit);
if (tracks.size() != 0 && tracks[0] != nullptr)
{
tracks[0]->pluginList.insertPlugin(*jPSamplerFxPlugin, 2, nullptr);
DBG("JPSamplerFxPlugin inserted into track 0");
bool foundMyPlugin = false;
for (auto* plugin : tracks[0]->pluginList)
{
if (plugin == jPSamplerFxPlugin.get())
{
foundMyPlugin = true;
DBG("CONFIRMATION: JPSamplerFxPlugin found in track's pluginList immediately after insertion.");
break;
}
}
if (!foundMyPlugin)
{
DBG("WARNING: JPSamplerFxPlugin NOT found in track's pluginList immediately after insertion.");
}
for (auto* plugin : tracks[0]->pluginList)
{
DBG("Searching plugins, found: " + plugin->getName());
if (auto* jpSamplerFx = dynamic_cast<tracktion::engine::JPSamplerFxPlugin*>(plugin))
{
jpSamplerFx->setGainParam(2.0f);
DBG("Parameter: " + juce::String(jpSamplerFx->getGainParam()->getCurrentValueAsString()));
}
}
}
else
{
DBG("No track available");
}
}
else
{
DBG("JPSamplerFxPlugin non created");
}
It compile but on this line:
tracks[0]->pluginList.insertPlugin(*jPSamplerFxPlugin, -1, nullptr);
I have this error: *** ERROR: Failed to create plugin: JPSamplerFxPlugin
*** ERROR: Failed to create plugin: JPSamplerFxPlugin
JPSamplerFxPlugin inserted into track 0
WARNING: JPSamplerFxPlugin NOT found in track's pluginList immediately after insertion.
Searching plugins, found: Sampler
Searching plugins, found: Pitch Shifter
Searching plugins, found: Volume & Pan Plugin
Searching plugins, found: Level Meter
Who know what I’m missing?
I tried also this:
auto id = edit->createNewItemID();
id.writeID(edit->state, nullptr);
juce::ValueTree pluginState(tracktion_engine::IDs::PLUGIN);
pluginState.setProperty(tracktion_engine::IDs::type, tracktion_engine::JPSamplerFxPlugin::xmlTypeName, nullptr);
auto plugin = std::make_shared<tracktion::engine::JPSamplerFxPlugin>(tracktion::engine::PluginCreationInfo(*edit, pluginState, true));
auto* track = tracktion::getAudioTracks(*edit)[0];
track->pluginList.insertPlugin(plugin.get(), 0, nullptr);
But here I receive:
*** ERROR: Failed to create plugin: JPSamplerFxPlugin
Thank you very much in advance!
Luca!
