| @@ -798,6 +798,24 @@ protected: | |||
| // context->history->setSaved(); | |||
| #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 | |||
| try { | |||
| data = rack::system::archiveDirectory(fAutosavePath, 1); | |||
| @@ -813,7 +831,7 @@ protected: | |||
| #if CARDINAL_VARIANT_MINI | |||
| if (std::strcmp(key, "param") == 0) | |||
| { | |||
| longlong moduleId = 0; | |||
| long long moduleId = 0; | |||
| int paramId = 0; | |||
| float paramValue = 0.f; | |||
| std::sscanf(value, "%lld:%d:%f", &moduleId, ¶mId, ¶mValue); | |||
| @@ -886,13 +904,13 @@ protected: | |||
| return; | |||
| #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::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); | |||
| #else | |||
| const std::vector<uint8_t> data(d_getChunkFromBase64String(value)); | |||
| @@ -924,6 +942,8 @@ protected: | |||
| try { | |||
| context->patch->loadAutosave(); | |||
| } catch(const rack::Exception& e) { | |||
| d_stderr(e.what()); | |||
| } DISTRHO_SAFE_EXCEPTION_RETURN("setState loadAutosave",); | |||
| // context->history->setSaved(); | |||
| @@ -139,7 +139,7 @@ void sendParamChangeToRemote(RemoteDetails* const remote, int64_t moduleId, int | |||
| { | |||
| #if CARDINAL_VARIANT_MINI | |||
| 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); | |||
| #elif defined(HAVE_LIBLO) | |||
| 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; | |||
| #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) | |||
| try { | |||
| data = archiveDirectory(context->patch->autosavePath, 1); | |||
| @@ -826,34 +826,21 @@ protected: | |||
| if (fAutosavePath.empty()) | |||
| return; | |||
| const std::vector<uint8_t> data(d_getChunkFromBase64String(value)); | |||
| DISTRHO_SAFE_ASSERT_RETURN(data.size() >= 4,); | |||
| rack::system::removeRecursively(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); | |||
| try { | |||
| context->patch->loadAutosave(); | |||
| } catch(const rack::Exception& e) { | |||
| d_stderr(e.what()); | |||
| } DISTRHO_SAFE_EXCEPTION_RETURN("setState loadAutosave",); | |||
| return; | |||
| @@ -356,6 +356,10 @@ BUILD_CXX_FLAGS += -std=gnu++17 | |||
| 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 | |||
| BUILD_CXX_FLAGS += -U_GLIBCXX_ASSERTIONS -Wp,-U_GLIBCXX_ASSERTIONS | |||