pluginbridge / Source /Plugin /PluginBridgeProcessor.h
Sitar118
fix: restore v0.5.2 architecture + wire AudioAnalyser correctly
fdc4e41
Raw History Blame
4.8 kB
#pragma once
#include <juce_audio_processors/juce_audio_processors.h>
#include <juce_dsp/juce_dsp.h>
#include "HelperConnection.h"
#include "McpServer.h"
#include "Blocklist.h"
#include "PluginSafetyDB.h"
#include "AudioAnalyser.h"
#include "Constants.h"
#include <map>
#include <mutex>
#include <set>
class PluginBridgeProcessor : public juce::AudioProcessor,
private juce::AudioProcessorListener
{
public:
PluginBridgeProcessor();
~PluginBridgeProcessor() override;
void prepareToPlay(double sampleRate, int samplesPerBlock) override;
void releaseResources() override;
void processBlock(juce::AudioBuffer<float>&, juce::MidiBuffer&) override;
juce::AudioProcessorEditor* createEditor() override;
bool hasEditor() const override { return true; }
const juce::String getName() const override { return "PluginBridge"; }
bool acceptsMidi() const override { return true; }
bool producesMidi() const override { return true; }
double getTailLengthSeconds() const override { return 0.0; }
int getNumPrograms() override { return 1; }
int getCurrentProgram() override { return 0; }
void setCurrentProgram(int) override {}
const juce::String getProgramName(int) override { return {}; }
void changeProgramName(int, const juce::String&) override {}
void getStateInformation(juce::MemoryBlock& destData) override;
void setStateInformation(const void* data, int sizeInBytes) override;
// MCP
bool isMcpServerRunning() const;
int getMcpServerPort() const;
HelperConnection& getHelperConnection() { return helper; }
// Plugin lifecycle
void loadPlugin(const juce::String& pluginPath);
void unloadPlugin();
bool isPluginLoaded() const { return pluginLoaded; }
juce::String getLoadedPluginName() const { return pluginName; }
int getLoadedPluginParamCount() const { return pluginParamCount; }
HelperConnection::State getConnectionState() const { return helper.getState(); }
juce::String getLastPluginPath() const { return pluginPath; }
// In-process plugin instance (GUI only — null when plugin is unsafe)
juce::AudioPluginInstance* getInProcessPlugin() const { return inProcessPlugin.get(); }
// Plugin list
juce::Array<juce::File> getInstalledPluginFiles() const;
// Manufacturer name for a plugin file (reads moduleinfo.json for VST3, heuristic for AU)
// Fast — no plugin loading. Results cached in memory.
juce::String getPluginManufacturer(const juce::File& pluginFile) const;
// Blocklist
bool isBlocked(const juce::String& path) const;
Blocklist& getBlocklist() { return blocklist; }
// Safety DB
PluginSafetyDB& getSafetyDB() { return safetyDB; }
void startBackgroundScan();
void stopBackgroundScan();
// Audio analysis (for MCP get_analysis)
std::string getAnalysis() const { return analyser.getCompactAnalysis(); }
// Callbacks for editor
std::function<void()> onPluginWillLoad; // fired BEFORE old plugin/editor torn down
std::function<void()> onPluginLoaded;
std::function<void()> onPluginUnloaded;
std::function<void(const juce::String&)> onLoadFailed;
std::function<void(const juce::String&, bool)> onScanProgress; // path, safe
private:
void loadInProcessPlugin(const juce::String& path);
void unloadInProcessPlugin();
// Spawns Helper with --scan <path>, waits up to 10s, returns true if safe.
// Safe to call from any thread. Never crashes Ableton on plugin crash.
bool runPluginScan(const juce::String& path);
// AudioProcessorListener — forwards in-process param changes to Helper
void audioProcessorParameterChanged(juce::AudioProcessor*, int paramIdx, float value) override;
void audioProcessorChanged(juce::AudioProcessor*, const ChangeDetails&) override {}
HelperConnection helper;
std::unique_ptr<McpServer> mcpServer;
Blocklist blocklist;
PluginSafetyDB safetyDB;
AudioAnalyser analyser;
// In-process plugin (GUI instance — nullptr for unsafe plugins)
juce::AudioPluginFormatManager inProcessFormatManager;
std::unique_ptr<juce::AudioPluginInstance> inProcessPlugin;
std::atomic<bool> suppressParamSync{false};
bool pluginLoaded = false;
juce::String pluginName;
juce::String pluginPath;
int pluginParamCount = 0;
double currentSampleRate = 44100.0;
int currentBlockSize = 512;
// Background scanner
std::thread scanThread;
std::atomic<bool> scanRunning{false};
// Manufacturer name cache (path → manufacturer)
mutable std::map<std::string, std::string> manufacturerCache;
mutable std::mutex manufacturerCacheMutex;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginBridgeProcessor)
};