diff --git a/doc/Carla-TODO b/doc/Carla-TODO index 4cc90d930..35ee4dafe 100644 --- a/doc/Carla-TODO +++ b/doc/Carla-TODO @@ -14,6 +14,7 @@ ENGINE: - implement latency in continuous-rack mode - DSSI/LV2/VST version (needs add-new support on control side) - Handle sample-rate changes in JACK (made possible by switch-master) + - Add MIDI-bank change type (GM, GS, XG and MMA). See fluidsynth docs Native: - Cleanup API diff --git a/source/backend/plugin/FluidSynthPlugin.cpp b/source/backend/plugin/FluidSynthPlugin.cpp index e5daf5b69..448ab69a7 100644 --- a/source/backend/plugin/FluidSynthPlugin.cpp +++ b/source/backend/plugin/FluidSynthPlugin.cpp @@ -21,7 +21,9 @@ #include -#define FLUIDSYNTH_VERSION_NEW_API (FLUIDSYNTH_VERSION_MAJOR >= 1 && FLUIDSYNTH_VERSION_MINOR >= 1 && FLUIDSYNTH_VERSION_MICRO >= 4) +#if (FLUIDSYNTH_VERSION_MAJOR >= 1 && FLUIDSYNTH_VERSION_MINOR >= 1 && FLUIDSYNTH_VERSION_MICRO >= 4) +# define FLUIDSYNTH_VERSION_NEW_API +#endif CARLA_BACKEND_START_NAMESPACE @@ -40,44 +42,38 @@ public: fSettings(nullptr), fSynth(nullptr), fSynthId(-1), -#ifdef CARLA_PROPER_CPP11_SUPPORT - fAudio16Buffers(nullptr), - fParamBuffers{0.0f}, - fCurMidiProgs{0} -#else fAudio16Buffers(nullptr) -#endif { carla_debug("FluidSynthPlugin::FluidSynthPlugin(%p, %i, %s)", engine, id, bool2str(use16Outs)); -#ifndef CARLA_PROPER_CPP11_SUPPORT FloatVectorOperations::clear(fParamBuffers, FluidSynthParametersMax); carla_fill(fCurMidiProgs, MAX_MIDI_CHANNELS, 0); -#endif // create settings fSettings = new_fluid_settings(); - CARLA_ASSERT(fSettings != nullptr); + CARLA_SAFE_ASSERT_RETURN(fSettings != nullptr,); // define settings fluid_settings_setint(fSettings, "synth.audio-channels", use16Outs ? 16 : 1); fluid_settings_setint(fSettings, "synth.audio-groups", use16Outs ? 16 : 1); fluid_settings_setnum(fSettings, "synth.sample-rate", pData->engine->getSampleRate()); - fluid_settings_setint(fSettings, "synth.threadsafe-api ", 0); + //fluid_settings_setnum(fSettings, "synth.cpu-cores", 2); + fluid_settings_setint(fSettings, "synth.parallel-render", 1); + fluid_settings_setint(fSettings, "synth.threadsafe-api", 0); // create synth fSynth = new_fluid_synth(fSettings); - CARLA_ASSERT(fSynth != nullptr); + CARLA_SAFE_ASSERT_RETURN(fSynth != nullptr,); #ifdef FLUIDSYNTH_VERSION_NEW_API fluid_synth_set_sample_rate(fSynth, pData->engine->getSampleRate()); #endif // set default values - fluid_synth_set_reverb_on(fSynth, 0); + fluid_synth_set_reverb_on(fSynth, 1); fluid_synth_set_reverb(fSynth, FLUID_REVERB_DEFAULT_ROOMSIZE, FLUID_REVERB_DEFAULT_DAMP, FLUID_REVERB_DEFAULT_WIDTH, FLUID_REVERB_DEFAULT_LEVEL); - fluid_synth_set_chorus_on(fSynth, 0); + fluid_synth_set_chorus_on(fSynth, 1); fluid_synth_set_chorus(fSynth, FLUID_CHORUS_DEFAULT_N, FLUID_CHORUS_DEFAULT_LEVEL, FLUID_CHORUS_DEFAULT_SPEED, FLUID_CHORUS_DEFAULT_DEPTH, FLUID_CHORUS_DEFAULT_TYPE); fluid_synth_set_polyphony(fSynth, FLUID_DEFAULT_POLYPHONY); @@ -103,8 +99,17 @@ public: pData->active = false; } - delete_fluid_synth(fSynth); - delete_fluid_settings(fSettings); + if (fSynth != nullptr) + { + delete_fluid_synth(fSynth); + fSynth = nullptr; + } + + if (fSettings != nullptr) + { + delete_fluid_settings(fSettings); + fSettings = nullptr; + } clearBuffers(); } @@ -127,7 +132,7 @@ public: uint32_t getParameterScalePointCount(const uint32_t parameterId) const override { - CARLA_ASSERT(parameterId < pData->param.count); + CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,); switch (parameterId) { @@ -163,15 +168,15 @@ public: float getParameterValue(const uint32_t parameterId) const override { - CARLA_ASSERT(parameterId < pData->param.count); + CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,); return fParamBuffers[parameterId]; } float getParameterScalePointValue(const uint32_t parameterId, const uint32_t scalePointId) const override { - CARLA_ASSERT(parameterId < pData->param.count); - CARLA_ASSERT(scalePointId < getParameterScalePointCount(parameterId)); + CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,); + CARLA_SAFE_ASSERT_RETURN(scalePointId < getParameterScalePointCount(parameterId),); switch (parameterId) { @@ -229,7 +234,7 @@ public: void getParameterName(const uint32_t parameterId, char* const strBuf) const override { - CARLA_ASSERT(parameterId < pData->param.count); + CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,); switch (parameterId) { @@ -283,7 +288,7 @@ public: void getParameterUnit(const uint32_t parameterId, char* const strBuf) const override { - CARLA_ASSERT(parameterId < pData->param.count); + CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,); switch (parameterId) { @@ -301,8 +306,8 @@ public: void getParameterScalePointLabel(const uint32_t parameterId, const uint32_t scalePointId, char* const strBuf) const override { - CARLA_ASSERT(parameterId < pData->param.count); - CARLA_ASSERT(scalePointId < getParameterScalePointCount(parameterId)); + CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,); + CARLA_SAFE_ASSERT_RETURN(scalePointId < getParameterScalePointCount(parameterId),); switch (parameterId) { @@ -342,7 +347,7 @@ public: void prepareForSave() override { - CARLA_ASSERT(fSynth != nullptr); + CARLA_SAFE_ASSERT_RETURN(fSynth != nullptr,); char strBuf[STR_MAX+1]; std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i:%i:%i:%i:%i:%i:%i:%i:%i:%i:%i:%i:%i", fCurMidiProgs[0], fCurMidiProgs[1], fCurMidiProgs[2], fCurMidiProgs[3], @@ -369,7 +374,7 @@ public: void setParameterValue(const uint32_t parameterId, const float value, const bool sendGui, const bool sendOsc, const bool sendCallback) override { - CARLA_ASSERT(parameterId < pData->param.count); + CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,); const float fixedValue(pData->param.getFixedValue(parameterId, value)); fParamBuffers[parameterId] = fixedValue; @@ -421,27 +426,18 @@ public: void setCustomData(const char* const type, const char* const key, const char* const value, const bool sendGui) override { - CARLA_ASSERT(fSynth != nullptr); - CARLA_ASSERT(type != nullptr); - CARLA_ASSERT(key != nullptr); - CARLA_ASSERT(value != nullptr); + CARLA_SAFE_ASSERT_RETURN(fSynth != nullptr,); + CARLA_SAFE_ASSERT_RETURN(type != nullptr,); + CARLA_SAFE_ASSERT_RETURN(key != nullptr,); + CARLA_SAFE_ASSERT_RETURN(value != nullptr,); carla_debug("DssiPlugin::setCustomData(%s, %s, %s, %s)", type, key, value, bool2str(sendGui)); - if (type == nullptr) - return carla_stderr2("DssiPlugin::setCustomData(\"%s\", \"%s\", \"%s\", %s) - type is invalid", type, key, value, bool2str(sendGui)); - if (std::strcmp(type, CUSTOM_DATA_STRING) != 0) return carla_stderr2("DssiPlugin::setCustomData(\"%s\", \"%s\", \"%s\", %s) - type is not string", type, key, value, bool2str(sendGui)); - if (key == nullptr) - return carla_stderr2("DssiPlugin::setCustomData(\"%s\", \"%s\", \"%s\", %s) - key is null", type, key, value, bool2str(sendGui)); - if (std::strcmp(key, "midiPrograms") != 0) return carla_stderr2("DssiPlugin::setCustomData(\"%s\", \"%s\", \"%s\", %s) - type is not string", type, key, value, bool2str(sendGui)); - if (value == nullptr) - return carla_stderr2("DssiPlugin::setCustomData(\"%s\", \"%s\", \"%s\", %s) - value is null", type, key, value, bool2str(sendGui)); - // QStringList midiProgramList(QString(value).split(":", QString::SkipEmptyParts)); // // if (midiProgramList.count() == MAX_MIDI_CHANNELS) @@ -646,12 +642,12 @@ public: pData->param.data[j].index = j; pData->param.data[j].rindex = j; pData->param.data[j].type = PARAMETER_INPUT; - pData->param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_AUTOMABLE | PARAMETER_IS_BOOLEAN; + pData->param.data[j].hints = PARAMETER_IS_ENABLED /*| PARAMETER_IS_AUTOMABLE*/ | PARAMETER_IS_BOOLEAN; pData->param.data[j].midiChannel = 0; pData->param.data[j].midiCC = -1; pData->param.ranges[j].min = 0.0f; pData->param.ranges[j].max = 1.0f; - pData->param.ranges[j].def = 0.0f; // off + pData->param.ranges[j].def = 1.0f; pData->param.ranges[j].step = 1.0f; pData->param.ranges[j].stepSmall = 1.0f; pData->param.ranges[j].stepLarge = 1.0f; @@ -662,7 +658,7 @@ public: pData->param.data[j].index = j; pData->param.data[j].rindex = j; pData->param.data[j].type = PARAMETER_INPUT; - pData->param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_AUTOMABLE; + pData->param.data[j].hints = PARAMETER_IS_ENABLED /*| PARAMETER_IS_AUTOMABLE*/; pData->param.data[j].midiChannel = 0; pData->param.data[j].midiCC = -1; pData->param.ranges[j].min = 0.0f; @@ -678,7 +674,7 @@ public: pData->param.data[j].index = j; pData->param.data[j].rindex = j; pData->param.data[j].type = PARAMETER_INPUT; - pData->param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_AUTOMABLE; + pData->param.data[j].hints = PARAMETER_IS_ENABLED /*| PARAMETER_IS_AUTOMABLE*/; pData->param.data[j].midiChannel = 0; pData->param.data[j].midiCC = -1; pData->param.ranges[j].min = 0.0f; @@ -694,7 +690,7 @@ public: pData->param.data[j].index = j; pData->param.data[j].rindex = j; pData->param.data[j].type = PARAMETER_INPUT; - pData->param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_AUTOMABLE; + pData->param.data[j].hints = PARAMETER_IS_ENABLED /*| PARAMETER_IS_AUTOMABLE*/; pData->param.data[j].midiChannel = 0; pData->param.data[j].midiCC = MIDI_CONTROL_REVERB_SEND_LEVEL; pData->param.ranges[j].min = 0.0f; @@ -710,7 +706,7 @@ public: pData->param.data[j].index = j; pData->param.data[j].rindex = j; pData->param.data[j].type = PARAMETER_INPUT; - pData->param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_AUTOMABLE; + pData->param.data[j].hints = PARAMETER_IS_ENABLED /*| PARAMETER_IS_AUTOMABLE*/; pData->param.data[j].midiChannel = 0; pData->param.data[j].midiCC = -1; pData->param.ranges[j].min = 0.0f; @@ -731,7 +727,7 @@ public: pData->param.data[j].midiCC = -1; pData->param.ranges[j].min = 0.0f; pData->param.ranges[j].max = 1.0f; - pData->param.ranges[j].def = 0.0f; // off + pData->param.ranges[j].def = 1.0f; pData->param.ranges[j].step = 1.0f; pData->param.ranges[j].stepSmall = 1.0f; pData->param.ranges[j].stepLarge = 1.0f; @@ -794,7 +790,7 @@ public: pData->param.data[j].midiChannel = 0; pData->param.data[j].midiCC = -1; pData->param.ranges[j].min = 0.0f; - pData->param.ranges[j].max = 2048000.0 / pData->engine->getSampleRate(); + pData->param.ranges[j].max = 2048.0 * 1000.0 / pData->engine->getSampleRate(); // FIXME? pData->param.ranges[j].def = FLUID_CHORUS_DEFAULT_DEPTH; pData->param.ranges[j].step = 0.01f; pData->param.ranges[j].stepSmall = 0.0001f; @@ -869,7 +865,7 @@ public: // plugin hints fHints = 0x0; - //fHints |= PLUGIN_IS_SYNTH; + fHints |= PLUGIN_IS_SYNTH; fHints |= PLUGIN_CAN_VOLUME; fHints |= PLUGIN_CAN_BALANCE; @@ -1351,13 +1347,8 @@ public: bool processSingle(float** const outBuffer, const uint32_t frames, const uint32_t timeOffset) { - CARLA_ASSERT(outBuffer != nullptr); - CARLA_ASSERT(frames > 0); - - if (outBuffer == nullptr) - return false; - if (frames == 0) - return false; + CARLA_SAFE_ASSERT_RETURN(outBuffer != nullptr, false); + CARLA_SAFE_ASSERT_RETURN(frames > 0, false); uint32_t i, k; diff --git a/source/widgets/canvaspreviewframe.py b/source/widgets/canvaspreviewframe.py index 3d868da44..6c3666695 100644 --- a/source/widgets/canvaspreviewframe.py +++ b/source/widgets/canvaspreviewframe.py @@ -20,9 +20,13 @@ # Imports (Global) # TODO - SIGNAL, SLOT -from PyQt5.QtCore import Qt, QRectF, QTimer -from PyQt5.QtGui import QBrush, QColor, QCursor, QPainter, QPen -from PyQt5.QtWidgets import QFrame +try: + from PyQt4.QtCore import Qt, QRectF, QTimer + from PyQt4.QtGui import QBrush, QColor, QCursor, QFrame, QPainter, QPen +except: + from PyQt5.QtCore import Qt, QRectF, QTimer + from PyQt5.QtGui import QBrush, QColor, QCursor, QPainter, QPen + from PyQt5.QtWidgets import QFrame # ------------------------------------------------------------------------------------------------------------ # Static Variables