Bunding of media files contained in snapshots.
This commit is contained in:
@@ -20,12 +20,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <boost/utility/string_view.hpp>
|
|
||||||
#include <boost/format.hpp>
|
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include "HtmlHelper.hpp"
|
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <map>
|
#include <map>
|
||||||
@@ -35,6 +32,9 @@
|
|||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <string_view>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
#define DECLARE_JSON_MAP(CLASSNAME) \
|
#define DECLARE_JSON_MAP(CLASSNAME) \
|
||||||
static pipedal::json_map::storage_type<CLASSNAME> jmap
|
static pipedal::json_map::storage_type<CLASSNAME> jmap
|
||||||
@@ -228,7 +228,7 @@ namespace pipedal
|
|||||||
reference(const char *name, MEMBER_TYPE CLASS::*member_pointer)
|
reference(const char *name, MEMBER_TYPE CLASS::*member_pointer)
|
||||||
{
|
{
|
||||||
return new json_member_reference<CLASS, MEMBER_TYPE>(name, member_pointer);
|
return new json_member_reference<CLASS, MEMBER_TYPE>(name, member_pointer);
|
||||||
};
|
}
|
||||||
template <typename CLASS, typename MEMBER_TYPE, typename ENUM_CONVERTER>
|
template <typename CLASS, typename MEMBER_TYPE, typename ENUM_CONVERTER>
|
||||||
static json_enum_member_reference<CLASS, MEMBER_TYPE> *
|
static json_enum_member_reference<CLASS, MEMBER_TYPE> *
|
||||||
enum_reference(
|
enum_reference(
|
||||||
@@ -237,14 +237,20 @@ namespace pipedal
|
|||||||
const ENUM_CONVERTER *converter)
|
const ENUM_CONVERTER *converter)
|
||||||
{
|
{
|
||||||
return new json_enum_member_reference<CLASS, MEMBER_TYPE>(name, member_pointer, converter);
|
return new json_enum_member_reference<CLASS, MEMBER_TYPE>(name, member_pointer, converter);
|
||||||
};
|
}
|
||||||
|
|
||||||
template <typename CLASS, typename MEMBER_TYPE>
|
template <typename CLASS, typename MEMBER_TYPE>
|
||||||
static json_conditional_member_reference<CLASS, MEMBER_TYPE> *
|
static json_conditional_member_reference<CLASS, MEMBER_TYPE> *
|
||||||
conditional_reference(const char *name, MEMBER_TYPE CLASS::*member_pointer, typename JsonConditionFunction<CLASS, MEMBER_TYPE>::Pointer condition)
|
conditional_reference(const char *name, MEMBER_TYPE CLASS::*member_pointer, typename JsonConditionFunction<CLASS, MEMBER_TYPE>::Pointer condition)
|
||||||
{
|
{
|
||||||
return new json_conditional_member_reference<CLASS, MEMBER_TYPE>(name, member_pointer, condition);
|
return new json_conditional_member_reference<CLASS, MEMBER_TYPE>(name, member_pointer, condition);
|
||||||
};
|
}
|
||||||
|
|
||||||
|
// for cases where the name is not a valid C++ identifier.
|
||||||
|
#define JSON_MAP_DICTIONARY_REFERENCE(class,name, variable) \
|
||||||
|
json_map::reference(name,&class::variable##_),
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
@@ -254,7 +260,7 @@ namespace pipedal
|
|||||||
{
|
{
|
||||||
|
|
||||||
template <class TYPE>
|
template <class TYPE>
|
||||||
static std::true_type test(decltype(TYPE::jmap) *) { return std::true_type(); };
|
static std::true_type test(decltype(TYPE::jmap) *) { return std::true_type(); }
|
||||||
|
|
||||||
template <class TYPE>
|
template <class TYPE>
|
||||||
static std::false_type test(...);
|
static std::false_type test(...);
|
||||||
@@ -268,7 +274,7 @@ namespace pipedal
|
|||||||
{
|
{
|
||||||
|
|
||||||
template <class TYPE>
|
template <class TYPE>
|
||||||
static std::true_type test() { return std::true_type(); };
|
static std::true_type test() { return std::true_type(); }
|
||||||
|
|
||||||
template <class TYPE>
|
template <class TYPE>
|
||||||
static std::false_type test(...);
|
static std::false_type test(...);
|
||||||
@@ -320,7 +326,7 @@ namespace pipedal
|
|||||||
{
|
{
|
||||||
os << text;
|
os << text;
|
||||||
}
|
}
|
||||||
using string_view = boost::string_view;
|
using string_view = std::string_view;
|
||||||
json_writer(std::ostream &os, bool compressed = true, bool allowNaN = false)
|
json_writer(std::ostream &os, bool compressed = true, bool allowNaN = false)
|
||||||
: os(os), compressed(compressed), allowNaN_(allowNaN), indent_level(0)
|
: os(os), compressed(compressed), allowNaN_(allowNaN), indent_level(0)
|
||||||
{
|
{
|
||||||
@@ -1049,6 +1055,7 @@ namespace pipedal
|
|||||||
if (peek() == ']')
|
if (peek() == ']')
|
||||||
{
|
{
|
||||||
c = get();
|
c = get();
|
||||||
|
(void)c;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
T item;
|
T item;
|
||||||
@@ -1057,6 +1064,7 @@ namespace pipedal
|
|||||||
if (peek() == ',')
|
if (peek() == ',')
|
||||||
{
|
{
|
||||||
c = get();
|
c = get();
|
||||||
|
(void)c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*value = std::move(result);
|
*value = std::move(result);
|
||||||
@@ -1068,7 +1076,7 @@ namespace pipedal
|
|||||||
{
|
{
|
||||||
|
|
||||||
template <typename TYPE, typename ARG>
|
template <typename TYPE, typename ARG>
|
||||||
static std::true_type test(decltype(json_reader(std::cin).read((ARG *)nullptr)) *v) { return std::true_type(); };
|
static std::true_type test(decltype(json_reader(std::cin).read((ARG *)nullptr)) *v) { return std::true_type(); }
|
||||||
|
|
||||||
template <typename TYPE, typename ARG>
|
template <typename TYPE, typename ARG>
|
||||||
static std::false_type test(...);
|
static std::false_type test(...);
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
#include "AlsaDriver.hpp"
|
#include "AlsaDriver.hpp"
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
using namespace pipedal;
|
using namespace pipedal;
|
||||||
|
|
||||||
@@ -213,11 +214,11 @@ public:
|
|||||||
|
|
||||||
audioDriver->Activate();
|
audioDriver->Activate();
|
||||||
|
|
||||||
sleep(3); // let audio stabilize.
|
std::this_thread::sleep_for(std::chrono::milliseconds(3000));
|
||||||
|
|
||||||
this->SetXruns(0);
|
this->SetXruns(0);
|
||||||
|
|
||||||
sleep(7); // run for a bit.
|
std::this_thread::sleep_for(std::chrono::milliseconds(7000));
|
||||||
|
|
||||||
audioDriver->Deactivate();
|
audioDriver->Deactivate();
|
||||||
audioDriver->Close();
|
audioDriver->Close();
|
||||||
|
|||||||
+261
-61
@@ -42,6 +42,45 @@ static std::string ToString(const std::vector<uint8_t> &value)
|
|||||||
return std::string(start, end);
|
return std::string(start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string ToJsonAtomPath(const std::string &path) {
|
||||||
|
json_variant v = json_variant::make_object();;
|
||||||
|
auto obj = v.as_object();
|
||||||
|
(*obj)["otype_"] = json_variant("Path");
|
||||||
|
(*obj)["value"] = json_variant(path);
|
||||||
|
std::ostringstream ss;
|
||||||
|
json_writer writer(ss);
|
||||||
|
writer.write(v);
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
static bool TryGetAtomPath(const std::string &atomJson, std::string *outPath)
|
||||||
|
{
|
||||||
|
if (atomJson.empty())
|
||||||
|
return false;
|
||||||
|
std::stringstream ss(atomJson);
|
||||||
|
json_reader reader(ss);
|
||||||
|
json_variant vProperty;
|
||||||
|
reader.read(&vProperty);
|
||||||
|
if (vProperty.is_object())
|
||||||
|
{
|
||||||
|
auto obj = vProperty.as_object();
|
||||||
|
if (obj->contains("otype_") &&
|
||||||
|
(*obj)["otype_"].as_string() == "Path")
|
||||||
|
{
|
||||||
|
if (obj->contains("value"))
|
||||||
|
{
|
||||||
|
std::string value = (*obj)["value"].as_string();
|
||||||
|
if (!value.empty())
|
||||||
|
{
|
||||||
|
*outPath = value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static std::vector<uint8_t> ToBinary(const std::string &value)
|
static std::vector<uint8_t> ToBinary(const std::string &value)
|
||||||
{
|
{
|
||||||
std::vector<uint8_t> result(value.length() + 1);
|
std::vector<uint8_t> result(value.length() + 1);
|
||||||
@@ -65,6 +104,9 @@ public:
|
|||||||
|
|
||||||
void LoadPresets(PiPedalModel &model, const std::string &presetJson)
|
void LoadPresets(PiPedalModel &model, const std::string &presetJson)
|
||||||
{
|
{
|
||||||
|
pluginUploadDirectory = model.GetPluginUploadDirectory();
|
||||||
|
pluginUploadDirectoryString = pluginUploadDirectory.string();
|
||||||
|
|
||||||
BankFile bankFile;
|
BankFile bankFile;
|
||||||
|
|
||||||
std::istringstream s(presetJson);
|
std::istringstream s(presetJson);
|
||||||
@@ -73,12 +115,13 @@ public:
|
|||||||
reader.read(&bankFile);
|
reader.read(&bankFile);
|
||||||
GatherMediaPaths(model, bankFile);
|
GatherMediaPaths(model, bankFile);
|
||||||
configFiles["bankFile.json"] = presetJson;
|
configFiles["bankFile.json"] = presetJson;
|
||||||
|
|
||||||
pluginUploadDirectory = model.GetPluginUploadDirectory();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadPluginPresets(PiPedalModel &model, const std::string pluginPresetJson)
|
void LoadPluginPresets(PiPedalModel &model, const std::string pluginPresetJson)
|
||||||
{
|
{
|
||||||
|
pluginUploadDirectory = model.GetPluginUploadDirectory();
|
||||||
|
pluginUploadDirectoryString = pluginUploadDirectory.string();
|
||||||
|
|
||||||
PluginPresets pluginPresets;
|
PluginPresets pluginPresets;
|
||||||
|
|
||||||
std::istringstream s(pluginPresetJson);
|
std::istringstream s(pluginPresetJson);
|
||||||
@@ -88,8 +131,6 @@ public:
|
|||||||
|
|
||||||
GatherMediaPaths(model, pluginPresets);
|
GatherMediaPaths(model, pluginPresets);
|
||||||
configFiles["pluginPresets.json"] = pluginPresetJson;
|
configFiles["pluginPresets.json"] = pluginPresetJson;
|
||||||
|
|
||||||
pluginUploadDirectory = model.GetPluginUploadDirectory();
|
|
||||||
}
|
}
|
||||||
virtual ~PresetBundleWriterImpl() noexcept;
|
virtual ~PresetBundleWriterImpl() noexcept;
|
||||||
|
|
||||||
@@ -98,6 +139,10 @@ public:
|
|||||||
private:
|
private:
|
||||||
void AddUsedPlugin(PiPedalModel &model, const std::string &pluginUri, const std::string &name);
|
void AddUsedPlugin(PiPedalModel &model, const std::string &pluginUri, const std::string &name);
|
||||||
|
|
||||||
|
std::string UnmapPath(const std::string &path);
|
||||||
|
std::string MapPath(const std::string &path);
|
||||||
|
bool IsValidMediaPath(const std::string &path);
|
||||||
|
|
||||||
void GatherMediaPaths(PiPedalModel &model, BankFile &bankFile);
|
void GatherMediaPaths(PiPedalModel &model, BankFile &bankFile);
|
||||||
void GatherMediaPaths(PiPedalModel &model, PluginPresets &pluginPreset);
|
void GatherMediaPaths(PiPedalModel &model, PluginPresets &pluginPreset);
|
||||||
|
|
||||||
@@ -107,6 +152,7 @@ private:
|
|||||||
std::vector<std::map<std::string, std::string>> pluginMetadata;
|
std::vector<std::map<std::string, std::string>> pluginMetadata;
|
||||||
|
|
||||||
std::filesystem::path pluginUploadDirectory;
|
std::filesystem::path pluginUploadDirectory;
|
||||||
|
std::string pluginUploadDirectoryString;
|
||||||
};
|
};
|
||||||
|
|
||||||
void PresetBundleWriterImpl::WriteToFile(const std::filesystem::path &filePath)
|
void PresetBundleWriterImpl::WriteToFile(const std::filesystem::path &filePath)
|
||||||
@@ -134,7 +180,14 @@ void PresetBundleWriterImpl::WriteToFile(const std::filesystem::path &filePath)
|
|||||||
std::filesystem::path sourcePath = this->pluginUploadDirectory / std::filesystem::path(mediaPath);
|
std::filesystem::path sourcePath = this->pluginUploadDirectory / std::filesystem::path(mediaPath);
|
||||||
if (std::filesystem::exists(sourcePath))
|
if (std::filesystem::exists(sourcePath))
|
||||||
{
|
{
|
||||||
zipFile->WriteFile(zipName, sourcePath);
|
if (IsValidMediaPath(sourcePath)) // paranoid guard against exfiltration of non-media files.
|
||||||
|
{
|
||||||
|
zipFile->WriteFile(zipName, sourcePath);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Lv2Log::warning(SS("Media file is not valid: " << sourcePath));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -145,7 +198,6 @@ void PresetBundleWriterImpl::WriteToFile(const std::filesystem::path &filePath)
|
|||||||
{
|
{
|
||||||
zipFile->WriteFile(SS(zipName << ".mdata"), metadataPath);
|
zipFile->WriteFile(SS(zipName << ".mdata"), metadataPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
zipFile->Close();
|
zipFile->Close();
|
||||||
}
|
}
|
||||||
@@ -171,6 +223,54 @@ void PresetBundleWriterImpl::GatherMediaPaths(PiPedalModel &model, BankFile &ban
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (const auto &property : plugin->pathProperties_)
|
||||||
|
{
|
||||||
|
std::string path;
|
||||||
|
if (TryGetAtomPath(property.second, &path))
|
||||||
|
{
|
||||||
|
path = UnmapPath(path);
|
||||||
|
if (!mediaPaths.contains(path))
|
||||||
|
{
|
||||||
|
mediaPaths.insert(std::move(path));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const auto &snapshot : pedalboard.snapshots())
|
||||||
|
{
|
||||||
|
if (snapshot)
|
||||||
|
{
|
||||||
|
for (const auto &value : snapshot->values_)
|
||||||
|
{
|
||||||
|
if (value.isEnabled_)
|
||||||
|
{
|
||||||
|
const Lv2PluginState &state = value.lv2State_;
|
||||||
|
for (const auto &v : state.values_)
|
||||||
|
{
|
||||||
|
if (v.second.atomType_ == LV2_ATOM__Path)
|
||||||
|
{
|
||||||
|
std::string path = ToString(v.second.value_);
|
||||||
|
if (!mediaPaths.contains(path))
|
||||||
|
{
|
||||||
|
mediaPaths.insert(std::move(path));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const auto &property : value.pathProperties_)
|
||||||
|
{
|
||||||
|
std::string path;
|
||||||
|
if (TryGetAtomPath(property.second, &path))
|
||||||
|
{
|
||||||
|
path = UnmapPath(path);
|
||||||
|
if (!mediaPaths.contains(path))
|
||||||
|
{
|
||||||
|
mediaPaths.insert(std::move(path));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -246,8 +346,8 @@ private:
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::string metadataZipFilename = SS(zipFileName <<".mdata");
|
std::string metadataZipFilename = SS(zipFileName << ".mdata");
|
||||||
std::filesystem::path metadataFilename = SS(filePath.string() <<".mdata");
|
std::filesystem::path metadataFilename = SS(filePath.string() << ".mdata");
|
||||||
|
|
||||||
if (!std::filesystem::exists(metadataFilename))
|
if (!std::filesystem::exists(metadataFilename))
|
||||||
{
|
{
|
||||||
@@ -256,7 +356,9 @@ private:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (!zipFile->FileExists(metadataZipFilename))
|
if (!zipFile->FileExists(metadataZipFilename))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -267,6 +369,12 @@ private:
|
|||||||
}
|
}
|
||||||
void RenameMediaFileProperty(const std::string oldName, const std::string &newName);
|
void RenameMediaFileProperty(const std::string oldName, const std::string &newName);
|
||||||
|
|
||||||
|
void RenameState(Lv2PluginState &state, const std::string oldName, const std::string &newName);
|
||||||
|
void RenamePedalboardItem(PedalboardItem *item, const std::string oldName, const std::string &newName);
|
||||||
|
void RenamePedalboard(Pedalboard &pedalboard, const std::string oldName, const std::string &newName);
|
||||||
|
void RenamePreset(PluginPreset &pedalboard, const std::string oldName, const std::string &newName);
|
||||||
|
void RenameSnapshot(Snapshot *snapshot, const std::string oldName, const std::string &newName);
|
||||||
|
|
||||||
std::filesystem::path pluginUploadDirectory;
|
std::filesystem::path pluginUploadDirectory;
|
||||||
// BankFile bankFile;
|
// BankFile bankFile;
|
||||||
ZipFileReader::ptr zipFile;
|
ZipFileReader::ptr zipFile;
|
||||||
@@ -274,75 +382,137 @@ private:
|
|||||||
BankFile bankFile;
|
BankFile bankFile;
|
||||||
PluginPresets pluginPresets;
|
PluginPresets pluginPresets;
|
||||||
};
|
};
|
||||||
|
void PresetBundleReaderImpl::RenameState(Lv2PluginState &state, const std::string oldName, const std::string &newName)
|
||||||
void PresetBundleReaderImpl::RenameMediaFileProperty(const std::string oldName, const std::string &newName)
|
|
||||||
{
|
{
|
||||||
for (auto &preset : bankFile.presets())
|
for (auto &value : state.values_)
|
||||||
{
|
{
|
||||||
Pedalboard &pedalboard = preset->preset();
|
if (value.second.atomType_ == LV2_ATOM__Path)
|
||||||
auto items = pedalboard.GetAllPlugins();
|
|
||||||
for (auto plugin : items)
|
|
||||||
{
|
{
|
||||||
Lv2PluginState &state = plugin->lv2State();
|
std::string path = ToString(value.second.value_);
|
||||||
for (auto &value : state.values_)
|
if (path == oldName)
|
||||||
{
|
{
|
||||||
if (value.second.atomType_ == LV2_ATOM__Path)
|
state.values_.at(value.first).value_ = ToBinary(newName);
|
||||||
{
|
|
||||||
std::string path = ToString(value.second.value_);
|
|
||||||
if (path == oldName)
|
|
||||||
{
|
|
||||||
state.values_.at(value.first).value_ = ToBinary(newName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
std::string fullOldPath = (pluginUploadDirectory / oldName).string();
|
}
|
||||||
for (auto &property : plugin->pathProperties_)
|
}
|
||||||
{
|
}
|
||||||
std::stringstream ss(property.second);
|
|
||||||
json_reader reader(ss);
|
|
||||||
json_variant vProperty;
|
|
||||||
reader.read(&vProperty);
|
|
||||||
if (vProperty.is_object())
|
|
||||||
{
|
|
||||||
auto obj = vProperty.as_object();
|
|
||||||
if (obj->contains("otype_") &&
|
|
||||||
(*obj)["otype_"].as_string() == "Path")
|
|
||||||
{
|
|
||||||
if (obj->contains("value"))
|
|
||||||
{
|
|
||||||
std::string value = (*obj)["value"].as_string();
|
|
||||||
if (value == fullOldPath)
|
|
||||||
{
|
|
||||||
(*obj)["value"] = (pluginUploadDirectory / newName).string();
|
|
||||||
std::ostringstream ss;
|
|
||||||
json_writer writer(ss);
|
|
||||||
writer.write(vProperty);
|
|
||||||
plugin->pathProperties_[property.first] = ss.str();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
void PresetBundleReaderImpl::RenamePedalboardItem(PedalboardItem *plugin, const std::string oldName, const std::string &newName)
|
||||||
|
{
|
||||||
|
Lv2PluginState &state = plugin->lv2State();
|
||||||
|
RenameState(state, oldName, newName);
|
||||||
|
|
||||||
|
std::vector<std::pair<std::string, std::string>> propertiesToUpdate;
|
||||||
|
std::string fullOldPath = (pluginUploadDirectory / oldName).string();
|
||||||
|
for (auto &property : plugin->pathProperties_)
|
||||||
|
{
|
||||||
|
std::stringstream ss(property.second);
|
||||||
|
json_reader reader(ss);
|
||||||
|
json_variant vProperty;
|
||||||
|
reader.read(&vProperty);
|
||||||
|
if (vProperty.is_object())
|
||||||
|
{
|
||||||
|
auto obj = vProperty.as_object();
|
||||||
|
if (obj->contains("otype_") &&
|
||||||
|
(*obj)["otype_"].as_string() == "Path")
|
||||||
|
{
|
||||||
|
if (obj->contains("value"))
|
||||||
|
{
|
||||||
|
std::string value = (*obj)["value"].as_string();
|
||||||
|
if (value == fullOldPath)
|
||||||
|
{
|
||||||
|
(*obj)["value"] = (pluginUploadDirectory / newName).string();
|
||||||
|
std::ostringstream ss;
|
||||||
|
json_writer writer(ss);
|
||||||
|
writer.write(vProperty);
|
||||||
|
propertiesToUpdate.push_back(std::make_pair(property.first, ss.str()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto preset : pluginPresets.presets_)
|
for (auto &property : propertiesToUpdate)
|
||||||
{
|
{
|
||||||
Lv2PluginState state = preset.state_;
|
plugin->pathProperties_[property.first] = property.second;
|
||||||
for (auto &value : state.values_)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PresetBundleReaderImpl::RenameSnapshot(Snapshot *snapshot, const std::string oldName, const std::string &newName)
|
||||||
|
{
|
||||||
|
std::string fullOldPath = (pluginUploadDirectory / oldName).string();
|
||||||
|
for (auto &value : snapshot->values_)
|
||||||
|
{
|
||||||
|
if (value.isEnabled_)
|
||||||
{
|
{
|
||||||
if (value.second.atomType_ == LV2_ATOM__Path)
|
Lv2PluginState &state = value.lv2State_;
|
||||||
|
RenameState(state, oldName, newName);
|
||||||
|
|
||||||
|
std::vector<std::pair<std::string, std::string>> propertiesToUpdate;
|
||||||
|
// Check the path properties in the snapshot value.
|
||||||
|
for (auto &property : value.pathProperties_)
|
||||||
{
|
{
|
||||||
std::string path = ToString(value.second.value_);
|
std::string path;
|
||||||
if (path == oldName)
|
if (TryGetAtomPath(property.second,&path)) {
|
||||||
{
|
if (path == fullOldPath) {
|
||||||
state.values_.at(value.first).value_ = ToBinary(newName);
|
propertiesToUpdate.push_back(std::make_pair(property.first,
|
||||||
|
ToJsonAtomPath((pluginUploadDirectory / newName).string())));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (auto &property : propertiesToUpdate)
|
||||||
|
{
|
||||||
|
value.pathProperties_[property.first] = property.second;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void PresetBundleReaderImpl::RenamePedalboard(Pedalboard &pedalboard, const std::string oldName, const std::string &newName)
|
||||||
|
{
|
||||||
|
auto items = pedalboard.GetAllPlugins();
|
||||||
|
for (auto pedalboardItem : items)
|
||||||
|
{
|
||||||
|
RenamePedalboardItem(pedalboardItem, oldName, newName);
|
||||||
|
}
|
||||||
|
for (std::shared_ptr<Snapshot> &snapshot : pedalboard.snapshots())
|
||||||
|
{
|
||||||
|
if (snapshot)
|
||||||
|
{
|
||||||
|
RenameSnapshot(snapshot.get(), oldName, newName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PresetBundleReaderImpl::RenamePreset(PluginPreset &preset, const std::string oldName, const std::string &newName)
|
||||||
|
{
|
||||||
|
Lv2PluginState state = preset.state_;
|
||||||
|
for (auto &value : state.values_)
|
||||||
|
{
|
||||||
|
if (value.second.atomType_ == LV2_ATOM__Path)
|
||||||
|
{
|
||||||
|
std::string path = ToString(value.second.value_);
|
||||||
|
if (path == oldName)
|
||||||
|
{
|
||||||
|
state.values_.at(value.first).value_ = ToBinary(newName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PresetBundleReaderImpl::RenameMediaFileProperty(const std::string oldName, const std::string &newName)
|
||||||
|
{
|
||||||
|
// snapshots.
|
||||||
|
// there should be a dictionary for remapped media files.
|
||||||
|
// there should be a set for saved media files.
|
||||||
|
for (auto &preset : bankFile.presets())
|
||||||
|
{
|
||||||
|
Pedalboard &pedalboard = preset->preset();
|
||||||
|
RenamePedalboard(pedalboard, oldName, newName);
|
||||||
|
}
|
||||||
|
for (auto &preset : pluginPresets.presets_)
|
||||||
|
{
|
||||||
|
RenamePreset(preset, oldName, newName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PresetBundleReader::ptr PresetBundleReader::LoadPresetsFile(PiPedalModel &model, const std::filesystem::path &filePath)
|
PresetBundleReader::ptr PresetBundleReader::LoadPresetsFile(PiPedalModel &model, const std::filesystem::path &filePath)
|
||||||
{
|
{
|
||||||
@@ -420,7 +590,7 @@ void PresetBundleReaderImpl::ExtractMediaFile(const std::string &zipFileName)
|
|||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
if (zipFileName.starts_with("media/"))
|
if (zipFileName.starts_with("media/"))
|
||||||
{
|
{
|
||||||
if (zipFileName.ends_with(".mdata"))
|
if (zipFileName.ends_with(".mdata"))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -530,3 +700,33 @@ void PresetBundleWriterImpl::AddUsedPlugin(PiPedalModel &model, const std::strin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
std::string PresetBundleWriterImpl::UnmapPath(const std::string &path)
|
||||||
|
{
|
||||||
|
if (path.starts_with(pluginUploadDirectoryString))
|
||||||
|
{
|
||||||
|
return path.substr(pluginUploadDirectory.string().length() + 1);
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
bool PresetBundleWriterImpl::IsValidMediaPath(const std::string &path)
|
||||||
|
{
|
||||||
|
if (path.starts_with(pluginUploadDirectoryString))
|
||||||
|
{
|
||||||
|
if (path.length() >= pluginUploadDirectoryString.length() + 1 &&
|
||||||
|
path[pluginUploadDirectoryString.length()] == '/')
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::string PresetBundleWriterImpl::MapPath(const std::string &path)
|
||||||
|
{
|
||||||
|
if (!path.starts_with("/"))
|
||||||
|
{
|
||||||
|
return pluginUploadDirectory / path;
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
#include "AudioFileMetadataReader.hpp"
|
#include "AudioFileMetadataReader.hpp"
|
||||||
#include "AudioFiles.hpp"
|
#include "AudioFiles.hpp"
|
||||||
#include "util.hpp"
|
#include "util.hpp"
|
||||||
|
#include "HtmlHelper.hpp"
|
||||||
|
|
||||||
#define OLD_PRESET_EXTENSION ".piPreset"
|
#define OLD_PRESET_EXTENSION ".piPreset"
|
||||||
#define PRESET_EXTENSION ".piPreset"
|
#define PRESET_EXTENSION ".piPreset"
|
||||||
|
|||||||
Reference in New Issue
Block a user