From 1bffb3f79a793ec28bc1f0c19a4abc93cec9a839 Mon Sep 17 00:00:00 2001 From: falkTX Date: Thu, 16 Jan 2014 19:17:05 +0000 Subject: [PATCH] Continue --- source/backend/Makefile.mk | 25 +- source/backend/engine/CarlaEngine.cpp | 7 +- source/backend/engine/CarlaEngineNative.cpp | 9 +- source/backend/engine/Makefile | 16 +- source/backend/plugin/BridgePlugin.cpp | 1 + source/backend/plugin/CarlaPlugin.cpp | 4 + source/backend/plugin/CarlaPluginInternal.hpp | 2 + source/backend/plugin/CarlaPluginThread.cpp | 3 +- source/backend/plugin/DssiPlugin.cpp | 3 +- source/backend/plugin/LinuxSamplerPlugin.cpp | 2 + source/backend/plugin/Lv2Plugin.cpp | 3 +- source/backend/plugin/Makefile | 81 ++- source/backend/plugin/NativePlugin.cpp | 2 + source/backend/plugin/VstPlugin.cpp | 3 +- source/utils/CarlaLibCounter.hpp | 2 +- source/utils/CarlaStateUtils.cpp | 567 ++++++++++++++++++ source/utils/CarlaStateUtils.hpp | 543 +---------------- 17 files changed, 695 insertions(+), 578 deletions(-) create mode 100644 source/utils/CarlaStateUtils.cpp diff --git a/source/backend/Makefile.mk b/source/backend/Makefile.mk index d55088d36..3a6ee3228 100644 --- a/source/backend/Makefile.mk +++ b/source/backend/Makefile.mk @@ -6,15 +6,15 @@ include ../../Makefile.mk -# -------------------------------------------------------------- +# ---------------------------------------------------------------------------------------------------------------------------- BUILD_CXX_FLAGS += -I. -I.. -I../../includes -I../../utils -isystem ../../modules BUILD_CXX_FLAGS += $(LIBLO_FLAGS) -BUILD_CXX_FLAGS += $(QTCORE_FLAGS) -BUILD_CXX_FLAGS += $(QTXML_FLAGS) +# BUILD_CXX_FLAGS += $(QTCORE_FLAGS) +# BUILD_CXX_FLAGS += $(QTXML_FLAGS) -# -------------------------------------------------------------- +# ---------------------------------------------------------------------------------------------------------------------------- BUILD_CXX_FLAGS += -DWANT_NATIVE @@ -26,7 +26,7 @@ BUILD_CXX_FLAGS += -DWANT_LADSPA -DWANT_DSSI -DWANT_LV2 # endif endif -# -------------------------------------------------------------- +# ---------------------------------------------------------------------------------------------------------------------------- # ifeq ($(HAVE_CSOUND),true) # BUILD_CXX_FLAGS += -DWANT_CSOUND @@ -40,7 +40,7 @@ ifeq ($(HAVE_LINUXSAMPLER),true) BUILD_CXX_FLAGS += -DWANT_LINUXSAMPLER endif -# -------------------------------------------------------------- +# ---------------------------------------------------------------------------------------------------------------------------- ifeq ($(HAVE_AF_DEPS),true) BUILD_CXX_FLAGS += -DWANT_AUDIOFILE @@ -57,7 +57,7 @@ BUILD_CXX_FLAGS += -DWANT_ZYNADDSUBFX_UI endif endif -# -------------------------------------------------------------- +# ---------------------------------------------------------------------------------------------------------------------------- CARLA_DEFINES_H = ../../includes/CarlaDefines.h CARLA_MIDI_H = ../../includes/CarlaMIDI.h @@ -69,6 +69,7 @@ CARLA_PLUGIN_HPP = ../CarlaPlugin.hpp $(CARLA_BACKEND_H) CARLA_UTILS_HPP = ../../utils/CarlaUtils.hpp $(CARLA_DEFINES_H) CARLA_JUCE_UTILS_HPP = ../../utils/CarlaJuceUtils.hpp $(CARLA_UTILS_HPP) +CARLA_LIB_UTILS_HPP = ../../utils/CarlaLibUtils.hpp $(CARLA_UTILS_HPP) CARLA_OSC_UTILS_HPP = ../../utils/CarlaOscUtils.hpp $(CARLA_UTILS_HPP) CARLA_MUTEX_HPP = ../../utils/CarlaMutex.hpp $(CARLA_UTILS_HPP) @@ -76,19 +77,27 @@ CARLA_RING_BUFFER_HPP = ../../utils/CarlaRingBuffer.hpp $(CARLA_UTILS_HPP) CARLA_STRING_HPP = ../../utils/CarlaString.hpp $(CARLA_JUCE_UTILS_HPP) CARLA_THREAD_HPP = ../../utils/CarlaThread.hpp $(CARLA_MUTEX_HPP) $(CARLA_STRING_HPP) +LV2_ATOM_QUEUE_HPP = ../../utils/Lv2AtomQueue.hpp $(CARLA_MUTEX_HPP) $(CARLA_RING_BUFFER_HPP) LINKED_LIST_HPP = ../../utils/LinkedList.hpp $(CARLA_UTILS_HPP) RT_LINKED_LIST_HPP = ../../utils/RtLinkedList.hpp $(LINKED_LIST_HPP) CARLA_BACKEND_UTILS_HPP = ../../utils/CarlaBackendUtils.hpp $(CARLA_BACKEND_H) $(CARLA_HOST_H) $(CARLA_STRING_HPP) CARLA_BRIDGE_UTILS_HPP = ../../utils/CarlaBridgeUtils.hpp $(CARLA_RING_BUFFER_HPP) CARLA_ENGINE_UTILS_HPP = ../../utils/CarlaEngineUtils.hpp $(CARLA_ENGINE_HPP) $(CARLA_UTILS_HPP) +CARLA_LIB_COUNTER_HPP = ../../utils/CarlaLibCounter.hpp $(CARLA_LIB_UTILS_HPP) $(CARLA_MUTEX_HPP) $(LINKED_LIST_HPP) CARLA_PIPE_UTILS_HPP = ../../utils/CarlaPipeUtils.hpp $(CARLA_STRING_HPP) +CARLA_SHM_UTILS_HPP = ../../utils/CarlaShmUtils.hpp $(CARLA_UTILS_HPP) CARLA_STATE_UTILS_HPP = ../../utils/CarlaStateUtils.hpp $(CARLA_BACKEND_UTILS_HPP) $(CARLA_MIDI_H) $(LINKED_LIST_HPP) +CARLA_LADSPA_UTILS_HPP = ../../utils/CarlaLadspaUtils.hpp $(CARLA_UTILS_HPP) +CARLA_DSSI_UTILS_HPP = ../../utils/CarlaDssiUtils.hpp $(CARLA_LADSPA_UTILS_HPP) +CARLA_LV2_UTILS_HPP = ../../utils/CarlaLv2Utils.hpp $(CARLA_UTILS_HPP) +CARLA_VST_UTILS_HPP = ../../utils/CarlaVstUtils.hpp $(CARLA_UTILS_HPP) + CARLA_NATIVE_H = ../../modules/CarlaNative.h CARLA_NATIVE_HPP = ../../modules/CarlaNative.hpp $(CARLA_NATIVE_H) $(CARLA_MIDI_H) $(CARLA_JUCE_UTILS_HPP) JACK_BRIDGE_HPP = ../../modules/jackbridge/JackBridge.hpp $(CARLA_DEFINES_H) RTAUDIO_HPP = ../../modules/rtaudio/RtAudio.h RTMIDI_HPP = ../../modules/rtmidi/RtMidi.h $(CARLA_DEFINES_H) -# -------------------------------------------------------------- +# ---------------------------------------------------------------------------------------------------------------------------- diff --git a/source/backend/engine/CarlaEngine.cpp b/source/backend/engine/CarlaEngine.cpp index 109c70b72..c9c0332c8 100644 --- a/source/backend/engine/CarlaEngine.cpp +++ b/source/backend/engine/CarlaEngine.cpp @@ -32,6 +32,8 @@ #include "CarlaEngineUtils.hpp" #include "CarlaStateUtils.hpp" +#include "CarlaMIDI.h" + #ifndef HAVE_JUCE # include #else @@ -42,6 +44,7 @@ using juce::FloatVectorOperations; #include #include #include +#include // ----------------------------------------------------------------------- @@ -1414,8 +1417,8 @@ bool CarlaEngine::saveProject(const char* const filename) plugin->getRealName(strBuf); - if (strBuf[0] != '\0') - out << QString(" \n").arg(xmlSafeString(strBuf, true)); + //if (strBuf[0] != '\0') + // out << QString(" \n").arg(xmlSafeString(strBuf, true)); QString content; fillXmlStringFromSaveState(content, plugin->getSaveState()); diff --git a/source/backend/engine/CarlaEngineNative.cpp b/source/backend/engine/CarlaEngineNative.cpp index 5781fcf19..33615e910 100644 --- a/source/backend/engine/CarlaEngineNative.cpp +++ b/source/backend/engine/CarlaEngineNative.cpp @@ -27,16 +27,19 @@ #include "CarlaEngineInternal.hpp" #include "CarlaPlugin.hpp" -#include "CarlaNative.hpp" +#include "CarlaBackendUtils.hpp" #include "CarlaPipeUtils.hpp" #include "CarlaStateUtils.hpp" +#include "CarlaNative.hpp" + #ifdef HAVE_JUCE # include "juce_audio_basics.h" using juce::FloatVectorOperations; #endif #include +#include CARLA_BACKEND_START_NAMESPACE @@ -1255,8 +1258,8 @@ protected: plugin->getRealName(strBuf); - if (strBuf[0] != '\0') - out << QString(" \n").arg(xmlSafeString(strBuf, true)); + //if (strBuf[0] != '\0') + // out << QString(" \n").arg(xmlSafeString(strBuf, true)); QString content; fillXmlStringFromSaveState(content, plugin->getSaveState()); diff --git a/source/backend/engine/Makefile b/source/backend/engine/Makefile index f949559f4..14922c85d 100644 --- a/source/backend/engine/Makefile +++ b/source/backend/engine/Makefile @@ -49,7 +49,7 @@ endif all: $(TARGETa) $(TARGETp) clean: - $(RM) *.o $(OBJSp) $(TARGET) $(TARGETp) + $(RM) *.o $(TARGET) $(TARGETp) debug: $(MAKE) DEBUG=true @@ -66,8 +66,8 @@ $(TARGETp): $(OBJSp) # ---------------------------------------------------------------------------------------------------------------------------- -CarlaEngine.cpp.o: CarlaEngine.cpp $(CARLA_ENGINE_INTERNAL_HPP) $(CARLA_PLUGIN_HPP) $(CARLA_BACKEND_UTILS_HPP) $(CARLA_ENGINE_UTILS_HPP) $(CARLA_STATE_UTILS_HPP) - $(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ +CarlaEngine.cpp.o: CarlaEngine.cpp $(CARLA_ENGINE_INTERNAL_HPP) $(CARLA_PLUGIN_HPP) $(CARLA_BACKEND_UTILS_HPP) $(CARLA_ENGINE_UTILS_HPP) $(CARLA_STATE_UTILS_HPP) $(CARLA_MIDI_H) + $(CXX) $< $(BUILD_CXX_FLAGS) $(QTCORE_FLAGS) $(QTXML_FLAGS) -c -o $@ CarlaEngineInternal.cpp.o: CarlaEngineInternal.cpp $(CARLA_ENGINE_INTERNAL_HPP) $(CARLA_PLUGIN_HPP) $(CARLA_MIDI_H) $(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ @@ -79,7 +79,7 @@ CarlaEngineThread.cpp.o: CarlaEngineThread.cpp $(CARLA_ENGINE_HPP) $(CARLA_ENGIN $(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ CarlaEngineJack.cpp.o: CarlaEngineJack.cpp $(CARLA_ENGINE_INTERNAL_HPP) $(CARLA_PLUGIN_HPP) $(CARLA_BACKEND_UTILS_HPP) $(CARLA_ENGINE_UTILS_HPP) $(CARLA_MIDI_H) $(JACK_BRIDGE_HPP) - $(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ + $(CXX) $< $(BUILD_CXX_FLAGS) $(QTCORE_FLAGS) -c -o $@ CarlaEngineRtAudio.cpp.o: CarlaEngineRtAudio.cpp $(CARLA_ENGINE_INTERNAL_HPP) $(CARLA_BACKEND_UTILS_HPP) $(RT_LINKED_LIST_HPP) $(RTAUDIO_HPP) $(RTMIDI_HPP) $(CXX) $< $(BUILD_CXX_FLAGS) $(RTAUDIO_FLAGS) $(RTMIDI_FLAGS) -c -o $@ @@ -87,10 +87,10 @@ CarlaEngineRtAudio.cpp.o: CarlaEngineRtAudio.cpp $(CARLA_ENGINE_INTERNAL_HPP) $( CarlaEngineJuce.cpp.o: CarlaEngineJuce.cpp $(CARLA_ENGINE_INTERNAL_HPP) $(CARLA_BACKEND_UTILS_HPP) $(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ -CarlaEngineNative.cpp.o: CarlaEngineNative.cpp $(CARLA_ENGINE_INTERNAL_HPP) $(CARLA_PLUGIN_HPP) $(CARLA_NATIVE_HPP) $(CARLA_PIPE_UTILS_HPP) $(CARLA_STATE_UTILS_HPP) - $(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ +CarlaEngineNative.cpp.o: CarlaEngineNative.cpp $(CARLA_ENGINE_INTERNAL_HPP) $(CARLA_PLUGIN_HPP) $(CARLA_BACKEND_UTILS_HPP) $(CARLA_PIPE_UTILS_HPP) $(CARLA_STATE_UTILS_HPP) $(CARLA_NATIVE_HPP) + $(CXX) $< $(BUILD_CXX_FLAGS) $(QTCORE_FLAGS) $(QTXML_FLAGS) -c -o $@ -CarlaEngineNative.cpp.exp.o: CarlaEngineNative.cpp $(CARLA_ENGINE_INTERNAL_HPP) $(CARLA_PLUGIN_HPP) $(CARLA_NATIVE_HPP) $(CARLA_PIPE_UTILS_HPP) $(CARLA_STATE_UTILS_HPP) - $(CXX) $< $(BUILD_CXX_FLAGS) -DCARLA_PLUGIN_EXPORT -c -o $@ +CarlaEngineNative.cpp.exp.o: CarlaEngineNative.cpp $(CARLA_ENGINE_INTERNAL_HPP) $(CARLA_PLUGIN_HPP) $(CARLA_BACKEND_UTILS_HPP) $(CARLA_PIPE_UTILS_HPP) $(CARLA_STATE_UTILS_HPP) $(CARLA_NATIVE_HPP) + $(CXX) $< $(BUILD_CXX_FLAGS) $(QTCORE_FLAGS) $(QTXML_FLAGS) -DCARLA_PLUGIN_EXPORT -c -o $@ # ---------------------------------------------------------------------------------------------------------------------------- diff --git a/source/backend/plugin/BridgePlugin.cpp b/source/backend/plugin/BridgePlugin.cpp index be84cccbd..979cfa16c 100644 --- a/source/backend/plugin/BridgePlugin.cpp +++ b/source/backend/plugin/BridgePlugin.cpp @@ -20,6 +20,7 @@ #ifndef BUILD_BRIDGE +#include "CarlaBackendUtils.hpp" #include "CarlaBridgeUtils.hpp" #include "CarlaShmUtils.hpp" diff --git a/source/backend/plugin/CarlaPlugin.cpp b/source/backend/plugin/CarlaPlugin.cpp index 41c27392c..4f449d0b2 100644 --- a/source/backend/plugin/CarlaPlugin.cpp +++ b/source/backend/plugin/CarlaPlugin.cpp @@ -18,8 +18,12 @@ #include "CarlaPluginInternal.hpp" #include "CarlaEngine.hpp" +#include "CarlaBackendUtils.hpp" +#include "CarlaMIDI.h" + #include #include +#include CARLA_BACKEND_START_NAMESPACE diff --git a/source/backend/plugin/CarlaPluginInternal.hpp b/source/backend/plugin/CarlaPluginInternal.hpp index f0b3f7078..b3ea2e669 100644 --- a/source/backend/plugin/CarlaPluginInternal.hpp +++ b/source/backend/plugin/CarlaPluginInternal.hpp @@ -27,6 +27,8 @@ #include "CarlaMutex.hpp" #include "RtLinkedList.hpp" +#include "CarlaMIDI.h" + #include #ifdef HAVE_JUCE diff --git a/source/backend/plugin/CarlaPluginThread.cpp b/source/backend/plugin/CarlaPluginThread.cpp index eed466418..98ce503ae 100644 --- a/source/backend/plugin/CarlaPluginThread.cpp +++ b/source/backend/plugin/CarlaPluginThread.cpp @@ -15,9 +15,8 @@ * For a full copy of the GNU General Public License see the doc/GPL.txt file. */ -#include "CarlaPluginThread.hpp" - #include "CarlaPlugin.hpp" +#include "CarlaPluginThread.hpp" #include "CarlaEngine.hpp" #include diff --git a/source/backend/plugin/DssiPlugin.cpp b/source/backend/plugin/DssiPlugin.cpp index 39f0db9c0..32e58d7c4 100644 --- a/source/backend/plugin/DssiPlugin.cpp +++ b/source/backend/plugin/DssiPlugin.cpp @@ -21,7 +21,6 @@ #ifdef WANT_DSSI #include "CarlaDssiUtils.hpp" -#include "CarlaLibUtils.hpp" CARLA_BACKEND_START_NAMESPACE @@ -1806,7 +1805,7 @@ public: if (! pData->libOpen(filename)) { - pData->engine->setLastError(lib_error(filename)); + pData->engine->setLastError(pData->libError(filename)); return false; } diff --git a/source/backend/plugin/LinuxSamplerPlugin.cpp b/source/backend/plugin/LinuxSamplerPlugin.cpp index 975cd7df1..8bbd3e79a 100644 --- a/source/backend/plugin/LinuxSamplerPlugin.cpp +++ b/source/backend/plugin/LinuxSamplerPlugin.cpp @@ -26,6 +26,8 @@ #ifdef WANT_LINUXSAMPLER +#include "CarlaBackendUtils.hpp" + #include "linuxsampler/EngineFactory.h" #include diff --git a/source/backend/plugin/Lv2Plugin.cpp b/source/backend/plugin/Lv2Plugin.cpp index 4f2ac5f96..76583214f 100644 --- a/source/backend/plugin/Lv2Plugin.cpp +++ b/source/backend/plugin/Lv2Plugin.cpp @@ -21,7 +21,6 @@ #ifdef WANT_LV2 #include "CarlaLv2Utils.hpp" -#include "CarlaLibUtils.hpp" #include "Lv2AtomQueue.hpp" #include "../engine/CarlaEngineOsc.hpp" @@ -1408,7 +1407,7 @@ public: if (! pData->libOpen(fRdfDescriptor->Binary)) { - pData->engine->setLastError(lib_error(fRdfDescriptor->Binary)); + pData->engine->setLastError(pData->libError(fRdfDescriptor->Binary)); return false; } diff --git a/source/backend/plugin/Makefile b/source/backend/plugin/Makefile index 689ef1519..7336c597b 100644 --- a/source/backend/plugin/Makefile +++ b/source/backend/plugin/Makefile @@ -6,55 +6,92 @@ include ../Makefile.mk -# -------------------------------------------------------------- +# ---------------------------------------------------------------------------------------------------------------------------- + +CARLA_ENGINE_OSC_HPP = ../engine/CarlaEngineOsc.hpp $(CARLA_BACKEND_H) $(CARLA_OSC_UTILS_HPP) $(CARLA_STRING_HPP) +CARLA_PLUGIN_THREAD_HPP = CarlaPluginThread.hpp $(CARLA_BACKEND_H) $(CARLA_THREAD_HPP) +CARLA_PLUGIN_INTERNAL_HPP = CarlaPluginInternal.hpp $(CARLA_PLUGIN_HPP) $(CARLA_PLUGIN_THREAD_HPP) $(CARLA_OSC_UTILS_HPP) $(CARLA_STATE_UTILS_HPP) $(CARLA_MUTEX_HPP) $(RT_LINKED_LIST_HPP) $(CARLA_MIDI_H) + +# ---------------------------------------------------------------------------------------------------------------------------- OBJS = \ CarlaPlugin.cpp.o \ CarlaPluginInternal.cpp.o \ CarlaPluginThread.cpp.o \ - BridgePlugin.cpp.o \ NativePlugin.cpp.o \ + BridgePlugin.cpp.o \ LadspaPlugin.cpp.o \ DssiPlugin.cpp.o \ Lv2Plugin.cpp.o \ VstPlugin.cpp.o \ AuPlugin.cpp.o \ CsoundPlugin.cpp.o \ + JucePlugin.cpp.o \ FluidSynthPlugin.cpp.o \ - LinuxSamplerPlugin.cpp.o \ - JucePlugin.cpp.o + LinuxSamplerPlugin.cpp.o -HEADERS = \ - ../CarlaBackend.h ../CarlaEngine.hpp ../CarlaPlugin.hpp \ - CarlaPluginInternal.hpp CarlaPluginThread.hpp +# ---------------------------------------------------------------------------------------------------------------------------- TARGET = ../carla_plugin.a -# -------------------------------------------------------------- +# ---------------------------------------------------------------------------------------------------------------------------- all: $(TARGET) -# -------------------------------------------------------------- - -%.cpp.o: %.cpp $(HEADERS) - $(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ +clean: + $(RM) *.o $(TARGET) -FluidSynthPlugin.cpp.o: FluidSynthPlugin.cpp $(HEADERS) - $(CXX) $< $(BUILD_CXX_FLAGS) $(FLUIDSYNTH_FLAGS) -c -o $@ +debug: + $(MAKE) DEBUG=true -LinuxSamplerPlugin.cpp.o: LinuxSamplerPlugin.cpp $(HEADERS) - $(CXX) $< $(BUILD_CXX_FLAGS) $(LINUXSAMPLER_FLAGS) -c -o $@ +# ---------------------------------------------------------------------------------------------------------------------------- $(TARGET): $(OBJS) $(RM) $@ $(AR) crs $@ $^ -# -------------------------------------------------------------- +# ---------------------------------------------------------------------------------------------------------------------------- -clean: - $(RM) *.o $(TARGET) +CarlaPlugin.cpp.o: CarlaPlugin.cpp $(CARLA_PLUGIN_INTERNAL_HPP) $(CARLA_ENGINE_HPP) $(CARLA_BACKEND_UTILS_HPP) + $(CXX) $< $(BUILD_CXX_FLAGS) $(QTCORE_FLAGS) $(QTXML_FLAGS) -c -o $@ -debug: - $(MAKE) DEBUG=true +CarlaPluginInternal.cpp.o: CarlaPluginInternal.cpp $(CARLA_PLUGIN_INTERNAL_HPP) $(CARLA_ENGINE_HPP) $(CARLA_LIB_COUNTER_HPP) + $(CXX) $< $(BUILD_CXX_FLAGS) $(QTCORE_FLAGS) -c -o $@ + +CarlaPluginThread.cpp.o: CarlaPluginThread.cpp $(CARLA_PLUGIN_HPP) $(CARLA_PLUGIN_THREAD_HPP) $(CARLA_ENGINE_HPP) + $(CXX) $< $(BUILD_CXX_FLAGS) $(QTCORE_FLAGS) -c -o $@ + +NativePlugin.cpp.o: NativePlugin.cpp $(CARLA_PLUGIN_INTERNAL_HPP) $(CARLA_ENGINE_HPP) $(CARLA_NATIVE_H) $(CARLA_HOST_H) + $(CXX) $< $(BUILD_CXX_FLAGS) $(QTCORE_FLAGS) -c -o $@ + +BridgePlugin.cpp.o: BridgePlugin.cpp $(CARLA_PLUGIN_INTERNAL_HPP) $(CARLA_ENGINE_HPP) $(CARLA_BACKEND_UTILS_HPP) $(CARLA_BRIDGE_UTILS_HPP) $(CARLA_SHM_UTILS_HPP) $(JACK_BRIDGE_HPP) + $(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ + +LadspaPlugin.cpp.o: LadspaPlugin.cpp $(CARLA_PLUGIN_INTERNAL_HPP) $(CARLA_ENGINE_HPP) $(CARLA_LADSPA_UTILS_HPP) + $(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ + +DssiPlugin.cpp.o: DssiPlugin.cpp $(CARLA_PLUGIN_INTERNAL_HPP) $(CARLA_ENGINE_HPP) $(CARLA_DSSI_UTILS_HPP) + $(CXX) $< $(BUILD_CXX_FLAGS) $(QTCORE_FLAGS) -c -o $@ # FIXME + +Lv2Plugin.cpp.o: Lv2Plugin.cpp $(CARLA_PLUGIN_INTERNAL_HPP) $(CARLA_ENGINE_HPP) $(CARLA_LV2_UTILS_HPP) $(LV2_ATOM_QUEUE_HPP) $(CARLA_ENGINE_OSC_HPP) + $(CXX) $< $(BUILD_CXX_FLAGS) $(QTCORE_FLAGS) -c -o $@ # FIXME + +VstPlugin.cpp.o: VstPlugin.cpp $(CARLA_PLUGIN_INTERNAL_HPP) $(CARLA_ENGINE_HPP) $(CARLA_VST_UTILS_HPP) + $(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ + +AuPlugin.cpp.o: AuPlugin.cpp $(CARLA_PLUGIN_HPP) $(CARLA_ENGINE_HPP) $(CARLA_UTILS_HPP) + $(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ + +CsoundPlugin.cpp.o: CsoundPlugin.cpp $(CARLA_PLUGIN_INTERNAL_HPP) $(CARLA_ENGINE_HPP) + $(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ + +JucePlugin.cpp.o: JucePlugin.cpp $(CARLA_PLUGIN_INTERNAL_HPP) $(CARLA_ENGINE_HPP) + $(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ + +FluidSynthPlugin.cpp.o: FluidSynthPlugin.cpp $(CARLA_PLUGIN_INTERNAL_HPP) $(CARLA_ENGINE_HPP) + $(CXX) $< $(BUILD_CXX_FLAGS) $(FLUIDSYNTH_FLAGS) $(QTCORE_FLAGS) -c -o $@ + +LinuxSamplerPlugin.cpp.o: LinuxSamplerPlugin.cpp $(CARLA_PLUGIN_INTERNAL_HPP) $(CARLA_ENGINE_HPP) $(CARLA_BACKEND_UTILS_HPP) + $(CXX) $< $(BUILD_CXX_FLAGS) $(LINUXSAMPLER_FLAGS) $(QTCORE_FLAGS) -c -o $@ -# -------------------------------------------------------------- +# ---------------------------------------------------------------------------------------------------------------------------- diff --git a/source/backend/plugin/NativePlugin.cpp b/source/backend/plugin/NativePlugin.cpp index 5c3c2238f..b621a5346 100644 --- a/source/backend/plugin/NativePlugin.cpp +++ b/source/backend/plugin/NativePlugin.cpp @@ -23,6 +23,8 @@ #include "CarlaNative.h" #include "CarlaHost.h" +#include "CarlaMIDI.h" + #include extern const char* carla_file_callback(FileCallbackOpcode action, bool isDir, const char* title, const char* filter); diff --git a/source/backend/plugin/VstPlugin.cpp b/source/backend/plugin/VstPlugin.cpp index 7a89d8177..0ea74a443 100644 --- a/source/backend/plugin/VstPlugin.cpp +++ b/source/backend/plugin/VstPlugin.cpp @@ -21,7 +21,6 @@ #ifdef WANT_VST #include "CarlaVstUtils.hpp" -#include "CarlaLibUtils.hpp" CARLA_BACKEND_START_NAMESPACE @@ -2157,7 +2156,7 @@ public: if (! pData->libOpen(filename)) { - pData->engine->setLastError(lib_error(filename)); + pData->engine->setLastError(pData->libError(filename)); return false; } diff --git a/source/utils/CarlaLibCounter.hpp b/source/utils/CarlaLibCounter.hpp index 09eb94395..057114bef 100644 --- a/source/utils/CarlaLibCounter.hpp +++ b/source/utils/CarlaLibCounter.hpp @@ -31,7 +31,7 @@ public: void* open(const char* const filename) { - CARLA_SAFE_ASSERT_RETURN(filename != nullptr, nullptr); + CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', nullptr); const CarlaMutex::ScopedLocker sl(fMutex); diff --git a/source/utils/CarlaStateUtils.cpp b/source/utils/CarlaStateUtils.cpp new file mode 100644 index 000000000..ac39dc272 --- /dev/null +++ b/source/utils/CarlaStateUtils.cpp @@ -0,0 +1,567 @@ +/* + * Carla State utils + * Copyright (C) 2012-2014 Filipe Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * For a full copy of the GNU General Public License see the doc/GPL.txt file. + */ + +#include "CarlaStateUtils.hpp" + +#include "CarlaBackendUtils.hpp" +#include "CarlaMIDI.h" + +#include +#include + +CARLA_BACKEND_START_NAMESPACE + +// ----------------------------------------------------------------------- +// StateParameter + +StateParameter::StateParameter() noexcept + : index(0), + name(nullptr), + symbol(nullptr), + value(0.0f), + midiChannel(0), + midiCC(-1) {} + +StateParameter::~StateParameter() +{ + if (name != nullptr) + { + delete[] name; + name = nullptr; + } + if (symbol != nullptr) + { + delete[] symbol; + symbol = nullptr; + } +} + +// ----------------------------------------------------------------------- +// StateCustomData + +StateCustomData::StateCustomData() noexcept + : type(nullptr), + key(nullptr), + value(nullptr) {} + +StateCustomData::~StateCustomData() +{ + if (type != nullptr) + { + delete[] type; + type = nullptr; + } + if (key != nullptr) + { + delete[] key; + key = nullptr; + } + if (value != nullptr) + { + delete[] value; + value = nullptr; + } +} + +// ----------------------------------------------------------------------- +// SaveState + +SaveState::SaveState() noexcept + : type(nullptr), + name(nullptr), + label(nullptr), + binary(nullptr), + uniqueID(0), + active(false), + dryWet(1.0f), + volume(1.0f), + balanceLeft(-1.0f), + balanceRight(1.0f), + panning(0.0f), + ctrlChannel(-1), + currentProgramIndex(-1), + currentProgramName(nullptr), + currentMidiBank(-1), + currentMidiProgram(-1), + chunk(nullptr) {} + +SaveState::~SaveState() +{ + reset(); +} + +void SaveState::reset() +{ + if (type != nullptr) + { + delete[] type; + type = nullptr; + } + if (name != nullptr) + { + delete[] name; + name = nullptr; + } + if (label != nullptr) + { + delete[] label; + label = nullptr; + } + if (binary != nullptr) + { + delete[] binary; + binary = nullptr; + } + if (currentProgramName != nullptr) + { + delete[] currentProgramName; + currentProgramName = nullptr; + } + if (chunk != nullptr) + { + delete[] chunk; + chunk = nullptr; + } + + uniqueID = 0; + active = false; + dryWet = 1.0f; + volume = 1.0f; + balanceLeft = -1.0f; + balanceRight = 1.0f; + panning = 0.0f; + ctrlChannel = -1; + currentProgramIndex = -1; + currentMidiBank = -1; + currentMidiProgram = -1; + + for (StateParameterItenerator it = parameters.begin(); it.valid(); it.next()) + { + StateParameter* const stateParameter(it.getValue()); + delete stateParameter; + } + + for (StateCustomDataItenerator it = customData.begin(); it.valid(); it.next()) + { + StateCustomData* const stateCustomData(it.getValue()); + delete stateCustomData; + } + + parameters.clear(); + customData.clear(); +} + +// ----------------------------------------------------------------------- +// xmlSafeString + +QString xmlSafeString(const QString& string, const bool toXml) +{ + QString newString(string); + + if (toXml) + return newString.replace("&","&").replace("<","<").replace(">",">").replace("'","'").replace("\"","""); + else + return newString.replace("&","&").replace("<","<").replace(">",">").replace("'","'").replace(""","\""); +} + +const char* xmlSafeStringCharDup(const QString& string, const bool toXml) +{ + return carla_strdup(xmlSafeString(string, toXml).toUtf8().constData()); +} + +// ----------------------------------------------------------------------- +// fillSaveStateFromXmlNode + +void fillSaveStateFromXmlNode(SaveState& saveState, const QDomNode& xmlNode) +{ + if (xmlNode.isNull()) + return; + + for (QDomNode node = xmlNode.firstChild(); ! node.isNull(); node = node.nextSibling()) + { + QString tagName(node.toElement().tagName()); + + // --------------------------------------------------------------- + // Info + + if (tagName.compare("info", Qt::CaseInsensitive) == 0) + { + for (QDomNode xmlInfo = node.toElement().firstChild(); ! xmlInfo.isNull(); xmlInfo = xmlInfo.nextSibling()) + { + const QString tag(xmlInfo.toElement().tagName()); + const QString text(xmlInfo.toElement().text().trimmed()); + + if (tag.compare("type", Qt::CaseInsensitive) == 0) + { + saveState.type = xmlSafeStringCharDup(text, false); + } + else if (tag.compare("name", Qt::CaseInsensitive) == 0) + { + saveState.name = xmlSafeStringCharDup(text, false); + } + else if (tag.compare("label", Qt::CaseInsensitive) == 0 || tag.compare("uri", Qt::CaseInsensitive) == 0) + { + saveState.label = xmlSafeStringCharDup(text, false); + } + else if (tag.compare("binary", Qt::CaseInsensitive) == 0 || tag.compare("filename", Qt::CaseInsensitive) == 0) + { + saveState.binary = xmlSafeStringCharDup(text, false); + } + else if (tag.compare("uniqueid", Qt::CaseInsensitive) == 0) + { + bool ok; + const long uniqueID(text.toLong(&ok)); + if (ok) saveState.uniqueID = uniqueID; + } + } + } + + // --------------------------------------------------------------- + // Data + + else if (tagName.compare("data", Qt::CaseInsensitive) == 0) + { + for (QDomNode xmlData = node.toElement().firstChild(); ! xmlData.isNull(); xmlData = xmlData.nextSibling()) + { + const QString tag(xmlData.toElement().tagName()); + const QString text(xmlData.toElement().text().trimmed()); + + // ------------------------------------------------------- + // Internal Data + + if (tag.compare("active", Qt::CaseInsensitive) == 0) + { + saveState.active = (text.compare("yes", Qt::CaseInsensitive) == 0 || text.compare("true", Qt::CaseInsensitive) == 0); + } + else if (tag.compare("drywet", Qt::CaseInsensitive) == 0) + { + bool ok; + const float value(text.toFloat(&ok)); + if (ok) saveState.dryWet = carla_fixValue(0.0f, 1.0f, value); + } + else if (tag.compare("volume", Qt::CaseInsensitive) == 0) + { + bool ok; + const float value(text.toFloat(&ok)); + if (ok) saveState.volume = carla_fixValue(0.0f, 1.27f, value); + } + else if (tag.compare("balanceleft", Qt::CaseInsensitive) == 0 || tag.compare("balance-left", Qt::CaseInsensitive) == 0) + { + bool ok; + const float value(text.toFloat(&ok)); + if (ok) saveState.balanceLeft = carla_fixValue(-1.0f, 1.0f, value); + } + else if (tag.compare("balanceright", Qt::CaseInsensitive) == 0 || tag.compare("balance-right", Qt::CaseInsensitive) == 0) + { + bool ok; + const float value(text.toFloat(&ok)); + if (ok) saveState.balanceRight = carla_fixValue(-1.0f, 1.0f, value); + } + else if (tag.compare("panning", Qt::CaseInsensitive) == 0) + { + bool ok; + const float value(text.toFloat(&ok)); + if (ok) saveState.panning = carla_fixValue(-1.0f, 1.0f, value); + } + else if (tag.compare("controlchannel", Qt::CaseInsensitive) == 0 || tag.compare("control-channel", Qt::CaseInsensitive) == 0) + { + 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.compare("currentprogramindex", Qt::CaseInsensitive) == 0 || tag.compare("current-program-index", Qt::CaseInsensitive) == 0) + { + bool ok; + const int value(text.toInt(&ok)); + if (ok && value >= 1) + saveState.currentProgramIndex = value-1; + } + else if (tag.compare("currentprogramname", Qt::CaseInsensitive) == 0 || tag.compare("current-program-name", Qt::CaseInsensitive) == 0) + { + saveState.currentProgramName = xmlSafeStringCharDup(text, false); + } + + // ------------------------------------------------------- + // Midi Program (current) + + else if (tag.compare("currentmidibank", Qt::CaseInsensitive) == 0 || tag.compare("current-midi-bank", Qt::CaseInsensitive) == 0) + { + bool ok; + const int value(text.toInt(&ok)); + if (ok && value >= 1) + saveState.currentMidiBank = value-1; + } + else if (tag.compare("currentmidiprogram", Qt::CaseInsensitive) == 0 || tag.compare("current-midi-program", Qt::CaseInsensitive) == 0) + { + bool ok; + const int value(text.toInt(&ok)); + if (ok && value >= 1) + saveState.currentMidiProgram = value-1; + } + + // ------------------------------------------------------- + // Parameters + + else if (tag.compare("parameter", Qt::CaseInsensitive) == 0) + { + StateParameter* const stateParameter(new StateParameter()); + + for (QDomNode xmlSubData = xmlData.toElement().firstChild(); ! xmlSubData.isNull(); xmlSubData = xmlSubData.nextSibling()) + { + const QString pTag(xmlSubData.toElement().tagName()); + const QString pText(xmlSubData.toElement().text().trimmed()); + + if (pTag.compare("index", Qt::CaseInsensitive) == 0) + { + bool ok; + const uint index(pText.toUInt(&ok)); + if (ok) stateParameter->index = index; + } + else if (pTag.compare("name", Qt::CaseInsensitive) == 0) + { + stateParameter->name = xmlSafeStringCharDup(pText, false); + } + else if (pTag.compare("symbol", Qt::CaseInsensitive) == 0) + { + stateParameter->symbol = xmlSafeStringCharDup(pText, false); + } + else if (pTag.compare("value", Qt::CaseInsensitive) == 0) + { + bool ok; + const float value(pText.toFloat(&ok)); + if (ok) stateParameter->value = value; + } + else if (pTag.compare("midichannel", Qt::CaseInsensitive) == 0 || pTag.compare("midi-channel", Qt::CaseInsensitive) == 0) + { + 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.compare("midicc", Qt::CaseInsensitive) == 0 || pTag.compare("midi-cc", Qt::CaseInsensitive) == 0) + { + bool ok; + const int cc(pText.toInt(&ok)); + if (ok && cc >= 1 && cc < 0x5F) + stateParameter->midiCC = static_cast(cc); + } + } + + saveState.parameters.append(stateParameter); + } + + // ------------------------------------------------------- + // Custom Data + + else if (tag.compare("customdata", Qt::CaseInsensitive) == 0 || tag.compare("custom-data", Qt::CaseInsensitive) == 0) + { + StateCustomData* const stateCustomData(new StateCustomData()); + + for (QDomNode xmlSubData = xmlData.toElement().firstChild(); ! xmlSubData.isNull(); xmlSubData = xmlSubData.nextSibling()) + { + const QString cTag(xmlSubData.toElement().tagName()); + const QString cText(xmlSubData.toElement().text().trimmed()); + + if (cTag.compare("type", Qt::CaseInsensitive) == 0) + stateCustomData->type = xmlSafeStringCharDup(cText, false); + else if (cTag.compare("key", Qt::CaseInsensitive) == 0) + stateCustomData->key = xmlSafeStringCharDup(cText, false); + else if (cTag.compare("value", Qt::CaseInsensitive) == 0) + stateCustomData->value = xmlSafeStringCharDup(cText, false); + } + + saveState.customData.append(stateCustomData); + } + + // ------------------------------------------------------- + // Chunk + + else if (tag.compare("chunk", Qt::CaseInsensitive) == 0) + { + saveState.chunk = xmlSafeStringCharDup(text, false); + } + } + } + } +} + +// ----------------------------------------------------------------------- +// fillXmlStringFromSaveState + +void fillXmlStringFromSaveState(QString& content, const SaveState& saveState) +{ + { + QString info(" \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 += QString(" \n").arg(xmlSafeString(saveState.label, true)); + break; + case PLUGIN_LADSPA: + 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 += QString(" %1\n").arg(xmlSafeString(saveState.binary, true)); + info += QString(" \n").arg(xmlSafeString(saveState.label, true)); + break; + case PLUGIN_LV2: + info += QString(" %1\n").arg(xmlSafeString(saveState.label, true)); + break; + case PLUGIN_VST: + info += QString(" %1\n").arg(xmlSafeString(saveState.binary, true)); + info += QString(" %1\n").arg(saveState.uniqueID); + break; + case PLUGIN_AU: + // TODO? + info += QString(" %1\n").arg(xmlSafeString(saveState.binary, true)); + info += QString(" %1\n").arg(saveState.uniqueID); + break; + case PLUGIN_FILE_CSD: + case PLUGIN_FILE_GIG: + case PLUGIN_FILE_SF2: + case PLUGIN_FILE_SFZ: + info += QString(" %1\n").arg(xmlSafeString(saveState.binary, true)); + info += QString(" \n").arg(xmlSafeString(saveState.label, true)); + break; + } + + info += " \n\n"; + + content += info; + } + + { + QString data(" \n"); + + data += QString(" %1\n").arg(saveState.active ? "Yes" : "No"); + + if (saveState.dryWet != 1.0f) + data += QString(" %1\n").arg(saveState.dryWet); + if (saveState.volume != 1.0f) + data += QString(" %1\n").arg(saveState.volume); + if (saveState.balanceLeft != -1.0f) + data += QString(" %1\n").arg(saveState.balanceLeft); + if (saveState.balanceRight != 1.0f) + data += QString(" %1\n").arg(saveState.balanceRight); + if (saveState.panning != 0.0f) + data += QString(" %1\n").arg(saveState.panning); + + if (saveState.ctrlChannel < 0) + data += QString(" N\n"); + else + data += QString(" %1\n").arg(saveState.ctrlChannel+1); + + content += data; + } + + for (StateParameterItenerator it = saveState.parameters.begin(); it.valid(); it.next()) + { + StateParameter* const stateParameter(it.getValue()); + + QString parameter("\n"" \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 += QString(" %1\n").arg(xmlSafeString(stateParameter->symbol, true)); + + parameter += QString(" %1\n").arg(stateParameter->value); + + if (stateParameter->midiCC > 0) + { + parameter += QString(" %1\n").arg(stateParameter->midiCC); + parameter += QString(" %1\n").arg(stateParameter->midiChannel+1); + } + + parameter += " \n"; + + content += parameter; + } + + if (saveState.currentProgramIndex >= 0 && saveState.currentProgramName != nullptr && saveState.currentProgramName[0] != '\0') + { + // ignore 'default' program + if (saveState.currentProgramIndex > 0 || QString(saveState.currentProgramName).compare("default", Qt::CaseInsensitive) != 0) + { + QString program("\n"); + program += QString(" %1\n").arg(saveState.currentProgramIndex+1); + program += QString(" %1\n").arg(xmlSafeString(saveState.currentProgramName, true)); + + content += program; + } + } + + if (saveState.currentMidiBank >= 0 && saveState.currentMidiProgram >= 0) + { + QString midiProgram("\n"); + midiProgram += QString(" %1\n").arg(saveState.currentMidiBank+1); + midiProgram += QString(" %1\n").arg(saveState.currentMidiProgram+1); + + content += midiProgram; + } + + for (StateCustomDataItenerator it = saveState.customData.begin(); it.valid(); it.next()) + { + StateCustomData* const stateCustomData(it.getValue()); + + 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_TYPE_CHUNK) == 0 || std::strlen(stateCustomData->value) >= 128) + { + customData += " \n"; + customData += QString("%1\n").arg(xmlSafeString(stateCustomData->value, true)); + customData += " \n"; + } + else + customData += QString(" %1\n").arg(xmlSafeString(stateCustomData->value, true)); + + customData += " \n"; + + content += customData; + } + + if (saveState.chunk != nullptr && saveState.chunk[0] != '\0') + { + QString chunk("\n"" \n"); + chunk += QString("%1\n").arg(saveState.chunk); + chunk += " \n"; + + content += chunk; + } + + content += " \n"; +} + +// ----------------------------------------------------------------------- + +CARLA_BACKEND_END_NAMESPACE diff --git a/source/utils/CarlaStateUtils.hpp b/source/utils/CarlaStateUtils.hpp index e5e2f64a2..4c79ff3fe 100644 --- a/source/utils/CarlaStateUtils.hpp +++ b/source/utils/CarlaStateUtils.hpp @@ -18,14 +18,19 @@ #ifndef CARLA_STATE_UTILS_HPP_INCLUDED #define CARLA_STATE_UTILS_HPP_INCLUDED -#include "CarlaBackendUtils.hpp" -#include "CarlaMIDI.h" #include "LinkedList.hpp" -#include +class QDomNode; +class QString; + +// ----------------------------------------------------------------------- CARLA_BACKEND_START_NAMESPACE +#if 0 +} // Fix editor indentation +#endif + // ----------------------------------------------------------------------- struct StateParameter { @@ -36,27 +41,8 @@ struct StateParameter { uint8_t midiChannel; int16_t midiCC; - StateParameter() noexcept - : index(0), - name(nullptr), - symbol(nullptr), - value(0.0f), - midiChannel(0), - midiCC(-1) {} - - ~StateParameter() - { - if (name != nullptr) - { - delete[] name; - name = nullptr; - } - if (symbol != nullptr) - { - delete[] symbol; - symbol = nullptr; - } - } + StateParameter() noexcept; + ~StateParameter(); CARLA_DECLARE_NON_COPY_STRUCT(StateParameter) }; @@ -66,29 +52,8 @@ struct StateCustomData { const char* key; const char* value; - StateCustomData() noexcept - : type(nullptr), - key(nullptr), - value(nullptr) {} - - ~StateCustomData() - { - if (type != nullptr) - { - delete[] type; - type = nullptr; - } - if (key != nullptr) - { - delete[] key; - key = nullptr; - } - if (value != nullptr) - { - delete[] value; - value = nullptr; - } - } + StateCustomData() noexcept; + ~StateCustomData(); CARLA_DECLARE_NON_COPY_STRUCT(StateCustomData) }; @@ -123,491 +88,17 @@ struct SaveState { StateParameterList parameters; StateCustomDataList customData; - SaveState() noexcept - : type(nullptr), - name(nullptr), - label(nullptr), - binary(nullptr), - uniqueID(0), - active(false), - dryWet(1.0f), - volume(1.0f), - balanceLeft(-1.0f), - balanceRight(1.0f), - panning(0.0f), - ctrlChannel(-1), - currentProgramIndex(-1), - currentProgramName(nullptr), - currentMidiBank(-1), - currentMidiProgram(-1), - chunk(nullptr) {} - - ~SaveState() - { - reset(); - } - - void reset() - { - if (type != nullptr) - { - delete[] type; - type = nullptr; - } - if (name != nullptr) - { - delete[] name; - name = nullptr; - } - if (label != nullptr) - { - delete[] label; - label = nullptr; - } - if (binary != nullptr) - { - delete[] binary; - binary = nullptr; - } - if (currentProgramName != nullptr) - { - delete[] currentProgramName; - currentProgramName = nullptr; - } - if (chunk != nullptr) - { - delete[] chunk; - chunk = nullptr; - } - - uniqueID = 0; - active = false; - dryWet = 1.0f; - volume = 1.0f; - balanceLeft = -1.0f; - balanceRight = 1.0f; - panning = 0.0f; - ctrlChannel = -1; - currentProgramIndex = -1; - currentMidiBank = -1; - currentMidiProgram = -1; - - for (StateParameterItenerator it = parameters.begin(); it.valid(); it.next()) - { - StateParameter* const stateParameter(it.getValue()); - delete stateParameter; - } - - for (StateCustomDataItenerator it = customData.begin(); it.valid(); it.next()) - { - StateCustomData* const stateCustomData(it.getValue()); - delete stateCustomData; - } - - parameters.clear(); - customData.clear(); - } + SaveState() noexcept; + ~SaveState(); + void reset(); CARLA_DECLARE_NON_COPY_STRUCT(SaveState) }; // ----------------------------------------------------------------------- -static inline -QString xmlSafeString(const QString& string, const bool toXml) -{ - QString newString(string); - - if (toXml) - return newString.replace("&","&").replace("<","<").replace(">",">").replace("'","'").replace("\"","""); - else - return newString.replace("&","&").replace("<","<").replace(">",">").replace("'","'").replace(""","\""); -} - -static inline -const char* xmlSafeStringCharDup(const QString& string, const bool toXml) -{ - return carla_strdup(xmlSafeString(string, toXml).toUtf8().constData()); -} - -// ----------------------------------------------------------------------- - -static inline -void fillSaveStateFromXmlNode(SaveState& saveState, const QDomNode& xmlNode) -{ - if (xmlNode.isNull()) - return; - - for (QDomNode node = xmlNode.firstChild(); ! node.isNull(); node = node.nextSibling()) - { - QString tagName(node.toElement().tagName()); - - // --------------------------------------------------------------- - // Info - - if (tagName.compare("info", Qt::CaseInsensitive) == 0) - { - for (QDomNode xmlInfo = node.toElement().firstChild(); ! xmlInfo.isNull(); xmlInfo = xmlInfo.nextSibling()) - { - const QString tag(xmlInfo.toElement().tagName()); - const QString text(xmlInfo.toElement().text().trimmed()); - - if (tag.compare("type", Qt::CaseInsensitive) == 0) - { - saveState.type = xmlSafeStringCharDup(text, false); - } - else if (tag.compare("name", Qt::CaseInsensitive) == 0) - { - saveState.name = xmlSafeStringCharDup(text, false); - } - else if (tag.compare("label", Qt::CaseInsensitive) == 0 || tag.compare("uri", Qt::CaseInsensitive) == 0) - { - saveState.label = xmlSafeStringCharDup(text, false); - } - else if (tag.compare("binary", Qt::CaseInsensitive) == 0 || tag.compare("filename", Qt::CaseInsensitive) == 0) - { - saveState.binary = xmlSafeStringCharDup(text, false); - } - else if (tag.compare("uniqueid", Qt::CaseInsensitive) == 0) - { - bool ok; - const long uniqueID(text.toLong(&ok)); - if (ok) saveState.uniqueID = uniqueID; - } - } - } - - // --------------------------------------------------------------- - // Data - - else if (tagName.compare("data", Qt::CaseInsensitive) == 0) - { - for (QDomNode xmlData = node.toElement().firstChild(); ! xmlData.isNull(); xmlData = xmlData.nextSibling()) - { - const QString tag(xmlData.toElement().tagName()); - const QString text(xmlData.toElement().text().trimmed()); - - // ------------------------------------------------------- - // Internal Data - - if (tag.compare("active", Qt::CaseInsensitive) == 0) - { - saveState.active = (text.compare("yes", Qt::CaseInsensitive) == 0 || text.compare("true", Qt::CaseInsensitive) == 0); - } - else if (tag.compare("drywet", Qt::CaseInsensitive) == 0) - { - bool ok; - const float value(text.toFloat(&ok)); - if (ok) saveState.dryWet = carla_fixValue(0.0f, 1.0f, value); - } - else if (tag.compare("volume", Qt::CaseInsensitive) == 0) - { - bool ok; - const float value(text.toFloat(&ok)); - if (ok) saveState.volume = carla_fixValue(0.0f, 1.27f, value); - } - else if (tag.compare("balanceleft", Qt::CaseInsensitive) == 0 || tag.compare("balance-left", Qt::CaseInsensitive) == 0) - { - bool ok; - const float value(text.toFloat(&ok)); - if (ok) saveState.balanceLeft = carla_fixValue(-1.0f, 1.0f, value); - } - else if (tag.compare("balanceright", Qt::CaseInsensitive) == 0 || tag.compare("balance-right", Qt::CaseInsensitive) == 0) - { - bool ok; - const float value(text.toFloat(&ok)); - if (ok) saveState.balanceRight = carla_fixValue(-1.0f, 1.0f, value); - } - else if (tag.compare("panning", Qt::CaseInsensitive) == 0) - { - bool ok; - const float value(text.toFloat(&ok)); - if (ok) saveState.panning = carla_fixValue(-1.0f, 1.0f, value); - } - else if (tag.compare("controlchannel", Qt::CaseInsensitive) == 0 || tag.compare("control-channel", Qt::CaseInsensitive) == 0) - { - 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.compare("currentprogramindex", Qt::CaseInsensitive) == 0 || tag.compare("current-program-index", Qt::CaseInsensitive) == 0) - { - bool ok; - const int value(text.toInt(&ok)); - if (ok && value >= 1) - saveState.currentProgramIndex = value-1; - } - else if (tag.compare("currentprogramname", Qt::CaseInsensitive) == 0 || tag.compare("current-program-name", Qt::CaseInsensitive) == 0) - { - saveState.currentProgramName = xmlSafeStringCharDup(text, false); - } - - // ------------------------------------------------------- - // Midi Program (current) - - else if (tag.compare("currentmidibank", Qt::CaseInsensitive) == 0 || tag.compare("current-midi-bank", Qt::CaseInsensitive) == 0) - { - bool ok; - const int value(text.toInt(&ok)); - if (ok && value >= 1) - saveState.currentMidiBank = value-1; - } - else if (tag.compare("currentmidiprogram", Qt::CaseInsensitive) == 0 || tag.compare("current-midi-program", Qt::CaseInsensitive) == 0) - { - bool ok; - const int value(text.toInt(&ok)); - if (ok && value >= 1) - saveState.currentMidiProgram = value-1; - } - - // ------------------------------------------------------- - // Parameters - - else if (tag.compare("parameter", Qt::CaseInsensitive) == 0) - { - StateParameter* const stateParameter(new StateParameter()); - - for (QDomNode xmlSubData = xmlData.toElement().firstChild(); ! xmlSubData.isNull(); xmlSubData = xmlSubData.nextSibling()) - { - const QString pTag(xmlSubData.toElement().tagName()); - const QString pText(xmlSubData.toElement().text().trimmed()); - - if (pTag.compare("index", Qt::CaseInsensitive) == 0) - { - bool ok; - const uint index(pText.toUInt(&ok)); - if (ok) stateParameter->index = index; - } - else if (pTag.compare("name", Qt::CaseInsensitive) == 0) - { - stateParameter->name = xmlSafeStringCharDup(pText, false); - } - else if (pTag.compare("symbol", Qt::CaseInsensitive) == 0) - { - stateParameter->symbol = xmlSafeStringCharDup(pText, false); - } - else if (pTag.compare("value", Qt::CaseInsensitive) == 0) - { - bool ok; - const float value(pText.toFloat(&ok)); - if (ok) stateParameter->value = value; - } - else if (pTag.compare("midichannel", Qt::CaseInsensitive) == 0 || pTag.compare("midi-channel", Qt::CaseInsensitive) == 0) - { - 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.compare("midicc", Qt::CaseInsensitive) == 0 || pTag.compare("midi-cc", Qt::CaseInsensitive) == 0) - { - bool ok; - const int cc(pText.toInt(&ok)); - if (ok && cc >= 1 && cc < 0x5F) - stateParameter->midiCC = static_cast(cc); - } - } - - saveState.parameters.append(stateParameter); - } - - // ------------------------------------------------------- - // Custom Data - - else if (tag.compare("customdata", Qt::CaseInsensitive) == 0 || tag.compare("custom-data", Qt::CaseInsensitive) == 0) - { - StateCustomData* const stateCustomData(new StateCustomData()); - - for (QDomNode xmlSubData = xmlData.toElement().firstChild(); ! xmlSubData.isNull(); xmlSubData = xmlSubData.nextSibling()) - { - const QString cTag(xmlSubData.toElement().tagName()); - const QString cText(xmlSubData.toElement().text().trimmed()); - - if (cTag.compare("type", Qt::CaseInsensitive) == 0) - stateCustomData->type = xmlSafeStringCharDup(cText, false); - else if (cTag.compare("key", Qt::CaseInsensitive) == 0) - stateCustomData->key = xmlSafeStringCharDup(cText, false); - else if (cTag.compare("value", Qt::CaseInsensitive) == 0) - stateCustomData->value = xmlSafeStringCharDup(cText, false); - } - - saveState.customData.append(stateCustomData); - } - - // ------------------------------------------------------- - // Chunk - - else if (tag.compare("chunk", Qt::CaseInsensitive) == 0) - { - saveState.chunk = xmlSafeStringCharDup(text, false); - } - } - } - } -} - -// ----------------------------------------------------------------------- - -static inline -void fillXmlStringFromSaveState(QString& content, const SaveState& saveState) -{ - { - QString info(" \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 += QString(" \n").arg(xmlSafeString(saveState.label, true)); - break; - case PLUGIN_LADSPA: - 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 += QString(" %1\n").arg(xmlSafeString(saveState.binary, true)); - info += QString(" \n").arg(xmlSafeString(saveState.label, true)); - break; - case PLUGIN_LV2: - info += QString(" %1\n").arg(xmlSafeString(saveState.label, true)); - break; - case PLUGIN_VST: - info += QString(" %1\n").arg(xmlSafeString(saveState.binary, true)); - info += QString(" %1\n").arg(saveState.uniqueID); - break; - case PLUGIN_AU: - // TODO? - info += QString(" %1\n").arg(xmlSafeString(saveState.binary, true)); - info += QString(" %1\n").arg(saveState.uniqueID); - break; - case PLUGIN_FILE_CSD: - case PLUGIN_FILE_GIG: - case PLUGIN_FILE_SF2: - case PLUGIN_FILE_SFZ: - info += QString(" %1\n").arg(xmlSafeString(saveState.binary, true)); - info += QString(" \n").arg(xmlSafeString(saveState.label, true)); - break; - } - - info += " \n\n"; - - content += info; - } - - { - QString data(" \n"); - - data += QString(" %1\n").arg(saveState.active ? "Yes" : "No"); - - if (saveState.dryWet != 1.0f) - data += QString(" %1\n").arg(saveState.dryWet); - if (saveState.volume != 1.0f) - data += QString(" %1\n").arg(saveState.volume); - if (saveState.balanceLeft != -1.0f) - data += QString(" %1\n").arg(saveState.balanceLeft); - if (saveState.balanceRight != 1.0f) - data += QString(" %1\n").arg(saveState.balanceRight); - if (saveState.panning != 0.0f) - data += QString(" %1\n").arg(saveState.panning); - - if (saveState.ctrlChannel < 0) - data += QString(" N\n"); - else - data += QString(" %1\n").arg(saveState.ctrlChannel+1); - - content += data; - } - - for (StateParameterItenerator it = saveState.parameters.begin(); it.valid(); it.next()) - { - StateParameter* const stateParameter(it.getValue()); - - QString parameter("\n"" \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 += QString(" %1\n").arg(xmlSafeString(stateParameter->symbol, true)); - - parameter += QString(" %1\n").arg(stateParameter->value); - - if (stateParameter->midiCC > 0) - { - parameter += QString(" %1\n").arg(stateParameter->midiCC); - parameter += QString(" %1\n").arg(stateParameter->midiChannel+1); - } - - parameter += " \n"; - - content += parameter; - } - - if (saveState.currentProgramIndex >= 0 && saveState.currentProgramName != nullptr && saveState.currentProgramName[0] != '\0') - { - // ignore 'default' program - if (saveState.currentProgramIndex > 0 || QString(saveState.currentProgramName).compare("default", Qt::CaseInsensitive) != 0) - { - QString program("\n"); - program += QString(" %1\n").arg(saveState.currentProgramIndex+1); - program += QString(" %1\n").arg(xmlSafeString(saveState.currentProgramName, true)); - - content += program; - } - } - - if (saveState.currentMidiBank >= 0 && saveState.currentMidiProgram >= 0) - { - QString midiProgram("\n"); - midiProgram += QString(" %1\n").arg(saveState.currentMidiBank+1); - midiProgram += QString(" %1\n").arg(saveState.currentMidiProgram+1); - - content += midiProgram; - } - - for (StateCustomDataItenerator it = saveState.customData.begin(); it.valid(); it.next()) - { - StateCustomData* const stateCustomData(it.getValue()); - - 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_TYPE_CHUNK) == 0 || std::strlen(stateCustomData->value) >= 128) - { - customData += " \n"; - customData += QString("%1\n").arg(xmlSafeString(stateCustomData->value, true)); - customData += " \n"; - } - else - customData += QString(" %1\n").arg(xmlSafeString(stateCustomData->value, true)); - - customData += " \n"; - - content += customData; - } - - if (saveState.chunk != nullptr && saveState.chunk[0] != '\0') - { - QString chunk("\n"" \n"); - chunk += QString("%1\n").arg(saveState.chunk); - chunk += " \n"; - - content += chunk; - } - - content += " \n"; -} +void fillSaveStateFromXmlNode(SaveState& saveState, const QDomNode& xmlNode); +void fillXmlStringFromSaveState(QString& content, const SaveState& saveState); // -----------------------------------------------------------------------