From b723bdfdaa87a426819dfbb3caa3166ce186aadb Mon Sep 17 00:00:00 2001 From: falkTX Date: Mon, 23 Dec 2013 07:22:59 +0000 Subject: [PATCH] Misc progress --- data/carla-standalone.pc | 10 + source/Makefile.mk | 26 ++- source/discovery/Makefile | 10 +- source/discovery/carla-discovery.cpp | 12 +- source/utils/CarlaLv2Utils.hpp | 57 +++-- source/utils/CarlaRingBuffer.hpp | 2 +- source/utils/CarlaStateUtils.hpp | 314 +++++++++++++++------------ 7 files changed, 250 insertions(+), 181 deletions(-) create mode 100644 data/carla-standalone.pc diff --git a/data/carla-standalone.pc b/data/carla-standalone.pc new file mode 100644 index 000000000..a2b0247cc --- /dev/null +++ b/data/carla-standalone.pc @@ -0,0 +1,10 @@ +prefix=X-PREFIX-X +exec_prefix=${prefix} +libdir=${exec_prefix}/lib +includedir=${prefix}/include + +Name: carla-standalone +Version: 1.9.1 +Description: Carla Host Standalone +Libs: -L${libdir} +Cflags: -I${includedir}/carla -I${includedir}/carla/includes diff --git a/source/Makefile.mk b/source/Makefile.mk index d72c79085..3fe08e25e 100644 --- a/source/Makefile.mk +++ b/source/Makefile.mk @@ -85,10 +85,10 @@ ifneq ($(shell pkg-config --exists liblo && echo true),true) $(error liblo missing, cannot continue) endif -# Qt5 always required -ifneq ($(shell pkg-config --exists Qt5Core Qt5Gui Qt5Widgets && echo true),true) -$(error liblo missing, cannot continue) -endif +# Qt always required +# ifneq ($(shell pkg-config --exists QtCore QtGui QtXml && echo true),true) +# $(error Qt4 missing, cannot continue) +# endif # -------------------------------------------------------------- # Check for optional libs (required by backend or bridges) @@ -101,7 +101,8 @@ HAVE_GTK2 = $(shell pkg-config --exists gtk+-2.0 && echo true) HAVE_GTK3 = $(shell pkg-config --exists gtk+-3.0 && echo true) HAVE_OPENGL = $(shell pkg-config --exists gl && echo true) HAVE_PULSEAUDIO = $(shell pkg-config --exists libpulse-simple && echo true) -HAVE_QT4 = $(shell pkg-config --exists QtCore QtGui && echo true) +HAVE_QT4 = $(shell pkg-config --exists QtCore QtGui QtXml && echo true) +HAVE_QT5 = $(shell pkg-config --exists Qt5Core Qt5Gui Qt5Widgets Qt5Xml && echo true) else HAVE_OPENGL = true endif @@ -174,8 +175,10 @@ JUCE_GUI_BASICS_FLAGS = $(shell pkg-config --cflags x11 xinerama xext xcursor JUCE_GUI_BASICS_LIBS = $(shell pkg-config --libs x11 xinerama xext xcursor) -ldl endif LILV_LIBS = -ldl -lm -lrt -QTCORE_FLAGS = $(shell pkg-config --cflags Qt5Core) -QTCORE_LIBS = $(shell pkg-config --libs Qt5Core) +QTCORE_FLAGS = $(shell pkg-config --cflags QtCore) +QTCORE_LIBS = $(shell pkg-config --libs QtCore) +QTXML_FLAGS = $(shell pkg-config --cflags QtXml) +QTXML_LIBS = $(shell pkg-config --libs QtXml) ifeq ($(HAVE_ALSA),true) RTAUDIO_FLAGS += $(shell pkg-config --cflags alsa) -D__LINUX_ALSA__ RTAUDIO_LIBS += $(shell pkg-config --libs alsa) -lpthread @@ -198,7 +201,8 @@ JUCE_CORE_LIBS = -framework Cocoa -framework IOKit JUCE_GRAPHICS_LIBS = -framework Cocoa -framework QuartzCore JUCE_GUI_BASICS_LIBS = -framework Cocoa -framework Carbon -framework QuartzCore LILV_LIBS = -ldl -lm -QTCORE_LIBS = -framework Qt5Core +QTCORE_LIBS = -framework QtCore +QTXML_LIBS = -framework QtXml RTAUDIO_FLAGS += -D__MACOSX_CORE__ RTAUDIO_LIBS += -lpthread RTMIDI_FLAGS += -D__MACOSX_CORE__ @@ -213,8 +217,10 @@ JUCE_EVENTS_LIBS = -lole32 JUCE_GRAPHICS_LIBS = -lgdi32 JUCE_GUI_BASICS_LIBS = -lgdi32 -limm32 -lcomdlg32 -lole32 LILV_LIBS = -lm -QTCORE_FLAGS = $(shell pkg-config --cflags Qt5Core) -QTCORE_LIBS = $(shell pkg-config --libs Qt5Core) +QTCORE_FLAGS = $(shell pkg-config --cflags QtCore) +QTCORE_LIBS = $(shell pkg-config --libs QtCore) +QTXML_FLAGS = $(shell pkg-config --cflags QtXml) +QTXML_LIBS = $(shell pkg-config --libs QtXml) RTAUDIO_FLAGS += -D__WINDOWS_ASIO__ -D__WINDOWS_DS__ RTAUDIO_LIBS += -lpthread RTMIDI_FLAGS += -D__WINDOWS_MM__ diff --git a/source/discovery/Makefile b/source/discovery/Makefile index 7fef62a7d..1acceeb73 100644 --- a/source/discovery/Makefile +++ b/source/discovery/Makefile @@ -17,19 +17,19 @@ LINK_FLAGS += $(QTCORE_LIBS) BUILD_CXX_FLAGS += -DWANT_NATIVE ifeq ($(CARLA_PLUGIN_SUPPORT),true) -BUILD_CXX_FLAGS += -DWANT_LADSPA -DWANT_VST +BUILD_CXX_FLAGS += -DWANT_LADSPA -DWANT_LV2 -DWANT_VST ifeq ($(CARLA_VESTIGE_HEADER),true) BUILD_CXX_FLAGS += -DVESTIGE_HEADER endif endif -# -DWANT_DSSI -DWANT_LV2 +# -DWANT_DSSI # -------------------------------------------------------------- ifeq ($(HAVE_CSOUND),true) -NATIVE_FLAGS += $(shell pkg-config --cflags --libs sndfile) -lcsound64 -DWANT_CSOUND -NATIVE_FLAGS += $(JUCE_CORE_FLAGS) $(JUCE_CORE_LIBS) +# NATIVE_FLAGS += $(shell pkg-config --cflags --libs sndfile) -lcsound64 -DWANT_CSOUND +# NATIVE_FLAGS += $(JUCE_CORE_FLAGS) $(JUCE_CORE_LIBS) endif ifeq ($(HAVE_FLUIDSYNTH),true) @@ -52,7 +52,7 @@ LINK_FLAGS += $(LILV_LIBS) endif ifeq ($(HAVE_CSOUND),true) -LIBS = ../modules/juce_core.a +# LIBS = ../modules/juce_core.a endif POSIX_BUILD_FLAGS = $(BUILD_CXX_FLAGS) diff --git a/source/discovery/carla-discovery.cpp b/source/discovery/carla-discovery.cpp index 95e32933f..c88a1df4f 100644 --- a/source/discovery/carla-discovery.cpp +++ b/source/discovery/carla-discovery.cpp @@ -946,30 +946,30 @@ void do_lv2_check(const char* const bundle, const bool init) const Lilv::Plugins lilvPlugins(lv2World.get_all_plugins()); // Get all plugin URIs in this bundle - juce::StringArray URIs; + QStringList URIs; LILV_FOREACH(plugins, i, lilvPlugins) { Lilv::Plugin lilvPlugin(lilv_plugins_get(lilvPlugins, i)); if (const char* const uri = lilvPlugin.get_uri().as_string()) - URIs.add(juce::String(uri)); + URIs.append(QString(uri)); } - if (URIs.size() == 0) + if (URIs.count() == 0) { DISCOVERY_OUT("warning", "LV2 Bundle doesn't provide any plugins"); return; } // Get & check every plugin-instance - for (juce::String* it = URIs.begin(); it != URIs.end(); ++it) + for (int i=0, count=URIs.count(); i < count; ++i) { - const LV2_RDF_Descriptor* const rdfDescriptor(lv2_rdf_new(it->toRawUTF8(), false)); + const LV2_RDF_Descriptor* const rdfDescriptor(lv2_rdf_new(URIs.at(i).toUtf8().constData(), false)); if (rdfDescriptor == nullptr || rdfDescriptor->URI == nullptr) { - DISCOVERY_OUT("error", "Failed to find LV2 plugin '" << it->toRawUTF8() << "'"); + DISCOVERY_OUT("error", "Failed to find LV2 plugin '" << URIs.at(i).toUtf8().constData() << "'"); continue; } diff --git a/source/utils/CarlaLv2Utils.hpp b/source/utils/CarlaLv2Utils.hpp index f2043e589..84650364f 100644 --- a/source/utils/CarlaLv2Utils.hpp +++ b/source/utils/CarlaLv2Utils.hpp @@ -18,7 +18,7 @@ #ifndef CARLA_LV2_UTILS_HPP_INCLUDED #define CARLA_LV2_UTILS_HPP_INCLUDED -#include "CarlaJuceUtils.hpp" +#include "CarlaUtils.hpp" #include "lv2/lv2.h" #include "lv2/atom.h" @@ -61,9 +61,8 @@ #include "lilv/lilvmm.hpp" #include "sratom/sratom.h" -#ifdef USE_JUCE -#include "juce_core.h" -#endif +#include +#include // ----------------------------------------------------------------------- // Define namespaces and missing prefixes @@ -79,9 +78,6 @@ #define LV2_MIDI_LL__MidiPort "http://ll-plugins.nongnu.org/lv2/ext/MidiPort" -#define LV2_OSC__OscEvent "http://kxstudio.sf.net/ns/lv2ext/osc#OscEvent" - -#define LV2_UI__NtkUI LV2_UI_PREFIX "NtkUI" #define LV2_UI__Qt5UI LV2_UI_PREFIX "Qt5UI" #define LV2_UI__idle LV2_UI_PREFIX "idle" #define LV2_UI__makeResident LV2_UI_PREFIX "makeResident" @@ -91,7 +87,7 @@ struct LV2_Atom_MidiEvent { LV2_Atom_Event event; - uint8_t data[8]; + uint8_t data[4]; }; // ----------------------------------------------------------------------- @@ -183,7 +179,6 @@ public: Lilv::Node ui_gtk3; Lilv::Node ui_qt4; Lilv::Node ui_qt5; - Lilv::Node ui_ntk; Lilv::Node ui_cocoa; Lilv::Node ui_windows; Lilv::Node ui_x11; @@ -205,7 +200,6 @@ public: // Port Data Types Lilv::Node midi_event; - Lilv::Node osc_event; Lilv::Node patch_message; Lilv::Node time_position; @@ -301,7 +295,6 @@ public: ui_gtk3 (new_uri(LV2_UI__Gtk3UI)), ui_qt4 (new_uri(LV2_UI__Qt4UI)), ui_qt5 (new_uri(LV2_UI__Qt5UI)), - ui_ntk (new_uri(LV2_UI__NtkUI)), ui_cocoa (new_uri(LV2_UI__CocoaUI)), ui_windows (new_uri(LV2_UI__WindowsUI)), ui_x11 (new_uri(LV2_UI__X11UI)), @@ -321,7 +314,6 @@ public: value_maximum (new_uri(LV2_CORE__maximum)), midi_event (new_uri(LV2_MIDI__MidiEvent)), - osc_event (new_uri(LV2_OSC__OscEvent)), patch_message (new_uri(LV2_PATCH__Message)), time_position (new_uri(LV2_TIME__Position)), @@ -552,7 +544,7 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool fillPresets) if (replaceNode.is_uri()) { -#ifdef USE_JUCE +#if 0//def HAVE_JUCE const juce::String replaceURI(replaceNode.as_uri()); if (replaceURI.startsWith("urn:")) @@ -560,6 +552,19 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool fillPresets) if (int uniqueId = replaceURI.getTrailingIntValue()) rdfDescriptor->UniqueID = (unsigned long)uniqueId; } +#else + const QString replaceURI(replaceNode.as_uri()); + + if (replaceURI.startsWith("urn:")) + { + const QString replaceId(replaceURI.split(":").last()); + + bool ok; + const ulong uniqueId(replaceId.toULong(&ok)); + + if (ok && uniqueId != 0) + rdfDescriptor->UniqueID = uniqueId; + } #endif } } @@ -1007,7 +1012,6 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool fillPresets) } } -#ifdef USE_JUCE // ------------------------------------------------------------------- // Set Plugin Presets @@ -1018,23 +1022,42 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool fillPresets) if (presetNodes.size() > 0) { // create a list of preset URIs (for checking appliesTo, sorting and unique-ness) +#if 0//def HAVE_JUCE juce::StringArray presetListURIs; +#else + QStringList presetListURIs; +#endif LILV_FOREACH(nodes, j, presetNodes) { Lilv::Node presetNode(presetNodes.get(j)); // FIXME - check appliesTo? +#if 0//def HAVE_JUCE juce::String presetURI(presetNode.as_uri()); if (presetURI.trim().isNotEmpty()) presetListURIs.addIfNotAlreadyThere(presetURI); +#else + QString presetURI(presetNode.as_uri()); + + if (! (presetURI.trimmed().isEmpty() || presetListURIs.contains(presetURI))) + presetListURIs.append(presetURI); +#endif } +#if 0//def HAVE_JUCE presetListURIs.sort(false); +#else + presetListURIs.sort(); +#endif // create presets with unique URIs +#if 0//def HAVE_JUCE rdfDescriptor->PresetCount = static_cast(presetListURIs.size()); +#else + rdfDescriptor->PresetCount = static_cast(presetListURIs.count()); +#endif rdfDescriptor->Presets = new LV2_RDF_Preset[rdfDescriptor->PresetCount]; // set preset data @@ -1047,8 +1070,11 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool fillPresets) if (const char* const presetURI = presetNode.as_uri()) { +#if 0//def HAVE_JUCE const int index(presetListURIs.indexOf(juce::String(presetURI))); - +#else + const int index(presetListURIs.indexOf(QString(presetURI))); +#endif CARLA_SAFE_ASSERT_CONTINUE(index >= 0); LV2_RDF_Preset* const rdfPreset(&rdfDescriptor->Presets[index]); @@ -1070,7 +1096,6 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool fillPresets) } } } -#endif // ------------------------------------------------------------------- // Set Plugin Features diff --git a/source/utils/CarlaRingBuffer.hpp b/source/utils/CarlaRingBuffer.hpp index f1dc3beb9..07e4e40a2 100644 --- a/source/utils/CarlaRingBuffer.hpp +++ b/source/utils/CarlaRingBuffer.hpp @@ -99,7 +99,7 @@ public: char readChar() { - char c = 0; + char c = '\0'; tryRead(&c, sizeof(char)); return c; } diff --git a/source/utils/CarlaStateUtils.hpp b/source/utils/CarlaStateUtils.hpp index 191ee5b59..86c4b53f8 100644 --- a/source/utils/CarlaStateUtils.hpp +++ b/source/utils/CarlaStateUtils.hpp @@ -22,9 +22,7 @@ #include "CarlaMIDI.h" #include "List.hpp" -#ifdef USE_JUCE -# include "juce_core.h" -#endif +#include CARLA_BACKEND_START_NAMESPACE @@ -213,13 +211,12 @@ struct SaveState { CARLA_DECLARE_NON_COPY_STRUCT(SaveState) }; -#ifdef USE_JUCE // ----------------------------------------------------------------------- static inline -juce::String xmlSafeString(const juce::String& string, const bool toXml) +QString xmlSafeString(const QString& string, const bool toXml) { - juce::String newString(string); + QString newString(string); if (toXml) return newString.replace("&","&").replace("<","<").replace(">",">").replace("'","'").replace("\"","""); @@ -228,97 +225,124 @@ juce::String xmlSafeString(const juce::String& string, const bool toXml) } static inline -const char* xmlSafeStringCharDup(const juce::String& string, const bool toXml) +const char* xmlSafeStringCharDup(const QString& string, const bool toXml) { - return carla_strdup(xmlSafeString(string, toXml).toRawUTF8()); + return carla_strdup(xmlSafeString(string, toXml).toUtf8().constData()); } // ----------------------------------------------------------------------- static inline -void fillSaveStateFromXmlElement(SaveState& saveState, const juce::XmlElement* const xmlElement) +void fillSaveStateFromXmlNode(SaveState& saveState, const QDomNode& xmlNode) { - using namespace juce; + if (xmlNode.isNull()) + return saveState; - for (XmlElement* elem = xmlElement->getFirstChildElement(); elem != nullptr; elem = elem->getNextElement()) + for (QDomNode node = xmlNode.firstChild(); ! node.isNull(); node = node.nextSibling()) { + QString tagName(node.toElement().tagName()); + // --------------------------------------------------------------- // Info - if (elem->getTagName().equalsIgnoreCase("info")) + if (tagName.compare("info", Qt::CaseInsensitive) == 0) { - for (XmlElement* xmlInfo = elem->getFirstChildElement(); xmlInfo != nullptr; xmlInfo = xmlInfo->getNextElement()) + for (QDomNode xmlInfo = node.toElement().firstChild(); ! xmlInfo.isNull(); xmlInfo = xmlInfo.nextSibling()) { - const String& tag(xmlInfo->getTagName()); - const String text(xmlInfo->getAllSubText().trim()); + const QString tag(xmlInfo.toElement().tagName()); + const QString text(xmlInfo.toElement().text().trimmed()); - if (tag.equalsIgnoreCase("type")) + if (tag.compare("type", Qt::CaseInsensitive) == 0) + { saveState.type = xmlSafeStringCharDup(text, false); - else if (tag.equalsIgnoreCase("name")) + } + else if (tag.compare("name", Qt::CaseInsensitive) == 0) + { saveState.name = xmlSafeStringCharDup(text, false); - else if (tag.equalsIgnoreCase("label") || tag.equalsIgnoreCase("uri")) + } + else if (tag.compare("label", Qt::CaseInsensitive) == 0 || tag.compare("uri", Qt::CaseInsensitive) == 0) + { saveState.label = xmlSafeStringCharDup(text, false); - else if (tag.equalsIgnoreCase("binary") || tag.equalsIgnoreCase("filename")) + } + else if (tag.compare("binary", Qt::CaseInsensitive) == 0 || tag.compare("filename", Qt::CaseInsensitive) == 0) + { saveState.binary = xmlSafeStringCharDup(text, false); - else if (tag.equalsIgnoreCase("uniqueid")) - saveState.uniqueID = text.getLargeIntValue(); + } + else if (tag.compare("uniqueid", Qt::CaseInsensitive) == 0) + { + bool ok; + const long uniqueID(text.toLong(&ok)); + if (ok) saveState.uniqueID = uniqueID; + } } } // --------------------------------------------------------------- // Data - else if (elem->getTagName().equalsIgnoreCase("data")) + else if (tagName.compare("data", Qt::CaseInsensitive) == 0) { - for (XmlElement* xmlData = elem->getFirstChildElement(); xmlData != nullptr; xmlData = xmlData->getNextElement()) + for (QDomNode xmlData = node.toElement().firstChild(); ! xmlData.isNull(); xmlData = xmlData.nextSibling()) { - const String& tag(xmlData->getTagName()); - const String text(xmlData->getAllSubText().trim()); + const QString tag(xmlData.toElement().tagName()); + const QString text(xmlData.toElement().text().trimmed()); // ------------------------------------------------------- // Internal Data - if (tag.equalsIgnoreCase("active")) + if (tag.compare("active", Qt::CaseInsensitive) == 0) { - saveState.active = (text.equalsIgnoreCase("yes")); + saveState.active = (text.compare("yes", Qt::CaseInsensitive) == 0 || text.compare("true", Qt::CaseInsensitive) == 0); } - else if (tag.equalsIgnoreCase("drywet")) + else if (tag.compare("drywet", Qt::CaseInsensitive) == 0) { - saveState.dryWet = carla_fixValue(0.0f, 1.0f, text.getFloatValue()); + bool ok; + const float value(text.toFloat(&ok)); + if (ok) saveState.dryWet = carla_fixValue(0.0f, 1.0f, value); } - else if (tag.equalsIgnoreCase("volume")) + else if (tag.compare("volume", Qt::CaseInsensitive) == 0) { - saveState.volume = carla_fixValue(0.0f, 1.27f, text.getFloatValue()); + bool ok; + const float value(text.toFloat(&ok)); + if (ok) saveState.volume = carla_fixValue(0.0f, 1.27f, value); } - else if (tag.equalsIgnoreCase("balanceleft") || tag.equalsIgnoreCase("balance-left")) + else if (tag.compare("balanceleft", Qt::CaseInsensitive) == 0 || tag.compare("balance-left", Qt::CaseInsensitive) == 0) { - saveState.balanceLeft = carla_fixValue(-1.0f, 1.0f, text.getFloatValue()); + bool ok; + const float value(text.toFloat(&ok)); + if (ok) saveState.balanceLeft = carla_fixValue(-1.0f, 1.0f, value); } - else if (tag.equalsIgnoreCase("balanceright") || tag.equalsIgnoreCase("balance-right")) + else if (tag.compare("balanceright", Qt::CaseInsensitive) == 0 || tag.compare("balance-right", Qt::CaseInsensitive) == 0) { - saveState.balanceRight = carla_fixValue(-1.0f, 1.0f, text.getFloatValue()); + bool ok; + const float value(text.toFloat(&ok)); + if (ok) saveState.balanceRight = carla_fixValue(-1.0f, 1.0f, value); } - else if (tag.equalsIgnoreCase("panning")) + else if (tag.compare("panning", Qt::CaseInsensitive) == 0) { - saveState.panning = carla_fixValue(-1.0f, 1.0f, text.getFloatValue()); + bool ok; + const float value(text.toFloat(&ok)); + if (ok) saveState.panning = carla_fixValue(-1.0f, 1.0f, value); } - else if (tag.equalsIgnoreCase("controlchannel") || tag.equalsIgnoreCase("control-channel")) + else if (tag.compare("controlchannel", Qt::CaseInsensitive) == 0 || tag.compare("control-channel", Qt::CaseInsensitive) == 0) { - const int value(text.getIntValue()); - if (value >= 1 && value <= MAX_MIDI_CHANNELS) + bool ok; + const short value(text.toShort(&ok)); + if (ok && value >= 1 && value < MAX_MIDI_CHANNELS) saveState.ctrlChannel = static_cast(value-1); } // ------------------------------------------------------- // Program (current) - else if (tag.equalsIgnoreCase("currentprogramindex") || tag.equalsIgnoreCase("current-program-index")) + else if (tag.compare("currentprogramindex", Qt::CaseInsensitive) == 0 || tag.compare("current-program-index", Qt::CaseInsensitive) == 0) { - const int value(text.getIntValue()); - if (value >= 1) + bool ok; + const int value(text.toInt(&ok)); + if (ok && value >= 1) saveState.currentProgramIndex = value-1; } - else if (tag.equalsIgnoreCase("currentprogramname") || tag.equalsIgnoreCase("current-program-name")) + else if (tag.compare("currentprogramname", Qt::CaseInsensitive) == 0 || tag.compare("current-program-name", Qt::CaseInsensitive) == 0) { saveState.currentProgramName = xmlSafeStringCharDup(text, false); } @@ -326,59 +350,65 @@ void fillSaveStateFromXmlElement(SaveState& saveState, const juce::XmlElement* c // ------------------------------------------------------- // Midi Program (current) - else if (tag.equalsIgnoreCase("currentmidibank") || tag.equalsIgnoreCase("current-midi-bank")) + else if (tag.compare("currentmidibank", Qt::CaseInsensitive) == 0 || tag.compare("current-midi-bank", Qt::CaseInsensitive) == 0) { - const int value(text.getIntValue()); - if (value >= 1) + bool ok; + const int value(text.toInt(&ok)); + if (ok && value >= 1) saveState.currentMidiBank = value-1; } - else if (tag.equalsIgnoreCase("currentmidiprogram") || tag.equalsIgnoreCase("current-midi-program")) + else if (tag.compare("currentmidiprogram", Qt::CaseInsensitive) == 0 || tag.compare("current-midi-program", Qt::CaseInsensitive) == 0) { - const int value(text.getIntValue()); - if (value >= 1) + bool ok; + const int value(text.toInt(&ok)); + if (ok && value >= 1) saveState.currentMidiProgram = value-1; } // ------------------------------------------------------- // Parameters - else if (tag.equalsIgnoreCase("parameter")) + else if (tag.compare("parameter", Qt::CaseInsensitive) == 0) { StateParameter* const stateParameter(new StateParameter()); - for (XmlElement* xmlSubData = xmlData->getFirstChildElement(); xmlSubData != nullptr; xmlSubData = xmlSubData->getNextElement()) + for (QDomNode xmlSubData = xmlData.toElement().firstChild(); ! xmlSubData.isNull(); xmlSubData = xmlSubData.nextSibling()) { - const String& pTag(xmlSubData->getTagName()); - const String pText(xmlSubData->getAllSubText().trim()); + const QString pTag(xmlSubData.toElement().tagName()); + const QString pText(xmlSubData.toElement().text().trimmed()); - if (pTag.equalsIgnoreCase("index")) + if (pTag.compare("index", Qt::CaseInsensitive) == 0) { - const int index(pText.getIntValue()); - if (index >= 0) - stateParameter->index = static_cast(index); + bool ok; + const uint index(pText.toUInt(&ok)); + if (ok) stateParameter->index = index; } - else if (pTag.equalsIgnoreCase("name")) + else if (pTag.compare("name", Qt::CaseInsensitive) == 0) { stateParameter->name = xmlSafeStringCharDup(pText, false); } - else if (pTag.equalsIgnoreCase("symbol")) + else if (pTag.compare("symbol", Qt::CaseInsensitive) == 0) { stateParameter->symbol = xmlSafeStringCharDup(pText, false); } - else if (pTag.equalsIgnoreCase("value")) + else if (pTag.compare("value", Qt::CaseInsensitive) == 0) { - stateParameter->value = pText.getFloatValue(); + bool ok; + const float value(pText.toFloat(&ok)); + if (ok) stateParameter->value = value; } - else if (pTag.equalsIgnoreCase("midichannel") || pTag.equalsIgnoreCase("midi-channel")) + else if (pTag.compare("midichannel", Qt::CaseInsensitive) == 0 || pTag.compare("midi-channel", Qt::CaseInsensitive) == 0) { - const int channel(pText.getIntValue()); - if (channel >= 1 && channel <= MAX_MIDI_CHANNELS) + bool ok; + const ushort channel(pText.toUShort(&ok)); + if (ok && channel >= 1 && channel < MAX_MIDI_CHANNELS) stateParameter->midiChannel = static_cast(channel-1); } - else if (pTag.equalsIgnoreCase("midicc") || pTag.equalsIgnoreCase("midi-cc")) + else if (pTag.compare("midicc", Qt::CaseInsensitive) == 0 || pTag.compare("midi-cc", Qt::CaseInsensitive) == 0) { - const int cc(pText.getIntValue()); - if (cc >= 1 && cc < 0x5F) + bool ok; + const int cc(pText.toInt(&ok)); + if (ok && cc >= 1 && cc < 0x5F) stateParameter->midiCC = static_cast(cc); } } @@ -389,20 +419,20 @@ void fillSaveStateFromXmlElement(SaveState& saveState, const juce::XmlElement* c // ------------------------------------------------------- // Custom Data - else if (tag.equalsIgnoreCase("customdata") || tag.equalsIgnoreCase("custom-data")) + else if (tag.compare("customdata", Qt::CaseInsensitive) == 0 || tag.compare("custom-data", Qt::CaseInsensitive) == 0) { StateCustomData* const stateCustomData(new StateCustomData()); - for (XmlElement* xmlSubData = xmlData->getFirstChildElement(); xmlSubData != nullptr; xmlSubData = xmlSubData->getNextElement()) + for (QDomNode xmlSubData = xmlData.toElement().firstChild(); ! xmlSubData.isNull(); xmlSubData = xmlSubData.nextSibling()) { - const String& cTag(xmlSubData->getTagName()); - const String cText(xmlSubData->getAllSubText().trim()); + const QString cTag(xmlSubData.toElement().tagName()); + const QString cText(xmlSubData.toElement().text().trimmed()); - if (cTag.equalsIgnoreCase("type")) + if (cTag.compare("type", Qt::CaseInsensitive) == 0) stateCustomData->type = xmlSafeStringCharDup(cText, false); - else if (cTag.equalsIgnoreCase("key")) + else if (cTag.compare("key", Qt::CaseInsensitive) == 0) stateCustomData->key = xmlSafeStringCharDup(cText, false); - else if (cTag.equalsIgnoreCase("value")) + else if (cTag.compare("value", Qt::CaseInsensitive) == 0) stateCustomData->value = xmlSafeStringCharDup(cText, false); } @@ -412,7 +442,7 @@ void fillSaveStateFromXmlElement(SaveState& saveState, const juce::XmlElement* c // ------------------------------------------------------- // Chunk - else if (tag.equalsIgnoreCase("chunk")) + else if (tag.compare("chunk", Qt::CaseInsensitive) == 0) { saveState.chunk = xmlSafeStringCharDup(text, false); } @@ -424,164 +454,162 @@ void fillSaveStateFromXmlElement(SaveState& saveState, const juce::XmlElement* c // ----------------------------------------------------------------------- static inline -void fillXmlStringFromSaveState(juce::String& content, const SaveState& saveState) +void fillXmlStringFromSaveState(QString& content, const SaveState& saveState) { - using namespace juce; - { - String info(" \n"); + QString info(" \n"); - info << " " << saveState.type << "\n"; - info << " " << xmlSafeString(saveState.name, true) << "\n"; + info += QString(" %1\n").arg(saveState.type); + info += QString(" %1\n").arg(xmlSafeString(saveState.name, true)); switch (getPluginTypeFromString(saveState.type)) { case PLUGIN_NONE: break; case PLUGIN_INTERNAL: - info << " \n"; + info += QString(" \n").arg(xmlSafeString(saveState.label, true)); break; case PLUGIN_LADSPA: - info << " " << xmlSafeString(saveState.binary, true) << "\n"; - info << " \n"; - info << " " << saveState.uniqueID << "\n"; + info += QString(" %1\n").arg(xmlSafeString(saveState.binary, true)); + info += QString(" \n").arg(xmlSafeString(saveState.label, true)); + info += QString(" %1\n").arg(saveState.uniqueID); break; case PLUGIN_DSSI: - info << " " << xmlSafeString(saveState.binary, true) << "\n"; - info << " \n"; + info += QString(" %1\n").arg(xmlSafeString(saveState.binary, true)); + info += QString(" \n").arg(xmlSafeString(saveState.label, true)); break; case PLUGIN_LV2: - info << " " << xmlSafeString(saveState.label, true) << "\n"; + info += QString(" %1\n").arg(xmlSafeString(saveState.label, true)); break; case PLUGIN_VST: - info << " " << xmlSafeString(saveState.binary, true) << "\n"; - info << " " << saveState.uniqueID << "\n"; + info += QString(" %1\n").arg(xmlSafeString(saveState.binary, true)); + info += QString(" %1\n").arg(saveState.uniqueID); break; case PLUGIN_AU: // TODO? - info << " " << xmlSafeString(saveState.binary, true) << "\n"; - info << " " << saveState.uniqueID << "\n"; + info += QString(" %1\n").arg(xmlSafeString(saveState.binary, true)); + info += QString(" %1\n").arg(saveState.uniqueID); break; case PLUGIN_CSOUND: case PLUGIN_GIG: case PLUGIN_SF2: case PLUGIN_SFZ: - info << " " << xmlSafeString(saveState.binary, true) << "\n"; - info << " \n"; + info += QString(" %1\n").arg(xmlSafeString(saveState.binary, true)); + info += QString(" \n").arg(xmlSafeString(saveState.label, true)); break; } - info << " \n\n"; + info += " \n\n"; - content << info; + content += info; } { - String data(" \n"); + QString data(" \n"); - data << " " << (saveState.active ? "Yes" : "No") << "\n"; + data += QString(" %1\n").arg(saveState.active ? "Yes" : "No"); if (saveState.dryWet != 1.0f) - data << " " << saveState.dryWet << "\n"; + data += QString(" %1\n").arg(saveState.dryWet); if (saveState.volume != 1.0f) - data << " " << saveState.volume << "\n"; + data += QString(" %1\n").arg(saveState.volume); if (saveState.balanceLeft != -1.0f) - data << " " << saveState.balanceLeft << "\n"; + data += QString(" %1\n").arg(saveState.balanceLeft); if (saveState.balanceRight != 1.0f) - data << " " << saveState.balanceRight << "\n"; + data += QString(" %1\n").arg(saveState.balanceRight); if (saveState.panning != 0.0f) - data << " " << saveState.panning << "\n"; + data += QString(" %1\n").arg(saveState.panning); if (saveState.ctrlChannel < 0) - data << " N\n"; + data += QString(" N\n"); else - data << " " << saveState.ctrlChannel+1 << "\n"; + data += QString(" %1\n").arg(saveState.ctrlChannel+1); - content << data; + content += data; } for (StateParameterItenerator it = saveState.parameters.begin(); it.valid(); it.next()) { StateParameter* const stateParameter(*it); - String parameter("\n"" \n"); + QString parameter("\n"" \n"); - parameter << " " << (long)stateParameter->index << "\n"; // FIXME - parameter << " " << xmlSafeString(stateParameter->name, true) << "\n"; + parameter += QString(" %1\n").arg(stateParameter->index); + parameter += QString(" %1\n").arg(xmlSafeString(stateParameter->name, true)); if (stateParameter->symbol != nullptr && stateParameter->symbol[0] != '\0') - parameter << " " << xmlSafeString(stateParameter->symbol, true) << "\n"; + parameter += QString(" %1\n").arg(xmlSafeString(stateParameter->symbol, true)); - parameter << " " << stateParameter->value << "\n"; + parameter += QString(" %1\n").arg(stateParameter->value); if (stateParameter->midiCC > 0) { - parameter << " " << stateParameter->midiCC << "\n"; - parameter << " " << stateParameter->midiChannel+1 << "\n"; + parameter += QString(" %1\n").arg(stateParameter->midiCC); + parameter += QString(" %1\n").arg(stateParameter->midiChannel+1); } - parameter << " \n"; + parameter += " \n"; - content << parameter; + content += parameter; } - if (saveState.currentProgramIndex >= 0 && saveState.currentProgramName != nullptr) + if (saveState.currentProgramIndex >= 0 && saveState.currentProgramName != nullptr && saveState.currentProgramName[0] != '\0') { // ignore 'default' program -#ifdef __USE_GNU - if ((saveState.currentProgramIndex > 0 || strcasecmp(saveState.currentProgramName, "default") != 0)) -#else - if ((saveState.currentProgramIndex > 0 || std::strcmp(saveState.currentProgramName, "Default") != 0)) -#endif + if (saveState.currentProgramIndex > 0 || QString(saveState.currentProgramName).compare("default", Qt::CaseInsensitive) != 0) { - String program("\n"); - program << " " << saveState.currentProgramIndex+1 << "\n"; - program << " " << xmlSafeString(saveState.currentProgramName, true) << "\n"; + QString program("\n"); + program += QString(" %1\n").arg(saveState.currentProgramIndex+1); + program += QString(" %1\n").arg(xmlSafeString(saveState.currentProgramName, true)); - content << program; + content += program; } } if (saveState.currentMidiBank >= 0 && saveState.currentMidiProgram >= 0) { - String midiProgram("\n"); - midiProgram << " " << saveState.currentMidiBank+1 << "\n"; - midiProgram << " " << saveState.currentMidiProgram+1 << "\n"; + QString midiProgram("\n"); + midiProgram += QString(" %1\n").arg(saveState.currentMidiBank+1); + midiProgram += QString(" %1\n").arg(saveState.currentMidiProgram+1); - content << midiProgram; + content += midiProgram; } for (StateCustomDataItenerator it = saveState.customData.begin(); it.valid(); it.next()) { StateCustomData* const stateCustomData(*it); - String customData("\n"" \n"); - customData << " " << xmlSafeString(stateCustomData->type, true) << "\n"; - customData << " " << xmlSafeString(stateCustomData->key, true) << "\n"; + QString customData("\n"" \n"); + customData += QString(" %1\n").arg(xmlSafeString(stateCustomData->type, true)); + customData += QString(" %1\n").arg(xmlSafeString(stateCustomData->key, true)); - if (std::strcmp(stateCustomData->type, CUSTOM_DATA_CHUNK) == 0 || std::strlen(stateCustomData->value) >= 128) - customData << " \n" << xmlSafeString(stateCustomData->value, true) << "\n \n"; + if (std::strcmp(stateCustomData->type, CUSTOM_DATA_TYPE_CHUNK) == 0 || std::strlen(stateCustomData->value) >= 128) + { + customData += " \n"; + customData += QString("%1\n").arg(xmlSafeString(stateCustomData->value, true)); + customData += " \n"; + } else - customData << " " << xmlSafeString(stateCustomData->value, true) << "\n"; + customData += QString(" %1\n").arg(xmlSafeString(stateCustomData->value, true)); - customData << " \n"; + customData += " \n"; - content << customData; + content += customData; } if (saveState.chunk != nullptr && saveState.chunk[0] != '\0') { - String chunk("\n"" \n"); - chunk << saveState.chunk << "\n \n"; + QString chunk("\n"" \n"); + chunk += QString("%1\n").arg(saveState.chunk); + chunk += " \n"; - content << chunk; + content += chunk; } - content << " \n"; + content += " \n"; } // ----------------------------------------------------------------------- -#endif CARLA_BACKEND_END_NAMESPACE