Merge branch 'main' into update/DrumKit

This commit is contained in:
dreamer 2024-09-22 03:21:51 +02:00
commit 208d79fae5
21 changed files with 104 additions and 90 deletions

View file

@ -5,7 +5,7 @@ body:
id: version id: version
attributes: attributes:
label: Version label: Version
value: "24.05" value: "24.09"
validations: validations:
required: true required: true
- type: dropdown - type: dropdown

View file

@ -15,7 +15,7 @@ include $(ROOT)/Makefile.base.mk
# src/CardinalPlugin.cpp `getVersion` # src/CardinalPlugin.cpp `getVersion`
# utils/macOS/Info_{JACK,Native}.plist # utils/macOS/Info_{JACK,Native}.plist
# .github/ISSUE_TEMPLATE/bug.yaml src/CardinalCommon.cpp src/CardinalPlugin.cpp utils/macOS/Info_{JACK,Native}.plist # .github/ISSUE_TEMPLATE/bug.yaml src/CardinalCommon.cpp src/CardinalPlugin.cpp utils/macOS/Info_{JACK,Native}.plist
VERSION = 24.05 VERSION = 24.09
# -------------------------------------------------------------- # --------------------------------------------------------------
# Build targets # Build targets

2
carla

@ -1 +1 @@
Subproject commit c37d53a4216654118e711fa41e88e7e801d5bd9b Subproject commit e39f04d2d8587327e741ad881617c427f5014d48

3
deps/Makefile vendored
View file

@ -78,6 +78,9 @@ export MACOSX_DEPLOYMENT_TARGET = $(subst -mmacosx-version-min=,,$(filter -mmaco
CMAKE += -DCMAKE_OSX_DEPLOYMENT_TARGET=$(MACOSX_DEPLOYMENT_TARGET) CMAKE += -DCMAKE_OSX_DEPLOYMENT_TARGET=$(MACOSX_DEPLOYMENT_TARGET)
else ifeq ($(CIBUILD),true) else ifeq ($(CIBUILD),true)
$(error CI build requires -mmacosx-version-min flag on macOS) $(error CI build requires -mmacosx-version-min flag on macOS)
else
export MACOSX_DEPLOYMENT_TARGET = 10.15
CMAKE += -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15
endif endif
CMAKE += -DCMAKE_OSX_SYSROOT="macosx" CMAKE += -DCMAKE_OSX_SYSROOT="macosx"
endif endif

View file

@ -6,12 +6,12 @@ While Cardinal itself is licensed under GPLv3+, some modules/plugins used by it
And since Cardinal builds the entire Rack and modules as a static library, And since Cardinal builds the entire Rack and modules as a static library,
the more restrictive of the **code licenses** will apply to the final binary. the more restrictive of the **code licenses** will apply to the final binary.
Bellow follows a list of all code licenses used in Cardinal and linked submodules. Below follows a list of all code licenses used in Cardinal and linked submodules.
| Name | License(s) | Additional notes | | Name | License(s) | Additional notes |
|-------------------------|--------------------------|------------------| |-------------------------|--------------------------|------------------|
| Carla | GPL-2.0-or-later | Used as plugin host within Cardinal | | Carla | GPL-2.0-or-later | Used as plugin host within Cardinal |
| DPF | ISC, GPL-2.0-or-later | Used as the plugin framework, VST2 binary GPLv2+ licensed | | DPF | ISC | Used as the plugin framework |
| Rack | GPL-3.0-or-later | The actual Rack code, internal dependencies are compatible with GPLv3+ | | Rack | GPL-3.0-or-later | The actual Rack code, internal dependencies are compatible with GPLv3+ |
| 21kHz | MIT | | | 21kHz | MIT | |
| 8Mode | BSD-3-Clause | | | 8Mode | BSD-3-Clause | |

2
dpf

@ -1 +1 @@
Subproject commit 470c5b7a77091bbea2154cd1d96d3cb1be737aa3 Subproject commit 5446300eac8f0480d6b2a2967d7dec2f227fe1bd

@ -1 +1 @@
Subproject commit d3ad6c6732cee8a80197aa351dd9efef9c278d4c Subproject commit b24e1c373c7c54871d33247d40216e311dc00849

View file

@ -551,7 +551,7 @@ MINIPLUGIN_FILES += BaconPlugs/src/Style.cpp
# -------------------------------------------------------------- # --------------------------------------------------------------
# Befaco # Befaco
PLUGIN_FILES += $(filter-out Befaco/src/plugin.cpp,$(wildcard Befaco/src/*.cpp)) PLUGIN_FILES += $(filter-out Befaco/src/plugin.cpp Befaco/src/MidiThing.cpp,$(wildcard Befaco/src/*.cpp))
PLUGIN_FILES += $(wildcard Befaco/src/noise-plethora/*/*.cpp) PLUGIN_FILES += $(wildcard Befaco/src/noise-plethora/*/*.cpp)
# modules/types which are present in other plugins # modules/types which are present in other plugins

@ -1 +1 @@
Subproject commit 5232180a0e1be52cb87dedc5c7637684cbf9bd23 Subproject commit ccca9e17a75798746feef177fb6fb63325bcd80b

View file

@ -1590,9 +1590,13 @@ static void initStatic__Befaco()
p->addModel(modelMotionMTR); p->addModel(modelMotionMTR);
p->addModel(modelBurst); p->addModel(modelBurst);
p->addModel(modelVoltio); p->addModel(modelVoltio);
p->addModel(modelOctaves);
#undef modelADSR #undef modelADSR
#undef modelMixer #undef modelMixer
#undef modelBurst #undef modelBurst
// NOTE disabled in Cardinal due to MIDI usage
spl.removeModule("MidiThingV2");
} }
} }
@ -3083,7 +3087,9 @@ static void initStatic__Sapphire()
p->addModel(modelSapphireNucleus); p->addModel(modelSapphireNucleus);
p->addModel(modelSapphirePivot); p->addModel(modelSapphirePivot);
p->addModel(modelSapphirePolynucleus); p->addModel(modelSapphirePolynucleus);
p->addModel(modelSapphirePop);
p->addModel(modelSapphireRotini); p->addModel(modelSapphireRotini);
p->addModel(modelSapphireSam);
p->addModel(modelSapphireTin); p->addModel(modelSapphireTin);
p->addModel(modelSapphireTout); p->addModel(modelSapphireTout);
p->addModel(modelSapphireTricorder); p->addModel(modelSapphireTricorder);

View file

@ -99,7 +99,7 @@ void destroyStaticPlugins();
} }
} }
const std::string CARDINAL_VERSION = "24.05"; const std::string CARDINAL_VERSION = "24.09";
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
@ -362,6 +362,15 @@ static int osc_hello_handler(const char*, const char*, lo_arg**, int, const lo_m
d_stdout("Hello received from OSC, saying hello back to them o/"); d_stdout("Hello received from OSC, saying hello back to them o/");
const lo_address source = lo_message_get_source(m); const lo_address source = lo_message_get_source(m);
const lo_server server = static_cast<Initializer*>(self)->oscServer; const lo_server server = static_cast<Initializer*>(self)->oscServer;
// send list of features first
#ifdef CARDINAL_INIT_OSC_THREAD
lo_send_from(source, server, LO_TT_IMMEDIATE, "/resp", "ss", "features", ":screenshot:");
#else
lo_send_from(source, server, LO_TT_IMMEDIATE, "/resp", "ss", "features", "");
#endif
// then finally hello reply
lo_send_from(source, server, LO_TT_IMMEDIATE, "/resp", "ss", "hello", "ok"); lo_send_from(source, server, LO_TT_IMMEDIATE, "/resp", "ss", "hello", "ok");
return 0; return 0;
} }
@ -386,7 +395,10 @@ static int osc_load_handler(const char*, const char* types, lo_arg** argv, int a
std::vector<uint8_t> data(size); std::vector<uint8_t> data(size);
std::memcpy(data.data(), blob, size); std::memcpy(data.data(), blob, size);
#ifdef CARDINAL_INIT_OSC_THREAD
rack::contextSet(context); rack::contextSet(context);
#endif
rack::system::removeRecursively(context->patch->autosavePath); rack::system::removeRecursively(context->patch->autosavePath);
rack::system::createDirectories(context->patch->autosavePath); rack::system::createDirectories(context->patch->autosavePath);
try { try {
@ -397,7 +409,10 @@ static int osc_load_handler(const char*, const char* types, lo_arg** argv, int a
catch (rack::Exception& e) { catch (rack::Exception& e) {
WARN("%s", e.what()); WARN("%s", e.what());
} }
#ifdef CARDINAL_INIT_OSC_THREAD
rack::contextSet(nullptr); rack::contextSet(nullptr);
#endif
} }
const lo_address source = lo_message_get_source(m); const lo_address source = lo_message_get_source(m);
@ -423,10 +438,18 @@ static int osc_param_handler(const char*, const char* types, lo_arg** argv, int
const int paramId = argv[1]->i; const int paramId = argv[1]->i;
const float paramValue = argv[2]->f; const float paramValue = argv[2]->f;
#ifdef CARDINAL_INIT_OSC_THREAD
rack::contextSet(context);
#endif
rack::engine::Module* const module = context->engine->getModule(moduleId); rack::engine::Module* const module = context->engine->getModule(moduleId);
DISTRHO_SAFE_ASSERT_RETURN(module != nullptr, 0); DISTRHO_SAFE_ASSERT_RETURN(module != nullptr, 0);
context->engine->setParamValue(module, paramId, paramValue); context->engine->setParamValue(module, paramId, paramValue);
#ifdef CARDINAL_INIT_OSC_THREAD
rack::contextSet(nullptr);
#endif
} }
return 0; return 0;

View file

@ -414,7 +414,7 @@ protected:
uint32_t getVersion() const override uint32_t getVersion() const override
{ {
return d_version(0, 24, 5); return d_version(0, 24, 9);
} }
int64_t getUniqueId() const override int64_t getUniqueId() const override

View file

@ -1,18 +1,7 @@
/* /*
* DISTRHO Cardinal Plugin * DISTRHO Cardinal Plugin
* Copyright (C) 2021-2024 Filipe Coelho <falktx@falktx.com> * Copyright (C) 2021-2024 Filipe Coelho <falktx@falktx.com>
* * SPDX-License-Identifier: GPL-3.0-or-later
* 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 3 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 LICENSE file.
*/ */
#include <engine/Engine.hpp> #include <engine/Engine.hpp>
@ -40,6 +29,12 @@
# include <lo/lo.h> # include <lo/lo.h>
#endif #endif
namespace rack {
namespace engine {
void Engine_setRemoteDetails(Engine*, remoteUtils::RemoteDetails*);
}
}
// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
namespace remoteUtils { namespace remoteUtils {
@ -53,8 +48,15 @@ static int osc_handler(const char* const path, const char* const types, lo_arg**
{ {
d_stdout("osc_handler(\"%s\", ...) - got resp | '%s' '%s'", path, &argv[0]->s, &argv[1]->s); d_stdout("osc_handler(\"%s\", ...) - got resp | '%s' '%s'", path, &argv[0]->s, &argv[1]->s);
if (std::strcmp(&argv[0]->s, "hello") == 0 && std::strcmp(&argv[1]->s, "ok") == 0) if (std::strcmp(&argv[0]->s, "hello") == 0)
static_cast<RemoteDetails*>(self)->connected = true; {
if (std::strcmp(&argv[1]->s, "ok") == 0)
static_cast<RemoteDetails*>(self)->connected = true;
}
else if (std::strcmp(&argv[0]->s, "features") == 0)
{
static_cast<RemoteDetails*>(self)->screenshot = std::strstr(&argv[1]->s, ":screenshot:") != nullptr;
}
} }
return 0; return 0;
} }
@ -92,8 +94,10 @@ bool connectToRemote(const char* const url)
ui->remoteDetails = remoteDetails = new RemoteDetails; ui->remoteDetails = remoteDetails = new RemoteDetails;
remoteDetails->handle = ui; remoteDetails->handle = ui;
remoteDetails->url = strdup(url); remoteDetails->url = strdup(url);
remoteDetails->connected = true;
remoteDetails->autoDeploy = true; remoteDetails->autoDeploy = true;
remoteDetails->connected = true;
remoteDetails->first = false;
remoteDetails->screenshot = false;
} }
#elif defined(HAVE_LIBLO) #elif defined(HAVE_LIBLO)
const lo_address addr = lo_address_new_from_url(url); const lo_address addr = lo_address_new_from_url(url);
@ -107,10 +111,16 @@ bool connectToRemote(const char* const url)
ui->remoteDetails = remoteDetails = new RemoteDetails; ui->remoteDetails = remoteDetails = new RemoteDetails;
remoteDetails->handle = oscServer; remoteDetails->handle = oscServer;
remoteDetails->url = strdup(url); remoteDetails->url = strdup(url);
remoteDetails->autoDeploy = true;
remoteDetails->first = true;
remoteDetails->connected = false; remoteDetails->connected = false;
remoteDetails->autoDeploy = false; remoteDetails->screenshot = false;
lo_server_add_method(oscServer, "/resp", nullptr, osc_handler, remoteDetails); lo_server_add_method(oscServer, "/resp", nullptr, osc_handler, remoteDetails);
sendFullPatchToRemote(remoteDetails);
Engine_setRemoteDetails(context->engine, remoteDetails);
} }
else if (std::strcmp(remoteDetails->url, url) != 0) else if (std::strcmp(remoteDetails->url, url) != 0)
{ {

View file

@ -1,18 +1,7 @@
/* /*
* DISTRHO Cardinal Plugin * DISTRHO Cardinal Plugin
* Copyright (C) 2021-2023 Filipe Coelho <falktx@falktx.com> * Copyright (C) 2021-2024 Filipe Coelho <falktx@falktx.com>
* * SPDX-License-Identifier: GPL-3.0-or-later
* 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 3 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 LICENSE file.
*/ */
#pragma once #pragma once
@ -27,8 +16,10 @@ namespace remoteUtils {
struct RemoteDetails { struct RemoteDetails {
void* handle; void* handle;
const char* url; const char* url;
bool connected;
bool autoDeploy; bool autoDeploy;
bool first;
bool connected;
bool screenshot;
}; };
RemoteDetails* getRemote(); RemoteDetails* getRemote();

View file

@ -1041,7 +1041,7 @@ protected:
if (inSelfTest) return false; if (inSelfTest) return false;
#endif #endif
const rack::math::Vec scrollDelta = rack::math::Vec(-ev.delta.getX(), ev.delta.getY()); const rack::math::Vec scrollDelta = rack::math::Vec(-ev.delta.getX(), ev.delta.getY()) * 50 ;
const int mods = glfwMods(ev.mod); const int mods = glfwMods(ev.mod);
const ScopedContext sc(this, mods); const ScopedContext sc(this, mods);

View file

@ -464,6 +464,7 @@ static const struct {
{ kModeBefaco, "/Befaco/res/panels/SpringReverb.svg" }, { kModeBefaco, "/Befaco/res/panels/SpringReverb.svg" },
{ kModeBefaco, "/Befaco/res/panels/StereoStrip.svg" }, { kModeBefaco, "/Befaco/res/panels/StereoStrip.svg" },
{ kModeBefaco, "/Befaco/res/panels/Voltio.svg" }, { kModeBefaco, "/Befaco/res/panels/Voltio.svg" },
{ kModeBefaco, "/Befaco/res/panels/Octaves.svg" },
// GPLv3+ // GPLv3+
{ kModeCardinal, "/Cardinal/res/AudioFile.svg" }, { kModeCardinal, "/Cardinal/res/AudioFile.svg" },
{ kModeCardinal, "/Cardinal/res/AudioToCVPitch.svg" }, { kModeCardinal, "/Cardinal/res/AudioToCVPitch.svg" },

View file

@ -1,18 +1,7 @@
/* /*
* DISTRHO Cardinal Plugin * DISTRHO Cardinal Plugin
* Copyright (C) 2021-2023 Filipe Coelho <falktx@falktx.com> * Copyright (C) 2021-2024 Filipe Coelho <falktx@falktx.com>
* * SPDX-License-Identifier: GPL-3.0-or-later
* 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 3 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 LICENSE file.
*/ */
/** /**
@ -295,7 +284,7 @@ static void Engine_stepFrame(Engine* that) {
Param* smoothParam = &smoothModule->params[smoothParamId]; Param* smoothParam = &smoothModule->params[smoothParamId];
float value = smoothParam->value; float value = smoothParam->value;
float newValue; float newValue;
if (internal->remoteDetails != nullptr) { if (internal->remoteDetails != nullptr && internal->remoteDetails->connected) {
newValue = value; newValue = value;
sendParamChangeToRemote(internal->remoteDetails, smoothModule->id, smoothParamId, value); sendParamChangeToRemote(internal->remoteDetails, smoothModule->id, smoothParamId, value);
} else { } else {
@ -1094,7 +1083,7 @@ void Engine::setParamValue(Module* module, int paramId, float value) {
internal->smoothModule = NULL; internal->smoothModule = NULL;
internal->smoothParamId = 0; internal->smoothParamId = 0;
} }
if (internal->remoteDetails != nullptr) { if (internal->remoteDetails != nullptr && internal->remoteDetails->connected) {
sendParamChangeToRemote(internal->remoteDetails, module->id, paramId, value); sendParamChangeToRemote(internal->remoteDetails, module->id, paramId, value);
} }
module->params[paramId].setValue(value); module->params[paramId].setValue(value);

View file

@ -1,18 +1,7 @@
/* /*
* DISTRHO Cardinal Plugin * DISTRHO Cardinal Plugin
* Copyright (C) 2021-2023 Filipe Coelho <falktx@falktx.com> * Copyright (C) 2021-2024 Filipe Coelho <falktx@falktx.com>
* * SPDX-License-Identifier: GPL-3.0-or-later
* 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 3 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 LICENSE file.
*/ */
/** /**
@ -207,14 +196,19 @@ void Scene::step() {
if (remoteUtils::RemoteDetails* const remoteDetails = remoteUtils::getRemote()) { if (remoteUtils::RemoteDetails* const remoteDetails = remoteUtils::getRemote()) {
idleRemote(remoteDetails); idleRemote(remoteDetails);
if (remoteDetails->autoDeploy) { if (remoteDetails->autoDeploy && remoteDetails->connected) {
const int actionIndex = APP->history->actionIndex; const int actionIndex = APP->history->actionIndex;
const double time = system::getTime(); const double time = system::getTime();
if (internal->historyActionIndex == -1) { if (internal->historyActionIndex == -1) {
internal->historyActionIndex = actionIndex; internal->historyActionIndex = actionIndex;
internal->lastSceneChangeTime = time; internal->lastSceneChangeTime = time;
} else if (internal->historyActionIndex != actionIndex && actionIndex > 0 && time - internal->lastSceneChangeTime >= 1.0) { } else if (remoteDetails->first ||
(internal->historyActionIndex != actionIndex
&& actionIndex > 0
&& time - internal->lastSceneChangeTime >= 1.0)) {
remoteDetails->first = false;
const std::string& name(APP->history->actions[actionIndex - 1]->name); const std::string& name(APP->history->actions[actionIndex - 1]->name);
static const std::vector<std::string> ignoredNames = { static const std::vector<std::string> ignoredNames = {
"move knob", "move knob",
@ -224,7 +218,10 @@ void Scene::step() {
if (std::find(ignoredNames.cbegin(), ignoredNames.cend(), name) == ignoredNames.cend()) { if (std::find(ignoredNames.cbegin(), ignoredNames.cend(), name) == ignoredNames.cend()) {
printf("action '%s'\n", APP->history->actions[actionIndex - 1]->name.c_str()); printf("action '%s'\n", APP->history->actions[actionIndex - 1]->name.c_str());
remoteUtils::sendFullPatchToRemote(remoteDetails); remoteUtils::sendFullPatchToRemote(remoteDetails);
window::generateScreenshot();
if (remoteDetails->screenshot) {
window::generateScreenshot();
}
} }
internal->historyActionIndex = actionIndex; internal->historyActionIndex = actionIndex;
internal->lastSceneChangeTime = time; internal->lastSceneChangeTime = time;
@ -334,8 +331,13 @@ void Scene::onHoverKey(const HoverKeyEvent& e) {
if (e.key == GLFW_KEY_F7 && (e.mods & RACK_MOD_MASK) == 0) { if (e.key == GLFW_KEY_F7 && (e.mods & RACK_MOD_MASK) == 0) {
if (remoteUtils::RemoteDetails* const remoteDetails = remoteUtils::getRemote()) if (remoteUtils::RemoteDetails* const remoteDetails = remoteUtils::getRemote())
{ {
remoteUtils::sendFullPatchToRemote(remoteDetails); if (remoteDetails->connected) {
window::generateScreenshot(); remoteUtils::sendFullPatchToRemote(remoteDetails);
if (remoteDetails->screenshot) {
window::generateScreenshot();
}
}
} }
e.consume(this); e.consume(this);
} }

View file

@ -1,18 +1,7 @@
/* /*
* DISTRHO Cardinal Plugin * DISTRHO Cardinal Plugin
* Copyright (C) 2021-2024 Filipe Coelho <falktx@falktx.com> * Copyright (C) 2021-2024 Filipe Coelho <falktx@falktx.com>
* * SPDX-License-Identifier: GPL-3.0-or-later
* 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 3 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 LICENSE file.
*/ */
/** /**
@ -598,7 +587,7 @@ static void Window__writeImagePNG(void* context, void* data, int size) {
CardinalBaseUI* const ui = static_cast<CardinalBaseUI*>(context); CardinalBaseUI* const ui = static_cast<CardinalBaseUI*>(context);
if (char* const screenshot = String::asBase64(data, size).getAndReleaseBuffer()) { if (char* const screenshot = String::asBase64(data, size).getAndReleaseBuffer()) {
ui->setState("screenshot", screenshot); ui->setState("screenshot", screenshot);
if (ui->remoteDetails != nullptr) if (ui->remoteDetails != nullptr && ui->remoteDetails->connected && ui->remoteDetails->screenshot)
remoteUtils::sendScreenshotToRemote(ui->remoteDetails, screenshot); remoteUtils::sendScreenshotToRemote(ui->remoteDetails, screenshot);
std::free(screenshot); std::free(screenshot);
} }

View file

@ -11,7 +11,7 @@
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
<string>studio.kx.distrho.cardinal.jack</string> <string>studio.kx.distrho.cardinal.jack</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>24.05</string> <string>24.09</string>
<key>LSMinimumSystemVersion</key> <key>LSMinimumSystemVersion</key>
<string>10.15</string> <string>10.15</string>
<key>NSHumanReadableCopyright</key> <key>NSHumanReadableCopyright</key>

View file

@ -11,7 +11,7 @@
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
<string>studio.kx.distrho.cardinal.native</string> <string>studio.kx.distrho.cardinal.native</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>24.05</string> <string>24.09</string>
<key>LSMinimumSystemVersion</key> <key>LSMinimumSystemVersion</key>
<string>10.15</string> <string>10.15</string>
<key>NSHumanReadableCopyright</key> <key>NSHumanReadableCopyright</key>