Download Source/Helper/HelperIPC.cpp from RAM2118/pluginbridge: direct link, hf CLI and curl.
- Browser
- Download file 6.63 kB
-
https://huggingface.co/RAM2118/pluginbridge/resolve/1dd0405171bf6efd5a8dfd67bc5b5d3a24dc7aee/Source/Helper/HelperIPC.cpp
- Command line
-
hf download hf://RAM2118/pluginbridge@1dd0405171bf6efd5a8dfd67bc5b5d3a24dc7aee/Source/Helper/HelperIPC.cpp
-
curl -L -o HelperIPC.cpp https://huggingface.co/RAM2118/pluginbridge/resolve/1dd0405171bf6efd5a8dfd67bc5b5d3a24dc7aee/Source/Helper/HelperIPC.cpp
6.63 kB
| using json = nlohmann::json; | |
| HelperIPC::HelperIPC(int parentPid, HelperPluginHost& host) | |
| : parentPid(parentPid), host(host) | |
| { | |
| signal(SIGPIPE, SIG_IGN); | |
| } | |
| HelperIPC::~HelperIPC() | |
| { | |
| disconnect(); | |
| } | |
| bool HelperIPC::connect() | |
| { | |
| auto socketPath = IPC::getSocketPath(parentPid); | |
| socketFd = socket(AF_UNIX, SOCK_STREAM, 0); | |
| if (socketFd < 0) return false; | |
| // Set SO_NOSIGPIPE (macOS) | |
| int nosigpipe = 1; | |
| setsockopt(socketFd, SOL_SOCKET, SO_NOSIGPIPE, &nosigpipe, sizeof(nosigpipe)); | |
| struct sockaddr_un addr; | |
| memset(&addr, 0, sizeof(addr)); | |
| addr.sun_family = AF_UNIX; | |
| strncpy(addr.sun_path, socketPath.c_str(), sizeof(addr.sun_path) - 1); | |
| int retries = 50; | |
| while (retries-- > 0) | |
| { | |
| if (::connect(socketFd, (struct sockaddr*)&addr, sizeof(addr)) == 0) | |
| { | |
| running.store(true); | |
| listenThread = std::thread([this]() { listenLoop(); }); | |
| return true; | |
| } | |
| usleep(100000); | |
| } | |
| close(socketFd); | |
| socketFd = -1; | |
| return false; | |
| } | |
| void HelperIPC::disconnect() | |
| { | |
| running.store(false); | |
| if (socketFd >= 0) | |
| { | |
| shutdown(socketFd, SHUT_RDWR); | |
| close(socketFd); | |
| socketFd = -1; | |
| } | |
| if (listenThread.joinable()) | |
| listenThread.join(); | |
| } | |
| void HelperIPC::sendReady() | |
| { | |
| json msg = {{"notify", "ready"}}; | |
| sendMessage(juce::String(msg.dump())); | |
| } | |
| void HelperIPC::sendParamChanged(int index, float value) | |
| { | |
| json msg = {{"notify", "param_changed"}, {"index", index}, {"value", value}}; | |
| sendMessage(juce::String(msg.dump())); | |
| } | |
| void HelperIPC::sendMessage(const juce::String& jsonStr) | |
| { | |
| if (socketFd < 0) return; | |
| auto data = jsonStr + "\n"; | |
| auto bytes = data.toRawUTF8(); | |
| auto len = (size_t)data.getNumBytesAsUTF8(); | |
| ::send(socketFd, bytes, len, 0); | |
| } | |
| void HelperIPC::listenLoop() | |
| { | |
| std::string buffer; | |
| char chunk[4096]; | |
| while (running.load()) | |
| { | |
| struct pollfd pfd; | |
| pfd.fd = socketFd; | |
| pfd.events = POLLIN; | |
| int ret = poll(&pfd, 1, 200); | |
| if (ret <= 0) continue; | |
| ssize_t n = recv(socketFd, chunk, sizeof(chunk) - 1, 0); | |
| if (n <= 0) | |
| { | |
| DBG("HelperIPC: Parent disconnected"); | |
| juce::JUCEApplication::getInstance()->systemRequestedQuit(); | |
| return; | |
| } | |
| chunk[n] = '\0'; | |
| buffer += chunk; | |
| size_t pos; | |
| while ((pos = buffer.find('\n')) != std::string::npos) | |
| { | |
| auto msg = buffer.substr(0, pos); | |
| buffer.erase(0, pos + 1); | |
| if (!msg.empty()) | |
| handleMessage(juce::String(msg)); | |
| } | |
| } | |
| } | |
| void HelperIPC::handleMessage(const juce::String& message) | |
| { | |
| try | |
| { | |
| auto j = json::parse(message.toStdString()); | |
| auto cmd = j.value("cmd", ""); | |
| if (cmd == "load") | |
| { | |
| auto path = j.value("path", ""); | |
| double sr = j.value("sampleRate", 44100.0); | |
| int bs = j.value("blockSize", 512); | |
| bool ok = host.loadPlugin(juce::String(path), sr, bs); | |
| json response; | |
| if (ok) | |
| response = {{"ok", true}, {"name", host.getPluginName().toStdString()}, {"params", host.getParameterCount()}}; | |
| else | |
| response = {{"ok", false}, {"error", "Failed to load plugin"}}; | |
| sendMessage(juce::String(response.dump())); | |
| } | |
| else if (cmd == "unload") | |
| { | |
| host.unloadPlugin(); | |
| sendMessage("{\"ok\":true}"); | |
| } | |
| else if (cmd == "search_param") | |
| { | |
| auto keyword = j.value("keyword", ""); | |
| auto results = host.searchParams(juce::String(keyword)); | |
| json arr = json::array(); | |
| for (auto& p : results) | |
| { | |
| arr.push_back({ | |
| {"i", p.index}, | |
| {"n", p.name.toStdString()}, | |
| {"v", std::round(p.value * 1000.0f) / 1000.0f}, | |
| {"t", p.displayText.toStdString()} | |
| }); | |
| } | |
| json response = {{"ok", true}, {"results", arr}}; | |
| sendMessage(juce::String(response.dump())); | |
| } | |
| else if (cmd == "get_params") | |
| { | |
| std::vector<int> ids; | |
| for (auto& id : j["ids"]) | |
| ids.push_back(id.get<int>()); | |
| auto results = host.getParams(ids); | |
| json values = json::object(); | |
| for (auto& [idx, val] : results) | |
| values[std::to_string(idx)] = std::round(val * 1000.0f) / 1000.0f; | |
| json response = {{"ok", true}, {"values", values}}; | |
| sendMessage(juce::String(response.dump())); | |
| } | |
| else if (cmd == "set_params") | |
| { | |
| std::map<int, float> values; | |
| for (auto& [key, val] : j["values"].items()) | |
| values[std::stoi(key)] = val.get<float>(); | |
| bool ok = host.setParams(values); | |
| sendMessage(ok ? "{\"ok\":true}" : "{\"ok\":false}"); | |
| } | |
| else if (cmd == "show_gui") | |
| { | |
| host.showGui(); | |
| sendMessage("{\"ok\":true}"); | |
| } | |
| else if (cmd == "hide_gui") | |
| { | |
| host.hideGui(); | |
| sendMessage("{\"ok\":true}"); | |
| } | |
| else if (cmd == "get_state") | |
| { | |
| auto state = host.getStateBase64(); | |
| json response = {{"ok", true}, {"state", state.toStdString()}}; | |
| sendMessage(juce::String(response.dump())); | |
| } | |
| else if (cmd == "set_state") | |
| { | |
| auto state = j.value("state", ""); | |
| bool ok = host.setStateBase64(juce::String(state)); | |
| sendMessage(ok ? "{\"ok\":true}" : "{\"ok\":false}"); | |
| } | |
| else if (cmd == "configure") | |
| { | |
| double sr = j.value("sampleRate", 44100.0); | |
| int bs = j.value("blockSize", 512); | |
| int ch = j.value("channels", 2); | |
| host.configure(sr, bs, ch); | |
| sendMessage("{\"ok\":true}"); | |
| } | |
| else if (cmd == "quit") | |
| { | |
| juce::JUCEApplication::getInstance()->systemRequestedQuit(); | |
| } | |
| } | |
| catch (const std::exception& e) | |
| { | |
| DBG("HelperIPC: Error handling message: " + juce::String(e.what())); | |
| sendMessage("{\"ok\":false,\"error\":\"parse error\"}"); | |
| } | |
| } | |