File size: 3,148 Bytes
644b727
 
 
 
42bb859
4a72dce
644b727
42bb859
 
644b727
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42bb859
644b727
 
 
42bb859
 
644b727
42bb859
 
 
4a72dce
 
42bb859
644b727
 
42bb859
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
644b727
42bb859
 
 
 
644b727
42bb859
 
644b727
42bb859
 
 
 
 
644b727
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#pragma once

#include <juce_audio_processors/juce_audio_processors.h>
#include <juce_dsp/juce_dsp.h>
#include "Blocklist.h"
#include "Constants.h"

class McpServer;

class PluginBridgeProcessor : public juce::AudioProcessor
{
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;

    // Plugin hosting (IN-PROCESS — plugin runs inside Ableton)
    void loadPlugin(const juce::String& path);
    void unloadPlugin();
    bool isPluginLoaded() const { return hostedPlugin != nullptr; }
    juce::String getLoadedPluginName() const;
    int getLoadedPluginParamCount() const;
    juce::String getLastPluginPath() const { return pluginPath; }

    // Plugin list
    juce::Array<juce::File> getInstalledPluginFiles() const;

    // Blocklist
    bool isBlocked(const juce::String& path) const;
    Blocklist& getBlocklist() { return blocklist; }

    // Parameter access (for MCP server)
    struct ParamInfo {
        int index;
        juce::String id;
        juce::String name;
        float value;
        juce::String displayText;
    };
    std::vector<ParamInfo> searchParams(const juce::String& keyword) const;
    std::vector<std::pair<int, float>> getParams(const std::vector<int>& ids) const;
    bool setParams(const std::map<int, float>& values);

    // For editor: get hosted plugin's editor component
    juce::AudioProcessorEditor* createHostedPluginEditor();

    // Notify editor that plugin changed
    std::function<void()> onPluginLoaded;
    std::function<void()> onPluginUnloaded;
    std::function<void(const juce::String&)> onLoadFailed;

private:
    // In-process hosted plugin
    juce::AudioPluginFormatManager formatManager;
    std::unique_ptr<juce::AudioPluginInstance> hostedPlugin;
    juce::CriticalSection pluginLock;

    // MCP server
    std::unique_ptr<McpServer> mcpServer;

    // Blocklist (persisted to disk)
    Blocklist blocklist;

    // State
    juce::String pluginPath;
    double currentSampleRate = 44100.0;
    int currentBlockSize = 512;

    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginBridgeProcessor)
};