| @@ -73,20 +73,6 @@ public: | |||||
| carla_debug("CarlaEngineNativeUI::~CarlaEngineNativeUI()"); | carla_debug("CarlaEngineNativeUI::~CarlaEngineNativeUI()"); | ||||
| } | } | ||||
| void writeShowMessage() noexcept | |||||
| { | |||||
| const CarlaMutexLocker cml(getPipeLock()); | |||||
| writeMessage("show\n", 5); | |||||
| flushMessages(); | |||||
| } | |||||
| void writeFocusMessage() noexcept | |||||
| { | |||||
| const CarlaMutexLocker cml(getPipeLock()); | |||||
| writeMessage("focus\n", 6); | |||||
| flushMessages(); | |||||
| } | |||||
| protected: | protected: | ||||
| bool msgReceived(const char* const msg) noexcept override | bool msgReceived(const char* const msg) noexcept override | ||||
| { | { | ||||
| @@ -425,135 +425,6 @@ public: | |||||
| CarlaPipeServer::startPipeServer(fFilename, fPluginURI, fUiURI); | CarlaPipeServer::startPipeServer(fFilename, fPluginURI, fUiURI); | ||||
| } | } | ||||
| void writeAtomMessage(const uint32_t index, const LV2_Atom* const atom) const noexcept | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(atom != nullptr,); | |||||
| char tmpBuf[0xff+1]; | |||||
| tmpBuf[0xff] = '\0'; | |||||
| CarlaString base64atom(CarlaString::asBase64(atom, lv2_atom_total_size(atom))); | |||||
| const CarlaMutexLocker cml(getPipeLock()); | |||||
| writeMessage("atom\n", 5); | |||||
| { | |||||
| std::snprintf(tmpBuf, 0xff, "%i\n", index); | |||||
| writeMessage(tmpBuf); | |||||
| std::snprintf(tmpBuf, 0xff, "%i\n", atom->size); | |||||
| writeMessage(tmpBuf); | |||||
| writeAndFixMessage(base64atom.buffer()); | |||||
| } | |||||
| flushMessages(); | |||||
| } | |||||
| void writeUridMessage(const uint32_t urid, const char* const uri) const noexcept | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(uri != nullptr && uri[0] != '\0',); | |||||
| char tmpBuf[0xff+1]; | |||||
| tmpBuf[0xff] = '\0'; | |||||
| const CarlaMutexLocker cml(getPipeLock()); | |||||
| writeMessage("urid\n", 5); | |||||
| { | |||||
| std::snprintf(tmpBuf, 0xff, "%i\n", urid); | |||||
| writeMessage(tmpBuf); | |||||
| writeAndFixMessage(uri); | |||||
| } | |||||
| flushMessages(); | |||||
| } | |||||
| void writeControlMessage(const uint32_t index, const float value) const noexcept | |||||
| { | |||||
| char tmpBuf[0xff+1]; | |||||
| tmpBuf[0xff] = '\0'; | |||||
| const CarlaMutexLocker cml(getPipeLock()); | |||||
| const ScopedLocale csl; | |||||
| writeMessage("control\n", 8); | |||||
| { | |||||
| std::snprintf(tmpBuf, 0xff, "%i\n", index); | |||||
| writeMessage(tmpBuf); | |||||
| std::snprintf(tmpBuf, 0xff, "%f\n", value); | |||||
| writeMessage(tmpBuf); | |||||
| } | |||||
| flushMessages(); | |||||
| } | |||||
| void writeProgramMessage(const uint32_t index) const noexcept | |||||
| { | |||||
| char tmpBuf[0xff+1]; | |||||
| tmpBuf[0xff] = '\0'; | |||||
| const CarlaMutexLocker cml(getPipeLock()); | |||||
| writeMessage("program\n", 8); | |||||
| { | |||||
| std::snprintf(tmpBuf, 0xff, "%i\n", index); | |||||
| writeMessage(tmpBuf); | |||||
| } | |||||
| flushMessages(); | |||||
| } | |||||
| void writeNoteMessage(const bool onOff, const uint8_t channel, const uint8_t note, const uint8_t velocity) noexcept | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,); | |||||
| CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,); | |||||
| CARLA_SAFE_ASSERT_RETURN(velocity < MAX_MIDI_VALUE,); | |||||
| char tmpBuf[0xff+1]; | |||||
| tmpBuf[0xff] = '\0'; | |||||
| const CarlaMutexLocker cml(getPipeLock()); | |||||
| writeMessage("note\n", 5); | |||||
| { | |||||
| std::snprintf(tmpBuf, 0xff, "%s\n", bool2str(onOff)); | |||||
| writeMessage(tmpBuf); | |||||
| std::snprintf(tmpBuf, 0xff, "%i\n", channel); | |||||
| writeMessage(tmpBuf); | |||||
| std::snprintf(tmpBuf, 0xff, "%i\n", note); | |||||
| writeMessage(tmpBuf); | |||||
| std::snprintf(tmpBuf, 0xff, "%i\n", velocity); | |||||
| writeMessage(tmpBuf); | |||||
| } | |||||
| flushMessages(); | |||||
| } | |||||
| void writeShowMessage() noexcept | |||||
| { | |||||
| const CarlaMutexLocker cml(getPipeLock()); | |||||
| writeMessage("show\n", 5); | |||||
| flushMessages(); | |||||
| } | |||||
| void writeFocusMessage() noexcept | |||||
| { | |||||
| const CarlaMutexLocker cml(getPipeLock()); | |||||
| writeMessage("focus\n", 6); | |||||
| flushMessages(); | |||||
| } | |||||
| protected: | protected: | ||||
| // returns true if msg was handled | // returns true if msg was handled | ||||
| bool msgReceived(const char* const msg) noexcept override; | bool msgReceived(const char* const msg) noexcept override; | ||||
| @@ -1335,9 +1206,9 @@ public: | |||||
| fPipeServer.startPipeServer(); | fPipeServer.startPipeServer(); | ||||
| for (std::size_t i=CARLA_URI_MAP_ID_COUNT, count=fCustomURIDs.count(); i < count; ++i) | for (std::size_t i=CARLA_URI_MAP_ID_COUNT, count=fCustomURIDs.count(); i < count; ++i) | ||||
| fPipeServer.writeUridMessage(static_cast<uint32_t>(i), fCustomURIDs.getAt(i, nullptr)); | |||||
| fPipeServer.writeLv2UridMessage(static_cast<uint32_t>(i), fCustomURIDs.getAt(i, nullptr)); | |||||
| fPipeServer.writeUridMessage(CARLA_URI_MAP_ID_NULL, "Complete"); | |||||
| fPipeServer.writeLv2UridMessage(CARLA_URI_MAP_ID_NULL, "Complete"); | |||||
| fPipeServer.writeShowMessage(); | fPipeServer.writeShowMessage(); | ||||
| } | } | ||||
| @@ -1523,7 +1394,7 @@ public: | |||||
| else if (fUI.type == UI::TYPE_BRIDGE) | else if (fUI.type == UI::TYPE_BRIDGE) | ||||
| { | { | ||||
| if (fPipeServer.isPipeRunning()) | if (fPipeServer.isPipeRunning()) | ||||
| fPipeServer.writeAtomMessage(portIndex, atom); | |||||
| fPipeServer.writeLv2AtomMessage(portIndex, atom); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| @@ -4015,7 +3886,7 @@ public: | |||||
| if (fUI.type == UI::TYPE_BRIDGE) | if (fUI.type == UI::TYPE_BRIDGE) | ||||
| { | { | ||||
| if (fPipeServer.isPipeRunning()) | if (fPipeServer.isPipeRunning()) | ||||
| fPipeServer.writeNoteMessage(false, channel, note, velo); | |||||
| fPipeServer.writeMidiNoteMessage(false, channel, note, velo); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| @@ -4042,7 +3913,7 @@ public: | |||||
| if (fUI.type == UI::TYPE_BRIDGE) | if (fUI.type == UI::TYPE_BRIDGE) | ||||
| { | { | ||||
| if (fPipeServer.isPipeRunning()) | if (fPipeServer.isPipeRunning()) | ||||
| fPipeServer.writeNoteMessage(false, channel, note, 0); | |||||
| fPipeServer.writeMidiNoteMessage(false, channel, note, 0); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| @@ -4306,7 +4177,7 @@ public: | |||||
| fCustomURIDs.append(carla_strdup(uri)); | fCustomURIDs.append(carla_strdup(uri)); | ||||
| if (fUI.type == UI::TYPE_BRIDGE && fPipeServer.isPipeRunning()) | if (fUI.type == UI::TYPE_BRIDGE && fPipeServer.isPipeRunning()) | ||||
| fPipeServer.writeUridMessage(urid, uri); | |||||
| fPipeServer.writeLv2UridMessage(urid, uri); | |||||
| return urid; | return urid; | ||||
| } | } | ||||
| @@ -6139,7 +6010,7 @@ bool CarlaPipeServerLV2::msgReceived(const char* const msg) noexcept | |||||
| CARLA_SAFE_ASSERT_RETURN(chunk.size() >= sizeof(LV2_Atom), true); | CARLA_SAFE_ASSERT_RETURN(chunk.size() >= sizeof(LV2_Atom), true); | ||||
| const LV2_Atom* const atom((const LV2_Atom*)chunk.data()); | const LV2_Atom* const atom((const LV2_Atom*)chunk.data()); | ||||
| CARLA_SAFE_ASSERT_RETURN(atom->size == chunk.size(), true); | |||||
| CARLA_SAFE_ASSERT_RETURN(lv2_atom_total_size(atom) == chunk.size(), true); | |||||
| try { | try { | ||||
| kPlugin->handleUIWrite(index, lv2_atom_total_size(atom), CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT, atom); | kPlugin->handleUIWrite(index, lv2_atom_total_size(atom), CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT, atom); | ||||
| @@ -6170,7 +6041,11 @@ bool CarlaPipeServerLV2::msgReceived(const char* const msg) noexcept | |||||
| CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(uri), true); | CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(uri), true); | ||||
| if (urid != 0) | if (urid != 0) | ||||
| kPlugin->handleUridMap(urid, uri); | |||||
| { | |||||
| try { | |||||
| kPlugin->handleUridMap(urid, uri); | |||||
| } CARLA_SAFE_EXCEPTION("msgReceived urid"); | |||||
| } | |||||
| delete[] uri; | delete[] uri; | ||||
| return true; | return true; | ||||
| @@ -613,7 +613,7 @@ public: | |||||
| } | } | ||||
| if (isPipeRunning()) | if (isPipeRunning()) | ||||
| sendURID(urid, uri); | |||||
| writeLv2UridMessage(urid, uri); | |||||
| return urid; | return urid; | ||||
| } | } | ||||
| @@ -632,7 +632,7 @@ public: | |||||
| void handleProgramChanged(const int32_t /*index*/) | void handleProgramChanged(const int32_t /*index*/) | ||||
| { | { | ||||
| if (isPipeRunning()) | if (isPipeRunning()) | ||||
| sendConfigure("reloadprograms", ""); | |||||
| writeConfigureMessage("reloadprograms", ""); | |||||
| } | } | ||||
| uint32_t handleUiPortMap(const char* const symbol) | uint32_t handleUiPortMap(const char* const symbol) | ||||
| @@ -674,7 +674,7 @@ public: | |||||
| const float value(*(const float*)buffer); | const float value(*(const float*)buffer); | ||||
| if (isPipeRunning()) | if (isPipeRunning()) | ||||
| sendControl(portIndex, value); | |||||
| writeControlMessage(portIndex, value); | |||||
| } | } | ||||
| else if (format == CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM || CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT) | else if (format == CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM || CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT) | ||||
| { | { | ||||
| @@ -683,7 +683,7 @@ public: | |||||
| const LV2_Atom* const atom((const LV2_Atom*)buffer); | const LV2_Atom* const atom((const LV2_Atom*)buffer); | ||||
| if (isPipeRunning()) | if (isPipeRunning()) | ||||
| sendAtom(portIndex, atom); | |||||
| writeLv2AtomMessage(portIndex, atom); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| @@ -76,143 +76,6 @@ CarlaBridgeUI::~CarlaBridgeUI() noexcept | |||||
| } | } | ||||
| // --------------------------------------------------------------------- | // --------------------------------------------------------------------- | ||||
| // Host DSP State | |||||
| void CarlaBridgeUI::sendControl(const uint32_t index, const float value) const noexcept | |||||
| { | |||||
| char tmpBuf[0xff+1]; | |||||
| tmpBuf[0xff] = '\0'; | |||||
| const CarlaMutexLocker cml(getPipeLock()); | |||||
| const ScopedLocale csl; | |||||
| writeMessage("control\n", 8); | |||||
| { | |||||
| std::snprintf(tmpBuf, 0xff, "%i\n", index); | |||||
| writeMessage(tmpBuf); | |||||
| std::snprintf(tmpBuf, 0xff, "%f\n", value); | |||||
| writeMessage(tmpBuf); | |||||
| } | |||||
| flushMessages(); | |||||
| } | |||||
| void CarlaBridgeUI::sendProgram(const uint32_t index) const noexcept | |||||
| { | |||||
| char tmpBuf[0xff+1]; | |||||
| tmpBuf[0xff] = '\0'; | |||||
| const CarlaMutexLocker cml(getPipeLock()); | |||||
| writeMessage("program\n", 8); | |||||
| { | |||||
| std::snprintf(tmpBuf, 0xff, "%i\n", index); | |||||
| writeMessage(tmpBuf); | |||||
| } | |||||
| flushMessages(); | |||||
| } | |||||
| void CarlaBridgeUI::sendConfigure(const char* const key, const char* const value) const noexcept | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',); | |||||
| CARLA_SAFE_ASSERT_RETURN(value != nullptr,); | |||||
| const CarlaMutexLocker cml(getPipeLock()); | |||||
| writeMessage("configure\n", 10); | |||||
| { | |||||
| writeAndFixMessage(key); | |||||
| writeAndFixMessage(value); | |||||
| } | |||||
| flushMessages(); | |||||
| } | |||||
| void CarlaBridgeUI::sendNote(const bool onOff, const uint8_t channel, const uint8_t note, const uint8_t velocity) const noexcept | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,); | |||||
| CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,); | |||||
| CARLA_SAFE_ASSERT_RETURN(velocity < MAX_MIDI_VALUE,); | |||||
| char tmpBuf[0xff+1]; | |||||
| tmpBuf[0xff] = '\0'; | |||||
| const CarlaMutexLocker cml(getPipeLock()); | |||||
| writeMessage("note\n", 5); | |||||
| { | |||||
| std::snprintf(tmpBuf, 0xff, "%s\n", bool2str(onOff)); | |||||
| writeMessage(tmpBuf); | |||||
| std::snprintf(tmpBuf, 0xff, "%i\n", channel); | |||||
| writeMessage(tmpBuf); | |||||
| std::snprintf(tmpBuf, 0xff, "%i\n", note); | |||||
| writeMessage(tmpBuf); | |||||
| std::snprintf(tmpBuf, 0xff, "%i\n", velocity); | |||||
| writeMessage(tmpBuf); | |||||
| } | |||||
| flushMessages(); | |||||
| } | |||||
| #ifdef BRIDGE_LV2 | |||||
| void CarlaBridgeUI::sendAtom(const uint32_t index, const LV2_Atom* const atom) const noexcept | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(atom != nullptr,); | |||||
| char tmpBuf[0xff+1]; | |||||
| tmpBuf[0xff] = '\0'; | |||||
| CarlaString base64atom(CarlaString::asBase64(atom, lv2_atom_total_size(atom))); | |||||
| const CarlaMutexLocker cml(getPipeLock()); | |||||
| writeMessage("atom\n", 5); | |||||
| { | |||||
| std::snprintf(tmpBuf, 0xff, "%i\n", index); | |||||
| writeMessage(tmpBuf); | |||||
| std::snprintf(tmpBuf, 0xff, "%i\n", atom->size); | |||||
| writeMessage(tmpBuf); | |||||
| writeAndFixMessage(base64atom.buffer()); | |||||
| } | |||||
| flushMessages(); | |||||
| } | |||||
| void CarlaBridgeUI::sendURID(const LV2_URID urid, const char* const uri) const noexcept | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(urid != 0,); | |||||
| CARLA_SAFE_ASSERT_RETURN(uri != nullptr && uri[0] != '\0',); | |||||
| char tmpBuf[0xff+1]; | |||||
| tmpBuf[0xff] = '\0'; | |||||
| const CarlaMutexLocker cml(getPipeLock()); | |||||
| writeMessage("urid\n", 5); | |||||
| { | |||||
| std::snprintf(tmpBuf, 0xff, "%i\n", urid); | |||||
| writeMessage(tmpBuf); | |||||
| writeAndFixMessage(uri); | |||||
| } | |||||
| flushMessages(); | |||||
| } | |||||
| #endif | |||||
| bool CarlaBridgeUI::libOpen(const char* const filename) noexcept | bool CarlaBridgeUI::libOpen(const char* const filename) noexcept | ||||
| { | { | ||||
| @@ -329,7 +192,7 @@ bool CarlaBridgeUI::msgReceived(const char* const msg) noexcept | |||||
| CARLA_SAFE_ASSERT_RETURN(chunk.size() >= sizeof(LV2_Atom), true); | CARLA_SAFE_ASSERT_RETURN(chunk.size() >= sizeof(LV2_Atom), true); | ||||
| const LV2_Atom* const atom((const LV2_Atom*)chunk.data()); | const LV2_Atom* const atom((const LV2_Atom*)chunk.data()); | ||||
| CARLA_SAFE_ASSERT_RETURN(atom->size == chunk.size(), true); | |||||
| CARLA_SAFE_ASSERT_RETURN(lv2_atom_total_size(atom) == chunk.size(), true); | |||||
| dspAtomReceived(index, atom); | dspAtomReceived(index, atom); | ||||
| return true; | return true; | ||||
| @@ -55,17 +55,6 @@ protected: | |||||
| virtual ~CarlaBridgeUI() noexcept; | virtual ~CarlaBridgeUI() noexcept; | ||||
| // --------------------------------------------------------------------- | // --------------------------------------------------------------------- | ||||
| // Host DSP State | |||||
| void sendControl(const uint32_t index, const float value) const noexcept; | |||||
| void sendProgram(const uint32_t index) const noexcept; | |||||
| void sendConfigure(const char* const key, const char* const value) const noexcept; | |||||
| void sendNote(const bool onOff, const uint8_t channel, const uint8_t note, const uint8_t velocity) const noexcept; | |||||
| #ifdef BRIDGE_LV2 | |||||
| void sendAtom(const uint32_t index, const LV2_Atom* const atom) const noexcept; | |||||
| void sendURID(const LV2_URID urid, const char* const uri) const noexcept; | |||||
| #endif | |||||
| bool libOpen(const char* const filename) noexcept; | bool libOpen(const char* const filename) noexcept; | ||||
| void* libSymbol(const char* const symbol) const noexcept; | void* libSymbol(const char* const symbol) const noexcept; | ||||
| @@ -33,7 +33,7 @@ public: | |||||
| UiCrashed | UiCrashed | ||||
| }; | }; | ||||
| CarlaExternalUI() | |||||
| CarlaExternalUI() noexcept | |||||
| : fFilename(), | : fFilename(), | ||||
| fSampleRate(), | fSampleRate(), | ||||
| fUiTitle(), | fUiTitle(), | ||||
| @@ -63,12 +63,8 @@ public: | |||||
| { | { | ||||
| CarlaPipeServer::startPipeServer(fFilename, fSampleRate, fUiTitle); | CarlaPipeServer::startPipeServer(fFilename, fSampleRate, fUiTitle); | ||||
| if (! show) | |||||
| return; | |||||
| const CarlaMutexLocker cml(getPipeLock()); | |||||
| writeMessage("show\n", 5); | |||||
| flushMessages(); | |||||
| if (show) | |||||
| writeShowMessage(); | |||||
| } | } | ||||
| protected: | protected: | ||||
| @@ -17,8 +17,14 @@ | |||||
| #include "CarlaPipeUtils.hpp" | #include "CarlaPipeUtils.hpp" | ||||
| #include "CarlaString.hpp" | #include "CarlaString.hpp" | ||||
| #include "CarlaMIDI.h" | |||||
| // needed for atom-util | |||||
| #undef NULL | |||||
| #define NULL nullptr | |||||
| #include "juce_core.h" | #include "juce_core.h" | ||||
| #include "lv2/atom-util.h" | |||||
| #include <clocale> | #include <clocale> | ||||
| @@ -709,7 +715,7 @@ bool CarlaPipeCommon::writeAndFixMessage(const char* const msg) const noexcept | |||||
| { | { | ||||
| std::strcpy(fixedMsg, msg); | std::strcpy(fixedMsg, msg); | ||||
| for (size_t i=0; i < size; ++i) | |||||
| for (std::size_t i=0; i<size; ++i) | |||||
| { | { | ||||
| if (fixedMsg[i] == '\n') | if (fixedMsg[i] == '\n') | ||||
| fixedMsg[i] = '\r'; | fixedMsg[i] = '\r'; | ||||
| @@ -759,6 +765,193 @@ bool CarlaPipeCommon::flushMessages() const noexcept | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| void CarlaPipeCommon::writeShowMessage() const noexcept | |||||
| { | |||||
| const CarlaMutexLocker cml(pData->writeLock); | |||||
| _writeMsgBuffer("show\n", 5); | |||||
| flushMessages(); | |||||
| } | |||||
| void CarlaPipeCommon::writeFocusMessage() const noexcept | |||||
| { | |||||
| const CarlaMutexLocker cml(pData->writeLock); | |||||
| _writeMsgBuffer("focus\n", 6); | |||||
| flushMessages(); | |||||
| } | |||||
| void CarlaPipeCommon::writeHideMessage() const noexcept | |||||
| { | |||||
| const CarlaMutexLocker cml(pData->writeLock); | |||||
| _writeMsgBuffer("show\n", 5); | |||||
| flushMessages(); | |||||
| } | |||||
| void CarlaPipeCommon::writeErrorMessage(const char* const error) const noexcept | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(error != nullptr && error[0] != '\0',); | |||||
| const CarlaMutexLocker cml(pData->writeLock); | |||||
| _writeMsgBuffer("error\n", 6); | |||||
| writeAndFixMessage(error); | |||||
| flushMessages(); | |||||
| } | |||||
| // ------------------------------------------------------------------- | |||||
| void CarlaPipeCommon::writeControlMessage(const uint32_t index, const float value) const noexcept | |||||
| { | |||||
| char tmpBuf[0xff+1]; | |||||
| tmpBuf[0xff] = '\0'; | |||||
| const CarlaMutexLocker cml(pData->writeLock); | |||||
| const ScopedLocale csl; | |||||
| _writeMsgBuffer("control\n", 8); | |||||
| { | |||||
| std::snprintf(tmpBuf, 0xff, "%i\n", index); | |||||
| _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf)); | |||||
| std::snprintf(tmpBuf, 0xff, "%f\n", value); | |||||
| _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf)); | |||||
| } | |||||
| flushMessages(); | |||||
| } | |||||
| void CarlaPipeCommon::writeConfigureMessage(const char* const key, const char* const value) const noexcept | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',); | |||||
| CARLA_SAFE_ASSERT_RETURN(value != nullptr,); | |||||
| const CarlaMutexLocker cml(pData->writeLock); | |||||
| _writeMsgBuffer("configure\n", 10); | |||||
| { | |||||
| writeAndFixMessage(key); | |||||
| writeAndFixMessage(value); | |||||
| } | |||||
| flushMessages(); | |||||
| } | |||||
| void CarlaPipeCommon::writeProgramMessage(const uint32_t index) const noexcept | |||||
| { | |||||
| char tmpBuf[0xff+1]; | |||||
| tmpBuf[0xff] = '\0'; | |||||
| const CarlaMutexLocker cml(pData->writeLock); | |||||
| _writeMsgBuffer("program\n", 8); | |||||
| { | |||||
| std::snprintf(tmpBuf, 0xff, "%i\n", index); | |||||
| _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf)); | |||||
| } | |||||
| flushMessages(); | |||||
| } | |||||
| void CarlaPipeCommon::writeMidiProgramMessage(const uint32_t bank, const uint32_t program) const noexcept | |||||
| { | |||||
| char tmpBuf[0xff+1]; | |||||
| tmpBuf[0xff] = '\0'; | |||||
| const CarlaMutexLocker cml(pData->writeLock); | |||||
| _writeMsgBuffer("midiprogram\n", 8); | |||||
| { | |||||
| std::snprintf(tmpBuf, 0xff, "%i\n", bank); | |||||
| _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf)); | |||||
| std::snprintf(tmpBuf, 0xff, "%i\n", program); | |||||
| _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf)); | |||||
| } | |||||
| flushMessages(); | |||||
| } | |||||
| void CarlaPipeCommon::writeMidiNoteMessage(const bool onOff, const uint8_t channel, const uint8_t note, const uint8_t velocity) const noexcept | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,); | |||||
| CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,); | |||||
| CARLA_SAFE_ASSERT_RETURN(velocity < MAX_MIDI_VALUE,); | |||||
| char tmpBuf[0xff+1]; | |||||
| tmpBuf[0xff] = '\0'; | |||||
| const CarlaMutexLocker cml(pData->writeLock); | |||||
| _writeMsgBuffer("note\n", 5); | |||||
| { | |||||
| std::snprintf(tmpBuf, 0xff, "%s\n", bool2str(onOff)); | |||||
| _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf)); | |||||
| std::snprintf(tmpBuf, 0xff, "%i\n", channel); | |||||
| _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf)); | |||||
| std::snprintf(tmpBuf, 0xff, "%i\n", note); | |||||
| _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf)); | |||||
| std::snprintf(tmpBuf, 0xff, "%i\n", velocity); | |||||
| _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf)); | |||||
| } | |||||
| flushMessages(); | |||||
| } | |||||
| void CarlaPipeCommon::writeLv2AtomMessage(const uint32_t index, const LV2_Atom* const atom) const noexcept | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(atom != nullptr,); | |||||
| char tmpBuf[0xff+1]; | |||||
| tmpBuf[0xff] = '\0'; | |||||
| CarlaString base64atom(CarlaString::asBase64(atom, lv2_atom_total_size(atom))); | |||||
| const CarlaMutexLocker cml(pData->writeLock); | |||||
| _writeMsgBuffer("atom\n", 5); | |||||
| { | |||||
| std::snprintf(tmpBuf, 0xff, "%i\n", index); | |||||
| _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf)); | |||||
| std::snprintf(tmpBuf, 0xff, "%i\n", atom->size); | |||||
| _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf)); | |||||
| writeAndFixMessage(base64atom.buffer()); | |||||
| } | |||||
| flushMessages(); | |||||
| } | |||||
| void CarlaPipeCommon::writeLv2UridMessage(const uint32_t urid, const char* const uri) const noexcept | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(uri != nullptr && uri[0] != '\0',); | |||||
| char tmpBuf[0xff+1]; | |||||
| tmpBuf[0xff] = '\0'; | |||||
| const CarlaMutexLocker cml(pData->writeLock); | |||||
| _writeMsgBuffer("urid\n", 5); | |||||
| { | |||||
| std::snprintf(tmpBuf, 0xff, "%i\n", urid); | |||||
| _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf)); | |||||
| writeAndFixMessage(uri); | |||||
| } | |||||
| flushMessages(); | |||||
| } | |||||
| // ------------------------------------------------------------------- | |||||
| // internal | // internal | ||||
| const char* CarlaPipeCommon::_readline() const noexcept | const char* CarlaPipeCommon::_readline() const noexcept | ||||
| { | { | ||||
| @@ -21,6 +21,8 @@ | |||||
| #include "CarlaJuceUtils.hpp" | #include "CarlaJuceUtils.hpp" | ||||
| #include "CarlaMutex.hpp" | #include "CarlaMutex.hpp" | ||||
| #include "lv2/atom.h" | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| // CarlaPipeCommon class | // CarlaPipeCommon class | ||||
| @@ -164,6 +166,64 @@ public: | |||||
| bool flushMessages() const noexcept; | bool flushMessages() const noexcept; | ||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| // write prepared messages, no lock or flush needed (done internally) | |||||
| /*! | |||||
| * Write a single "show" message. | |||||
| */ | |||||
| void writeShowMessage() const noexcept; | |||||
| /*! | |||||
| * Write a single "focus" message. | |||||
| */ | |||||
| void writeFocusMessage() const noexcept; | |||||
| /*! | |||||
| * Write a single "hide" message. | |||||
| */ | |||||
| void writeHideMessage() const noexcept; | |||||
| /*! | |||||
| * Write an "error" message. | |||||
| */ | |||||
| void writeErrorMessage(const char* const error) const noexcept; | |||||
| /*! | |||||
| * Write a "control" message used for parameter changes. | |||||
| */ | |||||
| void writeControlMessage(const uint32_t index, const float value) const noexcept; | |||||
| /*! | |||||
| * Write a "configure" message used for state changes. | |||||
| */ | |||||
| void writeConfigureMessage(const char* const key, const char* const value) const noexcept; | |||||
| /*! | |||||
| * Write a "program" message (using index). | |||||
| */ | |||||
| void writeProgramMessage(const uint32_t index) const noexcept; | |||||
| /*! | |||||
| * Write a "midiprogram" message (using bank and program). | |||||
| */ | |||||
| void writeMidiProgramMessage(const uint32_t bank, const uint32_t program) const noexcept; | |||||
| /*! | |||||
| * Write a MIDI "note" message. | |||||
| */ | |||||
| void writeMidiNoteMessage(const bool onOff, const uint8_t channel, const uint8_t note, const uint8_t velocity) const noexcept; | |||||
| /*! | |||||
| * Write an lv2 "atom" message. | |||||
| */ | |||||
| void writeLv2AtomMessage(const uint32_t index, const LV2_Atom* const atom) const noexcept; | |||||
| /*! | |||||
| * Write an lv2 "urid" message. | |||||
| */ | |||||
| void writeLv2UridMessage(const uint32_t urid, const char* const uri) const noexcept; | |||||
| // ------------------------------------------------------------------- | |||||
| protected: | protected: | ||||
| struct PrivateData; | struct PrivateData; | ||||