| @@ -798,6 +798,24 @@ protected: | |||||
| // context->history->setSaved(); | // context->history->setSaved(); | ||||
| #if CARDINAL_VARIANT_MINI | #if CARDINAL_VARIANT_MINI | ||||
| FILE* const f = std::fopen(join(context->patch->autosavePath, "patch.json").c_str(), "r"); | |||||
| DISTRHO_SAFE_ASSERT_RETURN(f != nullptr, String()); | |||||
| DEFER({ | |||||
| std::fclose(f); | |||||
| }); | |||||
| std::fseek(f, 0, SEEK_END); | |||||
| const long fileSize = std::ftell(f); | |||||
| DISTRHO_SAFE_ASSERT_RETURN(fileSize > 0, String()); | |||||
| std::fseek(f, 0, SEEK_SET); | |||||
| char* const fileContent = static_cast<char*>(std::malloc(fileSize+1)); | |||||
| DISTRHO_SAFE_ASSERT_RETURN(std::fread(fileContent, fileSize, 1, f) == 1, String()); | |||||
| fileContent[fileSize] = '\0'; | |||||
| return String(fileContent, false); | |||||
| #else | #else | ||||
| try { | try { | ||||
| data = rack::system::archiveDirectory(fAutosavePath, 1); | data = rack::system::archiveDirectory(fAutosavePath, 1); | ||||
| @@ -813,7 +831,7 @@ protected: | |||||
| #if CARDINAL_VARIANT_MINI | #if CARDINAL_VARIANT_MINI | ||||
| if (std::strcmp(key, "param") == 0) | if (std::strcmp(key, "param") == 0) | ||||
| { | { | ||||
| longlong moduleId = 0; | |||||
| long long moduleId = 0; | |||||
| int paramId = 0; | int paramId = 0; | ||||
| float paramValue = 0.f; | float paramValue = 0.f; | ||||
| std::sscanf(value, "%lld:%d:%f", &moduleId, ¶mId, ¶mValue); | std::sscanf(value, "%lld:%d:%f", &moduleId, ¶mId, ¶mValue); | ||||
| @@ -886,13 +904,13 @@ protected: | |||||
| return; | return; | ||||
| #if CARDINAL_VARIANT_MINI | #if CARDINAL_VARIANT_MINI | ||||
| FILE* const f = std::fopen(rack::system::join(fAutosavePath, "patch.json").c_str(), "w"); | |||||
| DISTRHO_SAFE_ASSERT_RETURN(f != nullptr,); | |||||
| rack::system::removeRecursively(fAutosavePath); | rack::system::removeRecursively(fAutosavePath); | ||||
| rack::system::createDirectories(fAutosavePath); | rack::system::createDirectories(fAutosavePath); | ||||
| std::fwrite(value, std::strlen(value)+1, 1, f); | |||||
| FILE* const f = std::fopen(rack::system::join(fAutosavePath, "patch.json").c_str(), "w"); | |||||
| DISTRHO_SAFE_ASSERT_RETURN(f != nullptr,); | |||||
| std::fwrite(value, std::strlen(value), 1, f); | |||||
| std::fclose(f); | std::fclose(f); | ||||
| #else | #else | ||||
| const std::vector<uint8_t> data(d_getChunkFromBase64String(value)); | const std::vector<uint8_t> data(d_getChunkFromBase64String(value)); | ||||
| @@ -924,6 +942,8 @@ protected: | |||||
| try { | try { | ||||
| context->patch->loadAutosave(); | context->patch->loadAutosave(); | ||||
| } catch(const rack::Exception& e) { | |||||
| d_stderr(e.what()); | |||||
| } DISTRHO_SAFE_EXCEPTION_RETURN("setState loadAutosave",); | } DISTRHO_SAFE_EXCEPTION_RETURN("setState loadAutosave",); | ||||
| // context->history->setSaved(); | // context->history->setSaved(); | ||||
| @@ -139,7 +139,7 @@ void sendParamChangeToRemote(RemoteDetails* const remote, int64_t moduleId, int | |||||
| { | { | ||||
| #if CARDINAL_VARIANT_MINI | #if CARDINAL_VARIANT_MINI | ||||
| char paramBuf[512] = {}; | char paramBuf[512] = {}; | ||||
| std::snprintf(paramBuf, sizeof(paramBuf), "%llu:%d:%f", (ulonglong)moduleId, paramId, value); | |||||
| std::snprintf(paramBuf, sizeof(paramBuf), "%lld:%d:%f", (long long)moduleId, paramId, value); | |||||
| static_cast<CardinalBaseUI*>(remote->handle)->setState("param", paramBuf); | static_cast<CardinalBaseUI*>(remote->handle)->setState("param", paramBuf); | ||||
| #elif defined(HAVE_LIBLO) | #elif defined(HAVE_LIBLO) | ||||
| const lo_address addr = lo_address_new_with_proto(LO_UDP, REMOTE_HOST, CARDINAL_DEFAULT_REMOTE_HOST_PORT); | const lo_address addr = lo_address_new_with_proto(LO_UDP, REMOTE_HOST, CARDINAL_DEFAULT_REMOTE_HOST_PORT); | ||||
| @@ -164,11 +164,24 @@ void sendFullPatchToRemote(RemoteDetails* const remote) | |||||
| using namespace rack::system; | using namespace rack::system; | ||||
| #if CARDINAL_VARIANT_MINI | #if CARDINAL_VARIANT_MINI | ||||
| try { | |||||
| data = readFile(join(context->patch->autosavePath, "patch.json")); | |||||
| } DISTRHO_SAFE_EXCEPTION_RETURN("sendFullPatchToRemote",); | |||||
| FILE* const f = std::fopen(join(context->patch->autosavePath, "patch.json").c_str(), "r"); | |||||
| DISTRHO_SAFE_ASSERT_RETURN(f != nullptr,); | |||||
| DEFER({ | |||||
| std::fclose(f); | |||||
| }); | |||||
| std::fseek(f, 0, SEEK_END); | |||||
| const long fileSize = std::ftell(f); | |||||
| DISTRHO_SAFE_ASSERT_RETURN(fileSize > 0,); | |||||
| std::fseek(f, 0, SEEK_SET); | |||||
| char* const fileContent = new char[fileSize+1]; | |||||
| static_cast<CardinalBaseUI*>(remote->handle)->setState("patch", reinterpret_cast<const char*>(data.data())); | |||||
| DISTRHO_SAFE_ASSERT_RETURN(std::fread(fileContent, fileSize, 1, f) == 1,); | |||||
| fileContent[fileSize] = '\0'; | |||||
| static_cast<CardinalBaseUI*>(remote->handle)->setState("patch", fileContent); | |||||
| delete[] fileContent; | |||||
| #elif defined(HAVE_LIBLO) | #elif defined(HAVE_LIBLO) | ||||
| try { | try { | ||||
| data = archiveDirectory(context->patch->autosavePath, 1); | data = archiveDirectory(context->patch->autosavePath, 1); | ||||
| @@ -826,34 +826,21 @@ protected: | |||||
| if (fAutosavePath.empty()) | if (fAutosavePath.empty()) | ||||
| return; | return; | ||||
| const std::vector<uint8_t> data(d_getChunkFromBase64String(value)); | |||||
| DISTRHO_SAFE_ASSERT_RETURN(data.size() >= 4,); | |||||
| rack::system::removeRecursively(fAutosavePath); | rack::system::removeRecursively(fAutosavePath); | ||||
| rack::system::createDirectories(fAutosavePath); | rack::system::createDirectories(fAutosavePath); | ||||
| static constexpr const char zstdMagic[] = "\x28\xb5\x2f\xfd"; | |||||
| if (std::memcmp(data.data(), zstdMagic, sizeof(zstdMagic)) != 0) | |||||
| { | |||||
| FILE* const f = std::fopen(rack::system::join(fAutosavePath, "patch.json").c_str(), "w"); | |||||
| DISTRHO_SAFE_ASSERT_RETURN(f != nullptr,); | |||||
| FILE* const f = std::fopen(rack::system::join(fAutosavePath, "patch.json").c_str(), "w"); | |||||
| DISTRHO_SAFE_ASSERT_RETURN(f != nullptr,); | |||||
| std::fwrite(data.data(), data.size(), 1, f); | |||||
| std::fclose(f); | |||||
| } | |||||
| else | |||||
| { | |||||
| try { | |||||
| rack::system::unarchiveToDirectory(data, fAutosavePath); | |||||
| } DISTRHO_SAFE_EXCEPTION_RETURN("setState unarchiveToDirectory",); | |||||
| } | |||||
| std::fwrite(value, std::strlen(value), 1, f); | |||||
| std::fclose(f); | |||||
| const ScopedContext sc(this); | const ScopedContext sc(this); | ||||
| try { | try { | ||||
| context->patch->loadAutosave(); | context->patch->loadAutosave(); | ||||
| } catch(const rack::Exception& e) { | |||||
| d_stderr(e.what()); | |||||
| } DISTRHO_SAFE_EXCEPTION_RETURN("setState loadAutosave",); | } DISTRHO_SAFE_EXCEPTION_RETURN("setState loadAutosave",); | ||||
| return; | return; | ||||
| @@ -356,6 +356,10 @@ BUILD_CXX_FLAGS += -std=gnu++17 | |||||
| endif | endif | ||||
| endif | endif | ||||
| ifeq ($(CARDINAL_VARIANT),mini) | |||||
| BUILD_CXX_FLAGS += -DDISTRHO_PLUGIN_MINIMUM_BUFFER_SIZE=0xffff | |||||
| endif | |||||
| # Rack code is not tested for this flag, unset it | # Rack code is not tested for this flag, unset it | ||||
| BUILD_CXX_FLAGS += -U_GLIBCXX_ASSERTIONS -Wp,-U_GLIBCXX_ASSERTIONS | BUILD_CXX_FLAGS += -U_GLIBCXX_ASSERTIONS -Wp,-U_GLIBCXX_ASSERTIONS | ||||