#include #include #include #include #include "SharedAudioBuffer.h" #include "IPCProtocol.h" #include "Constants.h" #include "HelperPluginHost.h" #include "HelperIPC.h" class HelperApplication : public juce::JUCEApplication { public: const juce::String getApplicationName() override { return "PluginBridgeHelper"; } const juce::String getApplicationVersion() override { return PluginBridgeConstants::kVersion; } void initialise(const juce::String& commandLine) override { auto args = juce::StringArray::fromTokens(commandLine, " ", "\""); int parentPid = 0; for (int i = 0; i < args.size() - 1; ++i) { if (args[i] == "--pid") parentPid = args[i + 1].getIntValue(); } if (parentPid == 0) { DBG("HelperApplication: --pid argument required"); quit(); return; } DBG("HelperApplication: Starting for parent PID " + juce::String(parentPid)); auto portName = juce::String(IPC::getLayerPortName(parentPid)); pluginHost = std::make_unique(); pluginHost->setLayerPortName(portName); ipcServer = std::make_unique(parentPid, *pluginHost); auto shmName = IPC::getShmName(parentPid); if (!sharedAudio.open(shmName)) { DBG("HelperApplication: Failed to open shared memory: " + shmName); quit(); return; } if (!inputSem.open(IPC::getInputSemName(parentPid)) || !outputSem.open(IPC::getOutputSemName(parentPid))) { DBG("HelperApplication: Failed to open semaphores"); quit(); return; } if (!ipcServer->connect()) { DBG("HelperApplication: Failed to connect to parent IPC socket"); quit(); return; } pluginHost->setSharedAudio(&sharedAudio, &inputSem, &outputSem); pluginHost->startProcessing(); ipcServer->sendReady(); DBG("HelperApplication: Ready and running"); } void shutdown() override { if (pluginHost) pluginHost->stopProcessing(); ipcServer.reset(); pluginHost.reset(); sharedAudio.destroy(); } void systemRequestedQuit() override { quit(); } private: std::unique_ptr pluginHost; std::unique_ptr ipcServer; SharedAudioBuffer sharedAudio; SharedSemaphore inputSem; SharedSemaphore outputSem; }; START_JUCE_APPLICATION(HelperApplication)