@@ -1801,16 +1801,26 @@ public: | |||
// write parameter values | |||
for (uint32_t i=0; i < pData->param.count; ++i) | |||
{ | |||
if (! fPipeServer.writeMessage("control\n", 8)) | |||
return; | |||
ParameterData& pdata(pData->param.data[i]); | |||
std::snprintf(tmpBuf, 0xff, "%i\n", pData->param.data[i].rindex); | |||
if (! fPipeServer.writeMessage(tmpBuf)) | |||
return; | |||
if (pdata.hints & PARAMETER_IS_NOT_SAVED) | |||
{ | |||
int32_t rindex = pdata.rindex; | |||
CARLA_SAFE_ASSERT_CONTINUE(rindex - static_cast<int32_t>(fRdfDescriptor->PortCount) >= 0); | |||
std::snprintf(tmpBuf, 0xff, "%.12g\n", static_cast<double>(getParameterValue(i))); | |||
if (! fPipeServer.writeMessage(tmpBuf)) | |||
return; | |||
rindex -= static_cast<int32_t>(fRdfDescriptor->PortCount); | |||
CARLA_SAFE_ASSERT_CONTINUE(rindex < static_cast<int32_t>(fRdfDescriptor->ParameterCount)); | |||
if (! fPipeServer.writeLv2ParameterMessage(fRdfDescriptor->Parameters[rindex].URI, | |||
getParameterValue(i), false)) | |||
return; | |||
} | |||
else | |||
{ | |||
if (! fPipeServer.writeControlMessage(static_cast<uint32_t>(pData->param.data[i].rindex), | |||
getParameterValue(i), false)) | |||
return; | |||
} | |||
} | |||
// ready to show | |||
@@ -4669,20 +4679,16 @@ public: | |||
if (fExt.options != nullptr && fExt.options->set != nullptr) | |||
{ | |||
LV2_Options_Option options[2]; | |||
carla_zeroStructs(options, 2); | |||
LV2_Options_Option options[4]; | |||
carla_zeroStructs(options, 4); | |||
carla_copyStruct(options[0], fLv2Options.opts[CarlaPluginLV2Options::MaxBlockLenth]); | |||
fExt.options->set(fHandle, options); | |||
carla_copyStruct(options[0], fLv2Options.opts[CarlaPluginLV2Options::NominalBlockLenth]); | |||
fExt.options->set(fHandle, options); | |||
carla_copyStruct(options[1], fLv2Options.opts[CarlaPluginLV2Options::NominalBlockLenth]); | |||
if (fLv2Options.minBufferSize != 1) | |||
{ | |||
carla_copyStruct(options[0], fLv2Options.opts[CarlaPluginLV2Options::MinBlockLenth]); | |||
fExt.options->set(fHandle, options); | |||
} | |||
carla_copyStruct(options[2], fLv2Options.opts[CarlaPluginLV2Options::MinBlockLenth]); | |||
fExt.options->set(fHandle, options); | |||
} | |||
} | |||
@@ -4703,15 +4709,8 @@ public: | |||
if (fExt.options != nullptr && fExt.options->set != nullptr) | |||
{ | |||
LV2_Options_Option options[2]; | |||
carla_zeroStructs(options, 2); | |||
LV2_Options_Option& optSampleRate(options[0]); | |||
optSampleRate.context = LV2_OPTIONS_INSTANCE; | |||
optSampleRate.subject = 0; | |||
optSampleRate.key = kUridParamSampleRate; | |||
optSampleRate.size = sizeof(float); | |||
optSampleRate.type = kUridAtomFloat; | |||
optSampleRate.value = &fLv2Options.sampleRate; | |||
carla_copyStruct(options[0], fLv2Options.opts[CarlaPluginLV2Options::SampleRate]); | |||
carla_zeroStruct(options[1]); | |||
fExt.options->set(fHandle, options); | |||
} | |||
@@ -4844,8 +4843,25 @@ public: | |||
if (fUI.type == UI::TYPE_BRIDGE) | |||
{ | |||
if (fPipeServer.isPipeRunning()) | |||
fPipeServer.writeControlMessage(static_cast<uint32_t>(pData->param.data[index].rindex), value); | |||
if (! fPipeServer.isPipeRunning()) | |||
return; | |||
ParameterData& pdata(pData->param.data[index]); | |||
if (pdata.hints & PARAMETER_IS_NOT_SAVED) | |||
{ | |||
int32_t rindex = pdata.rindex; | |||
CARLA_SAFE_ASSERT_RETURN(rindex - static_cast<int32_t>(fRdfDescriptor->PortCount) >= 0,); | |||
rindex -= static_cast<int32_t>(fRdfDescriptor->PortCount); | |||
CARLA_SAFE_ASSERT_RETURN(rindex < static_cast<int32_t>(fRdfDescriptor->ParameterCount),); | |||
fPipeServer.writeLv2ParameterMessage(fRdfDescriptor->Parameters[rindex].URI, value, true); | |||
} | |||
else | |||
{ | |||
fPipeServer.writeControlMessage(static_cast<uint32_t>(pData->param.data[index].rindex), value, true); | |||
} | |||
} | |||
else | |||
{ | |||
@@ -5926,6 +5942,49 @@ public: | |||
} | |||
} | |||
void handleUIBridgeParameter(const char* const uri, const float value) | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(uri != nullptr,); | |||
carla_debug("CarlaPluginLV2::handleUIBridgeParameter(%s, %f)", uri, static_cast<double>(value)); | |||
uint32_t parameterId = UINT32_MAX; | |||
for (uint32_t i=0; i < fRdfDescriptor->ParameterCount; ++i) | |||
{ | |||
const LV2_RDF_Parameter& rdfParam(fRdfDescriptor->Parameters[i]); | |||
if (std::strcmp(rdfParam.URI, uri) == 0) | |||
{ | |||
const int32_t rindex = static_cast<int32_t>(fRdfDescriptor->PortCount + i); | |||
switch (rdfParam.Type) | |||
{ | |||
case LV2_PARAMETER_BOOL: | |||
case LV2_PARAMETER_INT: | |||
// case LV2_PARAMETER_LONG: | |||
case LV2_PARAMETER_FLOAT: | |||
case LV2_PARAMETER_DOUBLE: | |||
for (uint32_t j=0; j < pData->param.count; ++j) | |||
{ | |||
if (pData->param.data[j].rindex == rindex) | |||
{ | |||
parameterId = j; | |||
break; | |||
} | |||
} | |||
break; | |||
} | |||
break; | |||
} | |||
} | |||
if (parameterId == UINT32_MAX) | |||
return; | |||
setParameterValue(parameterId, value, false, true, true); | |||
} | |||
// ------------------------------------------------------------------- | |||
void handleLilvSetPortValue(const char* const portSymbol, const void* const value, const uint32_t size, const uint32_t type) | |||
@@ -7748,6 +7807,21 @@ bool CarlaPipeServerLV2::msgReceived(const char* const msg) noexcept | |||
return true; | |||
} | |||
if (std::strcmp(msg, "pcontrol") == 0) | |||
{ | |||
const char* uri; | |||
float value; | |||
CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(uri, true), true); | |||
CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value), true); | |||
try { | |||
kPlugin->handleUIBridgeParameter(uri, value); | |||
} CARLA_SAFE_EXCEPTION("magReceived pcontrol"); | |||
return true; | |||
} | |||
if (std::strcmp(msg, "atom") == 0) | |||
{ | |||
uint32_t index, atomTotalSize, base64Size; | |||
@@ -177,6 +177,18 @@ bool CarlaBridgeFormat::msgReceived(const char* const msg) noexcept | |||
return true; | |||
} | |||
if (std::strcmp(msg, "parameter") == 0) | |||
{ | |||
const char* uri; | |||
float value; | |||
CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(uri, true), true); | |||
CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value), true); | |||
// dspParameterChanged(index, value); | |||
return true; | |||
} | |||
if (std::strcmp(msg, "program") == 0) | |||
{ | |||
uint32_t index; | |||
@@ -71,6 +71,8 @@ class HostWindow(QMainWindow): | |||
self.fPorts = self.fPlugin['ports'] | |||
self.fPortSymbols = {} | |||
self.fPortValues = {} | |||
self.fParamTypes = {} | |||
self.fParamValues = {} | |||
for port in self.fPorts['control']['input']: | |||
self.fPortSymbols[port['index']] = (port['symbol'], False) | |||
@@ -80,6 +82,32 @@ class HostWindow(QMainWindow): | |||
self.fPortSymbols[port['index']] = (port['symbol'], True) | |||
self.fPortValues [port['index']] = port['ranges']['default'] | |||
for parameter in self.fPlugin['parameters']: | |||
if parameter['ranges'] is None: | |||
continue | |||
if parameter['type'] == "http://lv2plug.in/ns/ext/atom#Bool": | |||
paramtype = 'b' | |||
elif parameter['type'] == "http://lv2plug.in/ns/ext/atom#Int": | |||
paramtype = 'i' | |||
elif parameter['type'] == "http://lv2plug.in/ns/ext/atom#Long": | |||
paramtype = 'l' | |||
elif parameter['type'] == "http://lv2plug.in/ns/ext/atom#Float": | |||
paramtype = 'f' | |||
elif parameter['type'] == "http://lv2plug.in/ns/ext/atom#Double": | |||
paramtype = 'g' | |||
elif parameter['type'] == "http://lv2plug.in/ns/ext/atom#String": | |||
paramtype = 's' | |||
elif parameter['type'] == "http://lv2plug.in/ns/ext/atom#Path": | |||
paramtype = 'p' | |||
elif parameter['type'] == "http://lv2plug.in/ns/ext/atom#URI": | |||
paramtype = 'u' | |||
else: | |||
continue | |||
if paramtype not in ('s','p','u') and parameter['ranges']['minimum'] == parameter['ranges']['maximum']: | |||
continue | |||
self.fParamTypes [parameter['uri']] = paramtype | |||
self.fParamValues[parameter['uri']] = parameter['ranges']['default'] | |||
# ---------------------------------------------------------------------------------------------------- | |||
# Init pipe | |||
@@ -217,7 +245,7 @@ class HostWindow(QMainWindow): | |||
self.setFixedSize(size) | |||
# set initial values | |||
self.fCurrentFrame.evaluateJavaScript("icongui.setPortValue(':bypass', 0, null)") | |||
self.fCurrentFrame.evaluateJavaScript("icongui.setPortWidgetsValue(':bypass', 0, null)") | |||
for index in self.fPortValues.keys(): | |||
symbol, isOutput = self.fPortSymbols[index] | |||
@@ -225,7 +253,14 @@ class HostWindow(QMainWindow): | |||
if isOutput: | |||
self.fCurrentFrame.evaluateJavaScript("icongui.setOutputPortValue('%s', %f)" % (symbol, value)) | |||
else: | |||
self.fCurrentFrame.evaluateJavaScript("icongui.setPortValue('%s', %f, null)" % (symbol, value)) | |||
self.fCurrentFrame.evaluateJavaScript("icongui.setPortWidgetsValue('%s', %f, null)" % (symbol, value)) | |||
for uri in self.fParamValues.keys(): | |||
ptype = self.fParamTypes[uri] | |||
value = str(self.fParamValues[uri]) | |||
print("icongui.setWritableParameterValue('%s', '%c', %s, 'from-carla')" % (uri, ptype, value)) | |||
self.fCurrentFrame.evaluateJavaScript("icongui.setWritableParameterValue('%s', '%c', %s, 'from-carla')" % ( | |||
uri, ptype, value)) | |||
# final setup | |||
self.fCanSetValues = True | |||
@@ -251,12 +286,20 @@ class HostWindow(QMainWindow): | |||
continue | |||
oldValue = self.fPortValues[index] | |||
newValue = self.fCurrentFrame.evaluateJavaScript("icongui.getPortValue('%s')" % (symbol,)) | |||
newValue = self.fCurrentFrame.evaluateJavaScript("icongui.controls['%s'].value" % (symbol,)) | |||
if oldValue != newValue: | |||
self.fPortValues[index] = newValue | |||
self.send(["control", index, newValue]) | |||
for uri in self.fParamValues.keys(): | |||
oldValue = self.fParamValues[uri] | |||
newValue = self.fCurrentFrame.evaluateJavaScript("icongui.parameters['%s'].value" % (uri,)) | |||
if oldValue != newValue: | |||
self.fParamValues[uri] = newValue | |||
self.send(["pcontrol", uri, newValue]) | |||
# -------------------------------------------------------------------------------------------------------- | |||
@pyqtSlot(bool) | |||
@@ -280,7 +323,12 @@ class HostWindow(QMainWindow): | |||
if msg == "control": | |||
index = self.readlineblock_int() | |||
value = self.readlineblock_float() | |||
self.dspParameterChanged(index, value) | |||
self.dspControlChanged(index, value) | |||
elif msg == "parameter": | |||
uri = self.readlineblock() | |||
value = self.readlineblock_float() | |||
self.dspParameterChanged(uri, value) | |||
elif msg == "program": | |||
index = self.readlineblock_int() | |||
@@ -288,7 +336,7 @@ class HostWindow(QMainWindow): | |||
elif msg == "midiprogram": | |||
bank = self.readlineblock_int() | |||
program = self.readlineblock_float() | |||
program = self.readlineblock_int() | |||
self.dspMidiProgramChanged(bank, program) | |||
elif msg == "configure": | |||
@@ -305,12 +353,14 @@ class HostWindow(QMainWindow): | |||
elif msg == "atom": | |||
index = self.readlineblock_int() | |||
size = self.readlineblock_int() | |||
atomsize = self.readlineblock_int() | |||
base64size = self.readlineblock_int() | |||
base64atom = self.readlineblock() | |||
# nothing to do yet | |||
elif msg == "urid": | |||
urid = self.readlineblock_int() | |||
size = self.readlineblock_int() | |||
uri = self.readlineblock() | |||
# nothing to do yet | |||
@@ -347,17 +397,33 @@ class HostWindow(QMainWindow): | |||
# -------------------------------------------------------------------------------------------------------- | |||
def dspParameterChanged(self, index, value): | |||
def dspControlChanged(self, index, value): | |||
self.fPortValues[index] = value | |||
if self.fCurrentFrame is not None and self.fCanSetValues: | |||
symbol, isOutput = self.fPortSymbols[index] | |||
if self.fCurrentFrame is None or not self.fCanSetValues: | |||
return | |||
if isOutput: | |||
self.fPortValues[index] = value | |||
self.fCurrentFrame.evaluateJavaScript("icongui.setOutputPortValue('%s', %f)" % (symbol, value)) | |||
else: | |||
self.fCurrentFrame.evaluateJavaScript("icongui.setPortValue('%s', %f, null)" % (symbol, value)) | |||
symbol, isOutput = self.fPortSymbols[index] | |||
if isOutput: | |||
self.fCurrentFrame.evaluateJavaScript("icongui.setOutputPortValue('%s', %f)" % (symbol, value)) | |||
else: | |||
self.fCurrentFrame.evaluateJavaScript("icongui.setPortWidgetsValue('%s', %f, null)" % (symbol, value)) | |||
def dspParameterChanged(self, uri, value): | |||
print("dspParameterChanged", uri, value) | |||
if uri not in self.fParamValues: | |||
return | |||
self.fParamValues[uri] = value | |||
if self.fCurrentFrame is None or not self.fCanSetValues: | |||
return | |||
ptype = self.fParamTypes[uri] | |||
self.fCurrentFrame.evaluateJavaScript("icongui.setWritableParameterValue('%s', '%c', %f, 'from-carla')" % ( | |||
uri, ptype, value)) | |||
def dspProgramChanged(self, index): | |||
return | |||
@@ -2,7 +2,7 @@ | |||
# -*- coding: utf-8 -*- | |||
# Carla bridge for LV2 modguis | |||
# Copyright (C) 2015-2019 Filipe Coelho <falktx@falktx.com> | |||
# Copyright (C) 2015-2020 Filipe Coelho <falktx@falktx.com> | |||
# | |||
# This program is free software; you can redistribute it and/or | |||
# modify it under the terms of the GNU General Public License as | |||
@@ -958,33 +958,38 @@ bool CarlaPipeCommon::flushMessages() const noexcept | |||
// ------------------------------------------------------------------- | |||
void CarlaPipeCommon::writeErrorMessage(const char* const error) const noexcept | |||
bool CarlaPipeCommon::writeErrorMessage(const char* const error) const noexcept | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(error != nullptr && error[0] != '\0',); | |||
CARLA_SAFE_ASSERT_RETURN(error != nullptr && error[0] != '\0', false); | |||
const CarlaMutexLocker cml(pData->writeLock); | |||
if (! _writeMsgBuffer("error\n", 6)) | |||
return; | |||
return false; | |||
if (! writeAndFixMessage(error)) | |||
return; | |||
return false; | |||
flushMessages(); | |||
return true; | |||
} | |||
void CarlaPipeCommon::writeControlMessage(const uint32_t index, const float value) const noexcept | |||
bool CarlaPipeCommon::writeControlMessage(const uint32_t index, const float value, const bool withWriteLock) const noexcept | |||
{ | |||
if (withWriteLock) | |||
{ | |||
const CarlaMutexLocker cml(pData->writeLock); | |||
return writeControlMessage(index, value, false); | |||
} | |||
char tmpBuf[0xff]; | |||
tmpBuf[0xfe] = '\0'; | |||
const CarlaMutexLocker cml(pData->writeLock); | |||
if (! _writeMsgBuffer("control\n", 8)) | |||
return; | |||
return false; | |||
std::snprintf(tmpBuf, 0xfe, "%i\n", index); | |||
if (! _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf))) | |||
return; | |||
return false; | |||
{ | |||
const CarlaScopedLocale csl; | |||
@@ -992,29 +997,31 @@ void CarlaPipeCommon::writeControlMessage(const uint32_t index, const float valu | |||
} | |||
if (! _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf))) | |||
return; | |||
return false; | |||
flushMessages(); | |||
return true; | |||
} | |||
void CarlaPipeCommon::writeConfigureMessage(const char* const key, const char* const value) const noexcept | |||
bool 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,); | |||
CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0', false); | |||
CARLA_SAFE_ASSERT_RETURN(value != nullptr, false); | |||
const CarlaMutexLocker cml(pData->writeLock); | |||
if (! _writeMsgBuffer("configure\n", 10)) | |||
return; | |||
return false; | |||
if (! writeAndFixMessage(key)) | |||
return; | |||
return false; | |||
if (! writeAndFixMessage(value)) | |||
return; | |||
return false; | |||
flushMessages(); | |||
return true; | |||
} | |||
void CarlaPipeCommon::writeProgramMessage(const uint32_t index) const noexcept | |||
bool CarlaPipeCommon::writeProgramMessage(const uint32_t index) const noexcept | |||
{ | |||
char tmpBuf[0xff]; | |||
tmpBuf[0xfe] = '\0'; | |||
@@ -1022,16 +1029,17 @@ void CarlaPipeCommon::writeProgramMessage(const uint32_t index) const noexcept | |||
const CarlaMutexLocker cml(pData->writeLock); | |||
if (! _writeMsgBuffer("program\n", 8)) | |||
return; | |||
return false; | |||
std::snprintf(tmpBuf, 0xfe, "%i\n", index); | |||
if (! _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf))) | |||
return; | |||
return false; | |||
flushMessages(); | |||
return true; | |||
} | |||
void CarlaPipeCommon::writeProgramMessage(const uint8_t channel, const uint32_t bank, const uint32_t program) const noexcept | |||
bool CarlaPipeCommon::writeProgramMessage(const uint8_t channel, const uint32_t bank, const uint32_t program) const noexcept | |||
{ | |||
char tmpBuf[0xff]; | |||
tmpBuf[0xfe] = '\0'; | |||
@@ -1039,24 +1047,25 @@ void CarlaPipeCommon::writeProgramMessage(const uint8_t channel, const uint32_t | |||
const CarlaMutexLocker cml(pData->writeLock); | |||
if (! _writeMsgBuffer("program\n", 8)) | |||
return; | |||
return false; | |||
std::snprintf(tmpBuf, 0xfe, "%i\n", channel); | |||
if (! _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf))) | |||
return; | |||
return false; | |||
std::snprintf(tmpBuf, 0xfe, "%i\n", bank); | |||
if (! _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf))) | |||
return; | |||
return false; | |||
std::snprintf(tmpBuf, 0xfe, "%i\n", program); | |||
if (! _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf))) | |||
return; | |||
return false; | |||
flushMessages(); | |||
return true; | |||
} | |||
void CarlaPipeCommon::writeMidiProgramMessage(const uint32_t bank, const uint32_t program) const noexcept | |||
bool CarlaPipeCommon::writeMidiProgramMessage(const uint32_t bank, const uint32_t program) const noexcept | |||
{ | |||
char tmpBuf[0xff]; | |||
tmpBuf[0xfe] = '\0'; | |||
@@ -1064,20 +1073,21 @@ void CarlaPipeCommon::writeMidiProgramMessage(const uint32_t bank, const uint32_ | |||
const CarlaMutexLocker cml(pData->writeLock); | |||
if (! _writeMsgBuffer("midiprogram\n", 12)) | |||
return; | |||
return false; | |||
std::snprintf(tmpBuf, 0xfe, "%i\n", bank); | |||
if (! _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf))) | |||
return; | |||
return false; | |||
std::snprintf(tmpBuf, 0xfe, "%i\n", program); | |||
if (! _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf))) | |||
return; | |||
return false; | |||
flushMessages(); | |||
return true; | |||
} | |||
void CarlaPipeCommon::writeReloadProgramsMessage(const int32_t index) const noexcept | |||
bool CarlaPipeCommon::writeReloadProgramsMessage(const int32_t index) const noexcept | |||
{ | |||
char tmpBuf[0xff]; | |||
tmpBuf[0xfe] = '\0'; | |||
@@ -1085,20 +1095,21 @@ void CarlaPipeCommon::writeReloadProgramsMessage(const int32_t index) const noex | |||
const CarlaMutexLocker cml(pData->writeLock); | |||
if (! _writeMsgBuffer("reloadprograms\n", 15)) | |||
return; | |||
return false; | |||
std::snprintf(tmpBuf, 0xfe, "%i\n", index); | |||
if (! _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf))) | |||
return; | |||
return false; | |||
flushMessages(); | |||
return true; | |||
} | |||
void CarlaPipeCommon::writeMidiNoteMessage(const bool onOff, const uint8_t channel, const uint8_t note, const uint8_t velocity) const noexcept | |||
bool 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,); | |||
CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false); | |||
CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE, false); | |||
CARLA_SAFE_ASSERT_RETURN(velocity < MAX_MIDI_VALUE, false); | |||
char tmpBuf[0xff]; | |||
tmpBuf[0xfe] = '\0'; | |||
@@ -1106,30 +1117,31 @@ void CarlaPipeCommon::writeMidiNoteMessage(const bool onOff, const uint8_t chann | |||
const CarlaMutexLocker cml(pData->writeLock); | |||
if (! _writeMsgBuffer("note\n", 5)) | |||
return; | |||
return false; | |||
std::snprintf(tmpBuf, 0xfe, "%s\n", bool2str(onOff)); | |||
if (! _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf))) | |||
return; | |||
return false; | |||
std::snprintf(tmpBuf, 0xfe, "%i\n", channel); | |||
if (! _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf))) | |||
return; | |||
return false; | |||
std::snprintf(tmpBuf, 0xfe, "%i\n", note); | |||
if (! _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf))) | |||
return; | |||
return false; | |||
std::snprintf(tmpBuf, 0xfe, "%i\n", velocity); | |||
if (! _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf))) | |||
return; | |||
return false; | |||
flushMessages(); | |||
return true; | |||
} | |||
void CarlaPipeCommon::writeLv2AtomMessage(const uint32_t index, const LV2_Atom* const atom) const noexcept | |||
bool CarlaPipeCommon::writeLv2AtomMessage(const uint32_t index, const LV2_Atom* const atom) const noexcept | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(atom != nullptr,); | |||
CARLA_SAFE_ASSERT_RETURN(atom != nullptr, false); | |||
char tmpBuf[0xff]; | |||
tmpBuf[0xfe] = '\0'; | |||
@@ -1140,30 +1152,60 @@ void CarlaPipeCommon::writeLv2AtomMessage(const uint32_t index, const LV2_Atom* | |||
const CarlaMutexLocker cml(pData->writeLock); | |||
if (! _writeMsgBuffer("atom\n", 5)) | |||
return; | |||
return false; | |||
std::snprintf(tmpBuf, 0xfe, "%i\n", index); | |||
if (! _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf))) | |||
return; | |||
return false; | |||
std::snprintf(tmpBuf, 0xfe, "%i\n", atomTotalSize); | |||
if (! _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf))) | |||
return; | |||
return false; | |||
std::snprintf(tmpBuf, 0xfe, "%lu\n", static_cast<long unsigned>(base64atom.length())); | |||
if (! _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf))) | |||
return; | |||
return false; | |||
if (! writeAndFixMessage(base64atom.buffer())) | |||
return; | |||
return false; | |||
flushMessages(); | |||
return true; | |||
} | |||
void CarlaPipeCommon::writeLv2UridMessage(const uint32_t urid, const char* const uri) const noexcept | |||
bool CarlaPipeCommon::writeLv2ParameterMessage(const char* const uri, const float value, const bool withWriteLock) const noexcept | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(urid != 0,); | |||
CARLA_SAFE_ASSERT_RETURN(uri != nullptr && uri[0] != '\0',); | |||
if (withWriteLock) | |||
{ | |||
const CarlaMutexLocker cml(pData->writeLock); | |||
return writeLv2ParameterMessage(uri, value, false); | |||
} | |||
char tmpBuf[0xff]; | |||
tmpBuf[0xfe] = '\0'; | |||
if (! _writeMsgBuffer("parameter\n", 10)) | |||
return false; | |||
if (! writeAndFixMessage(uri)) | |||
return false; | |||
{ | |||
const CarlaScopedLocale csl; | |||
std::snprintf(tmpBuf, 0xfe, "%.12g\n", static_cast<double>(value)); | |||
} | |||
if (! _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf))) | |||
return false; | |||
flushMessages(); | |||
return true; | |||
} | |||
bool CarlaPipeCommon::writeLv2UridMessage(const uint32_t urid, const char* const uri) const noexcept | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(urid != 0, false); | |||
CARLA_SAFE_ASSERT_RETURN(uri != nullptr && uri[0] != '\0', false); | |||
char tmpBuf[0xff]; | |||
tmpBuf[0xfe] = '\0'; | |||
@@ -1171,20 +1213,21 @@ void CarlaPipeCommon::writeLv2UridMessage(const uint32_t urid, const char* const | |||
const CarlaMutexLocker cml(pData->writeLock); | |||
if (! _writeMsgBuffer("urid\n", 5)) | |||
return; | |||
return false; | |||
std::snprintf(tmpBuf, 0xfe, "%i\n", urid); | |||
if (! _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf))) | |||
return; | |||
return false; | |||
std::snprintf(tmpBuf, 0xfe, "%lu\n", static_cast<long unsigned>(std::strlen(uri))); | |||
if (! _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf))) | |||
return; | |||
return false; | |||
if (! writeAndFixMessage(uri)) | |||
return; | |||
return false; | |||
flushMessages(); | |||
return true; | |||
} | |||
// ------------------------------------------------------------------- | |||
@@ -180,52 +180,57 @@ public: | |||
/*! | |||
* Write an "error" message. | |||
*/ | |||
void writeErrorMessage(const char* error) const noexcept; | |||
bool writeErrorMessage(const char* error) const noexcept; | |||
/*! | |||
* Write a "control" message used for parameter changes. | |||
* Write a "control" message used for parameter/control changes. | |||
*/ | |||
void writeControlMessage(uint32_t index, float value) const noexcept; | |||
bool writeControlMessage(uint32_t index, float value, bool withWriteLock = true) const noexcept; | |||
/*! | |||
* Write a "configure" message used for state changes. | |||
*/ | |||
void writeConfigureMessage(const char* key, const char* value) const noexcept; | |||
bool writeConfigureMessage(const char* key, const char* value) const noexcept; | |||
/*! | |||
* Write a "program" message (using index). | |||
*/ | |||
void writeProgramMessage(uint32_t index) const noexcept; | |||
bool writeProgramMessage(uint32_t index) const noexcept; | |||
/*! | |||
* Write a "program" message (using channel, bank and program). | |||
*/ | |||
void writeProgramMessage(uint8_t channel, uint32_t bank, uint32_t program) const noexcept; | |||
bool writeProgramMessage(uint8_t channel, uint32_t bank, uint32_t program) const noexcept; | |||
/*! | |||
* Write a "midiprogram" message (using bank and program). | |||
*/ | |||
void writeMidiProgramMessage(uint32_t bank, uint32_t program) const noexcept; | |||
bool writeMidiProgramMessage(uint32_t bank, uint32_t program) const noexcept; | |||
/*! | |||
* Write a "reloadprograms" message. | |||
*/ | |||
void writeReloadProgramsMessage(int32_t index) const noexcept; | |||
bool writeReloadProgramsMessage(int32_t index) const noexcept; | |||
/*! | |||
* Write a MIDI "note" message. | |||
*/ | |||
void writeMidiNoteMessage(bool onOff, uint8_t channel, uint8_t note, uint8_t velocity) const noexcept; | |||
bool writeMidiNoteMessage(bool onOff, uint8_t channel, uint8_t note, uint8_t velocity) const noexcept; | |||
/*! | |||
* Write an lv2 "atom" message. | |||
*/ | |||
void writeLv2AtomMessage(uint32_t index, const LV2_Atom* atom) const noexcept; | |||
bool writeLv2AtomMessage(uint32_t index, const LV2_Atom* atom) const noexcept; | |||
/*! | |||
* Write an lv2 "parameter" message. | |||
*/ | |||
bool writeLv2ParameterMessage(const char* uri, float value, bool withWriteLock = true) const noexcept; | |||
/*! | |||
* Write an lv2 "urid" message. | |||
*/ | |||
void writeLv2UridMessage(uint32_t urid, const char* uri) const noexcept; | |||
bool writeLv2UridMessage(uint32_t urid, const char* uri) const noexcept; | |||
// ------------------------------------------------------------------- | |||