V3 FactoryPresets

This commit is contained in:
Robin E.R. Davies
2026-05-30 22:38:59 -04:00
parent 9bc348bc9e
commit c7f003ec92
17 changed files with 674 additions and 527 deletions
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/bash
export SRC_ZIP="V3 Factory Presets.piBank"
export DST_ZIP="Factory Presets.piBank"
rm "presets/$DST_ZIP"
cd presets
rm -rf temp_folder
echo Unpacking "$SRC_ZIP"
unzip "$SRC_ZIP" -d ./temp_folder
cd temp_folder
cp -r ../Factory_Presets_Extra/* ./
echo Repacking "../$DST_ZIP"
zip -r9 "../$DST_ZIP" .
cd ..
rm -rf temp_folder
cd ..
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -0,0 +1,29 @@
<div id='tone3000_float' >
<img id='tone3000_thumbnail' src='img/PiPedal20Thumb.jpg' alt='' />
<div id='tone3000_float_content' >
<h3 id='tone3000_title'>PiPedal Factory-Provided IRs</h3>
<div>
<p id='tone3000_subtitle'>
All Impulse Response Files in this folder are provided under a <a href='licenses/t3k_license.html' target='_blank' rel='noopener noreferrer' >T3K License</a>. Permission has been granted ONLY to use these IRs with PiPedal. Please contact the original creators for permission to use these IRs for any other purpose.
</p>
</div>
</div>
</div>
---
<div id='tone3000_float_right'>
<img id='tone3000_small_thumbnail' src='/var/tone3000_thumbnail?id=67526' alt='' />
<div id='tone3000_float_content' >
<h3 id='tone3000_title'>Marshall JCM800 Lead 1960 A (4- SM57, eoc)</h3>
<div id='tone3000_subtitle'>
<p>IR Created by <a target='_blank' href="tonelink?user=kenazmusic">kenazmusic</a><br/>
From the <a target="_blank" href="https://www.tone3000.com/tones/marshall-jcm800-lead-1960-a-celestion-t75-multi-mics-67526">Marshall JCM800 Lead 1960 A (Celestion T75, multi mics)</a> IR pack.<a></p>
<p>Marshall JCM800 Lead 1960 A, Celestion G12T-75 (16 Ohm) Speakers from 1987. Mics: Shure SM57. Mic position: top right (slanted), eoc.
</p>
</div>
</div>
</div>
@@ -0,0 +1,98 @@
<div id='tone3000_float' >
<img id='tone3000_thumbnail' src='img/PiPedal20Thumb.jpg' alt='' />
<div id='tone3000_float_content' >
<h3 id='tone3000_title'>PiPedal Factory-Provided Models </h3>
<div>
<p id='tone3000_subtitle'>
All models in this folder are provided under a <a href='licenses/t3k_license.html' target='_blank' rel='noopener noreferrer' >T3K License</a>. Permission has been granted ONLY to use these models with PiPedal. Please contact the original creators for permission to use these models for any other purpose.
</p>
</div>
</div>
</div>
---
<div id='tone3000_float_right'>
<img id='tone3000_small_thumbnail' src='/var/tone3000_thumbnail?id=54580' alt='' />
<div id='tone3000_float_content' >
<h3 id='tone3000_title'>1960 Fender Tweed Deluxe 5E3 - Clean</h3>
<div id='tone3000_subtitle'>
<p>Full rig, NAM A2. Created by <a target='_blank' href="https://tone3000.com/tone3000">tone3000</a><br/>
From the <a target="_blank" href="https://tone3000.com/tones/1960-fender-tweed-deluxe-5e3-54580">1960 Fender Tweed Deluxe 5E3</a> model pack.<a></p>
<p>A model of a 1960 Fender Tweed Deluxe 5E3, with clean settings (T 5, I 3, M 9). SM57, cap edge.
</p>
</div>
</div>
</div>
---
<div id='tone3000_float_right'>
<img id='tone3000_small_thumbnail' src='/var/tone3000_thumbnail?id=54580' alt='' />
<div id='tone3000_float_content' >
<h3 id='tone3000_title'>1960 Fender Tweed Deluxe 5E3 - Crunch</h3>
<div id='tone3000_subtitle'>
<p>Full rig, NAM A2. Created by <a target='_blank' href="https://tone3000.com/tone3000">tone3000</a><br/>
From the <a target="_blank" href="https://tone3000.com/tones/1960-fender-tweed-deluxe-5e3-54580">1960 Fender Tweed Deluxe 5E3</a> model pack.<a></p>
<p>A model of a 1960 Fender Tweed Deluxe 5E3, with crunch settings (T 5, I 11, M 12). SM57, cap edge.
</p>
</div>
</div>
</div>
---
<div id='tone3000_float_right'>
<img id='tone3000_small_thumbnail' src='/var/tone3000_thumbnail?id=60033' alt='' />
<div id='tone3000_float_content' >
<h3 id='tone3000_title'>1960 Gibson Rhythm King - Edge of Breakup</h3>
<div id='tone3000_subtitle'>
<p>Full rig, NAM A2. Created by <a target='_blank' href="https://tone3000.com/amalgamaudio">amalgamaudio</a><br/>
From the <a target='_blank' href="https://www.tone3000.com/tones/gibson-ga-200-rhythm-king-1960-60033">Gibson GA-200 Rhythm King 1960</a> model pack.<a></p>
<p>One of the larger amps Gibson built in the Tweed era. The rival to the Tweed Bassman and Tweed Twin - wonderful big, bold cleans and edge of breakup, worthy of the title "King".
</p>
<p>Get the full <a target='_blank' href="https://www.amalgamcaptures.com/product-page/gbsn-g200-namdi">capture pack for this amp here</a>.
</p>
<p><a target='_blank' href="https://www.amalgamcaptures.com/nam">https://www.amalgamcaptures.com/nam</a></p>
</div>
</div>
</div>
---
<div id='tone3000_float_right'>
<img id='tone3000_small_thumbnail' src='/var/tone3000_thumbnail?id=59301' alt='' />
<div id='tone3000_float_content' >
<h3 id='tone3000_title'>Marshall - JCM800 KKS (TS9) [18dBu] - Hi Gain</h3>
<div id='tone3000_subtitle'>
<p>Amp head only, NAM A2. Created by <a target='_blank' href="https://tone3000.com/kenazmusic&architecture=2">kenazmusic</a><br/>
From the <a target='_blank' href="https://www.tone3000.com/tones/marshall-jcm800-kerry-king-signature-18dbu-59301">Marshall - JCM800 (Kerry King Signature) [18dBu]</a> model pack.<a></p>
<p>A model of a high-gain Marshall JCM800 Kerry King Signature Amp, with an Ibanez TS9. The model is not calibrated, but expects the input signal to be gain-staged to -18dBU.
</p>
<p>This is a model of an amp head only. You must add a Cabinet IR after this model in order to get a good sound.
</div>
</div>
</div>
---
<div id='tone3000_float_right'>
<img id='tone3000_small_thumbnail' src='/var/tone3000_thumbnail?id=40737' alt='' />
<div id='tone3000_float_content' >
<h3 id='tone3000_title'>Peavey 6505 1992 Lead - Chug</h3>
<div id='tone3000_subtitle'>
<p>Full rig, NAM A2. Created by <a href="https://tone3000.com/outmodedelectronics" target='_blank' >outmodedelectronics</a><br/>
From the <a target="_blank" href="https://www.tone3000.com/tones/peavey-6505-1992-original-lead-evh-5150iii-4x12-full-rig-40737">Peavey 6505 1992 Original Lead - EVH 5150III 4x12 - Full Rig</a> model pack.</p>
<p>A Peavey 6505 1992 Original heads Lead Channel through an EVH 5150III 4x12 cabinet. Pr-4 B-6 M-4 T-7 Pro-1 R-7 P-8, SM57c.
</p>
</div>
</div>
</div>
---
Binary file not shown.

After

Width:  |  Height:  |  Size: 385 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
2
3
+356 -312
View File
File diff suppressed because it is too large Load Diff
+2
View File
@@ -80,6 +80,8 @@ private:
private:
void FillSampleDirectoryTree(FilePropertyDirectoryTree*node, const std::filesystem::path&directory) const;
void UpgradeV1FactoryPresets();
void UpgradeV2FactoryPresets();
void UpgradeFactoryPresets();
void MaybeCopyDefaultPresets();
static std::string SafeEncodeName(const std::string& name);
+1
View File
@@ -145,6 +145,7 @@ namespace pipedal
const std::string &errorMessage) = 0;
virtual std::string Tone3000ThumbnailDirectory() = 0;
virtual std::string OldTone3000ThumbnailDirectory() = 0;
};
using self = Tone3000Downloader;
+161 -141
View File
@@ -48,7 +48,7 @@
#define BANK_EXTENSION ".piBank"
#define PLUGIN_PRESETS_EXTENSION ".piPluginPresets"
static const std::filesystem::path WEB_TEMP_DIR{"/var/pipedal/web_temp"};
static const std::filesystem::path WEB_TEMP_DIR{ "/var/pipedal/web_temp" };
static const std::string PLUGIN_PRESETS_MIME_TYPE = "application/vnd.pipedal.pluginPresets";
static const std::string PRESET_MIME_TYPE = "application/vnd.pipedal.preset";
@@ -73,10 +73,10 @@ JSON_MAP_REFERENCE(UserUploadResponse, errorMessage)
JSON_MAP_REFERENCE(UserUploadResponse, path)
JSON_MAP_END()
static std::string GetMimeType(const std::filesystem::path &path)
static std::string GetMimeType(const std::filesystem::path& path)
{
std::string extension = path.extension();
const MimeTypes &mimeTypes = MimeTypes::instance();
const MimeTypes& mimeTypes = MimeTypes::instance();
auto result = mimeTypes.MimeTypeFromExtension(extension);
return result;
}
@@ -108,7 +108,7 @@ static bool IsSafeThumbnailPath(const fs::path path)
}
return true;
}
int32_t ConvertThumbnailSize(const std::string &param)
int32_t ConvertThumbnailSize(const std::string& param)
{
if (param.empty())
{
@@ -117,7 +117,7 @@ int32_t ConvertThumbnailSize(const std::string &param)
return static_cast<int32_t>(std::stoi(param));
}
static bool IsZipFile(const std::filesystem::path &path)
static bool IsZipFile(const std::filesystem::path& path)
{
std::ifstream f(path);
if (!f.is_open())
@@ -135,15 +135,15 @@ static bool IsZipFile(const std::filesystem::path &path)
class ExtensionChecker
{
public:
ExtensionChecker(const std::string &extensionList)
ExtensionChecker(const std::string& extensionList)
: extensions(split(extensionList, ','))
{
}
bool IsValidExtension(const std::string &extension)
bool IsValidExtension(const std::string& extension)
{
if (extensions.size() == 0)
return true;
for (const auto &ext : extensions)
for (const auto& ext : extensions)
{
if (ext == extension)
return true;
@@ -155,7 +155,7 @@ private:
std::vector<std::string> extensions;
};
static fs::path GetTone3000ThumbnailFile(const fs::path &thumbnailDirectory, const std::string &id)
static fs::path GetTone3000ThumbnailFile(const fs::path& thumbnailDirectory, const std::string& id)
{
std::string stem = id;
// find a file in thumbnailDirectory which has a filename of {stem}.*.
@@ -164,13 +164,13 @@ static fs::path GetTone3000ThumbnailFile(const fs::path &thumbnailDirectory, con
return {};
}
for (const auto &entry : fs::directory_iterator(thumbnailDirectory))
for (const auto& entry : fs::directory_iterator(thumbnailDirectory))
{
if (!entry.is_regular_file())
{
continue;
}
const auto &path = entry.path();
const auto& path = entry.path();
if (path.stem() == stem)
{
return path;
@@ -179,18 +179,50 @@ static fs::path GetTone3000ThumbnailFile(const fs::path &thumbnailDirectory, con
return {};
}
int64_t ImportBankFile(PiPedalModel &model, const std::filesystem::path& filePath,uint64_t uploadAfter = -1)
{
BankFile bankFile;
if (filePath.empty())
{
throw std::runtime_error("Unexpected.");
}
if (IsZipFile(filePath))
{
auto presetReader = PresetBundleReader::LoadPresetsFile(model, filePath);
presetReader->ExtractMediaFiles();
std::stringstream ss(presetReader->GetPresetJson());
json_reader reader(ss);
reader.read(&bankFile);
}
else
{
std::ifstream f {filePath};
if (!f.is_open()) {
throw std::runtime_error(SS("Unable to open file " << filePath));
}
// legacy json format, no zip, no media files.
json_reader reader(f);
reader.read(&bankFile);
}
uint64_t instanceId = model.UploadBank(bankFile, uploadAfter);
return instanceId;
}
class DownloadIntercept : public RequestHandler
{
PiPedalModel *model;
PiPedalModel* model;
public:
DownloadIntercept(PiPedalModel *model)
DownloadIntercept(PiPedalModel* model)
: RequestHandler("/var"),
model(model)
model(model)
{
}
virtual bool wants(const std::string &method, const uri &request_uri) const
virtual bool wants(const std::string& method, const uri& request_uri) const
{
if (request_uri.segment_count() != 2 || request_uri.segment(0) != "var")
{
@@ -304,7 +336,7 @@ public:
return false;
}
static std::string GetContentDispositionHeader(const std::string &name, const std::string &extension)
static std::string GetContentDispositionHeader(const std::string& name, const std::string& extension)
{
std::string fileName = name.substr(0, 64) + extension;
std::stringstream s;
@@ -314,7 +346,7 @@ public:
return result;
}
void GetPluginPresets(const uri &request_uri, std::string *pName, std::string *pContent)
void GetPluginPresets(const uri& request_uri, std::string* pName, std::string* pContent)
{
std::string pluginUri = request_uri.query("id");
auto plugin = model->GetPluginHost().GetPluginInfo(pluginUri);
@@ -327,7 +359,7 @@ public:
writer.write(pluginPresets);
*pContent = s.str();
}
void GetPreset(const uri &request_uri, std::string *pName, std::string *pContent)
void GetPreset(const uri& request_uri, std::string* pName, std::string* pContent)
{
std::string strInstanceId = request_uri.query("id");
int64_t instanceId = std::stol(strInstanceId);
@@ -345,7 +377,7 @@ public:
*pContent = s.str();
*pName = pedalboard.name();
}
void GetBank(const uri &request_uri, std::string *pName, std::string *pContent)
void GetBank(const uri& request_uri, std::string* pName, std::string* pContent)
{
std::string strInstanceId = request_uri.query("id");
int64_t instanceId = std::stol(strInstanceId);
@@ -360,10 +392,10 @@ public:
}
virtual void head_response(
const uri &request_uri,
HttpRequest &req,
HttpResponse &res,
std::error_code &ec) override
const uri& request_uri,
HttpRequest& req,
HttpResponse& res,
std::error_code& ec) override
{
try
{
@@ -392,7 +424,11 @@ public:
fs::path path = GetTone3000ThumbnailFile(this->model->Tone3000ThumbnailDirectory(), id);
if (!fs::exists(path))
{
throw PiPedalException("File not found.");
path = GetTone3000ThumbnailFile(this->model->OldTone3000ThumbnailDirectory(), id);
if (!fs::exists(path))
{
throw PiPedalException("File not found.");
}
}
auto mimeType = GetMimeType(path);
if (mimeType.empty())
@@ -447,7 +483,7 @@ public:
std::string content;
GetPluginPresets(request_uri, &name, &content);
TemporaryFile tmpFile{WEB_TEMP_DIR};
TemporaryFile tmpFile{ WEB_TEMP_DIR };
PresetBundleWriter::ptr presetbundleWriter = PresetBundleWriter::CreatePluginPresetsFile(*(this->model), content);
presetbundleWriter->WriteToFile(tmpFile.Path());
size_t contentLength = std::filesystem::file_size(tmpFile.Path());
@@ -465,7 +501,7 @@ public:
std::string content;
GetPreset(request_uri, &name, &content);
TemporaryFile tmpFile{WEB_TEMP_DIR};
TemporaryFile tmpFile{ WEB_TEMP_DIR };
PresetBundleWriter::ptr presetbundleWriter = PresetBundleWriter::CreatePresetsFile(*(this->model), content);
presetbundleWriter->WriteToFile(tmpFile.Path());
size_t contentLength = std::filesystem::file_size(tmpFile.Path());
@@ -482,7 +518,7 @@ public:
std::string content;
GetBank(request_uri, &name, &content);
TemporaryFile tmpFile{WEB_TEMP_DIR};
TemporaryFile tmpFile{ WEB_TEMP_DIR };
PresetBundleWriter::ptr presetbundleWriter = PresetBundleWriter::CreatePresetsFile(*(this->model), content);
presetbundleWriter->WriteToFile(tmpFile.Path());
size_t contentLength = std::filesystem::file_size(tmpFile.Path());
@@ -495,7 +531,7 @@ public:
}
throw PiPedalException("Not found.");
}
catch (const std::exception &e)
catch (const std::exception& e)
{
if (strcmp(e.what(), "Not found") == 0)
{
@@ -508,20 +544,20 @@ public:
}
}
static void setLastModifiedFromFile(HttpResponse &res, const std::filesystem::path &path)
static void setLastModifiedFromFile(HttpResponse& res, const std::filesystem::path& path)
{
auto lastModified = std::filesystem::last_write_time(path);
res.set(HttpField::LastModified, HtmlHelper::timeToHttpDate(lastModified));
}
AudioDirectoryInfo::Ptr CreateDirectoryInfo(const fs::path &path)
AudioDirectoryInfo::Ptr CreateDirectoryInfo(const fs::path& path)
{
return AudioDirectoryInfo::Create(path,
GetShadowIndexDirectory(
this->model->GetPluginUploadDirectory(),
path));
GetShadowIndexDirectory(
this->model->GetPluginUploadDirectory(),
path));
}
bool isInfoFile(const fs::path &path)
bool isInfoFile(const fs::path& path)
{
auto extension = path.extension();
if (extension == ".pdf")
@@ -546,24 +582,24 @@ public:
std::string T3kResponse()
{
return "<html>\n"
"<head>\n"
"<script>\n"
" window.close();"
"</script>\n"
"</head>\n"
"<body>\n"
"</body>\n"
"</html>\n";
"<head>\n"
"<script>\n"
" window.close();"
"</script>\n"
"</head>\n"
"<body>\n"
"</body>\n"
"</html>\n";
}
void DownloadTone3000Tone(const uri &requestUri)
void DownloadTone3000Tone(const uri& requestUri)
{
}
virtual void get_response(
const uri &request_uri,
HttpRequest &req,
HttpResponse &res,
std::error_code &ec) override
const uri& request_uri,
HttpRequest& req,
HttpResponse& res,
std::error_code& ec) override
{
try
{
@@ -690,7 +726,7 @@ public:
try
{
auto files = audioDirectory->GetFiles();
for (const auto &file : files)
for (const auto& file : files)
{
std::string fileNameOnly = path.filename();
if (file.fileName() == fileNameOnly)
@@ -703,7 +739,7 @@ public:
}
}
}
catch (const std::exception &e)
catch (const std::exception& e)
{
Lv2Log::error("Error getting audio directory info: %s - (%s)", path.c_str(), e.what());
throw e;
@@ -761,7 +797,7 @@ public:
thumbnailTemporaryFile = audioDirectory->GetThumbnail(path.filename(), width, height);
}
catch (const std::exception &e)
catch (const std::exception& e)
{
fs::path defaultThumbnail = model->GetWebRoot() / "img/missing_thumbnail.jpg";
thumbnailTemporaryFile.SetNonDeletedPath(defaultThumbnail, "image/jpeg");
@@ -776,7 +812,7 @@ public:
res.setBodyFile(t, thumbnailTemporaryFile.DeleteFile());
thumbnailTemporaryFile.Detach();
}
catch (const std::exception &e)
catch (const std::exception& e)
{
Lv2Log::error("Error getting thumbnail: %s - (%s)", request_uri.str().c_str(), e.what());
throw e;
@@ -809,7 +845,7 @@ public:
res.setBody(ss.str());
}
catch (const std::exception &e)
catch (const std::exception& e)
{
res.setBody("\"\"");
}
@@ -841,7 +877,7 @@ public:
res.setBody(ss.str());
}
catch (const std::exception &e)
catch (const std::exception& e)
{
res.setBody("\"\"");
}
@@ -852,7 +888,7 @@ public:
throw PiPedalException("Not found");
}
}
catch (const std::exception &e)
catch (const std::exception& e)
{
if (strcmp(e.what(), "Not found") == 0)
{
@@ -864,9 +900,9 @@ public:
}
}
}
static std::string GetFirstFolderOrFile(const std::vector<std::string> &fileNames)
static std::string GetFirstFolderOrFile(const std::vector<std::string>& fileNames)
{
for (const auto &fileName : fileNames)
for (const auto& fileName : fileNames)
{
size_t nPos = fileName.find('/');
if (nPos != std::string::npos)
@@ -883,11 +919,11 @@ public:
return fileNames[0];
}
}
static bool HasSingleRootDirectory(ZipFileReader &zipFile)
static bool HasSingleRootDirectory(ZipFileReader& zipFile)
{
bool hasDirectory = false;
std::string previousDirectory;
for (auto &file : zipFile.GetFiles())
for (auto& file : zipFile.GetFiles())
{
auto pos = file.find('/');
if (pos == std::string::npos)
@@ -916,15 +952,15 @@ public:
}
void UploadEmbeddedZipFile(
PiPedalModel *model,
pipedal::zip_file_input_stream &si,
const std::string &inputFileName,
PiPedalModel* model,
pipedal::zip_file_input_stream& si,
const std::string& inputFileName,
fs::path directory,
ExtensionChecker &extensionChecker,
ExtensionChecker& extensionChecker,
int64_t instanceId,
const std::string &patchProperty)
const std::string& patchProperty)
{
TemporaryFile tempFile{WEB_TEMP_DIR};
TemporaryFile tempFile{ WEB_TEMP_DIR };
// Extract the zip_file_input_stream to the temporary file.
{
std::ofstream out(tempFile.Path(), std::ios::binary);
@@ -955,11 +991,11 @@ public:
{
directory = (fs::path(directory) / fs::path(inputFileName).filename().stem()).string();
}
for (const auto &inputFile : files)
for (const auto& inputFile : files)
{
if (!inputFile.ends_with("/")) // don't process directory entries.
{
fs::path inputPath{inputFile};
fs::path inputPath{ inputFile };
std::string extension = inputPath.extension();
if (extensionChecker.IsValidExtension(extension) || isInfoFile(inputFile))
{
@@ -985,10 +1021,10 @@ public:
}
virtual void post_response(
const uri &request_uri,
HttpRequest &req,
HttpResponse &res,
std::error_code &ec) override
const uri& request_uri,
HttpRequest& req,
HttpResponse& res,
std::error_code& ec) override
{
try
{
@@ -1004,7 +1040,7 @@ public:
{
throw std::runtime_error("Invalid path");
}
if (!IsSafeMediaPath(targetPath) && !IsSafeThumbnailPath(targetPath))
if (!IsSafeMediaPath(targetPath) && !IsSafeThumbnailPath(targetPath))
{
throw std::runtime_error("Unsafe path.");
}
@@ -1024,24 +1060,26 @@ public:
fs::rename(req.get_body_temporary_file(), targetPath);
req.detach_body_temporary_file();
} catch (const std::exception &e) {
}
catch (const std::exception& e) {
// ok Copy into place instead.
fs::copy(req.get_body_temporary_file(), targetPath);
}
// set target permissions to "pipedal_d:pipedald -rw-rw-r-- if we can.
try {
fs::permissions(targetPath, fs::perms::owner_read | fs::perms::owner_write |
fs::perms::group_read | fs::perms::group_write |
fs::perms::others_read,
fs::perm_options::replace);
} catch (const std::exception&)
fs::permissions(targetPath, fs::perms::owner_read | fs::perms::owner_write |
fs::perms::group_read | fs::perms::group_write |
fs::perms::others_read,
fs::perm_options::replace);
}
catch (const std::exception&)
{
// ignore.
}
responseText = "{\"ok\": true}";
}
catch (const std::exception &e)
catch (const std::exception& e)
{
std::string jsonString = json_writer::encode_string(e.what());
std::ostringstream os;
@@ -1131,28 +1169,7 @@ public:
else if (segment == "uploadBank")
{
BankFile bankFile;
fs::path filePath = req.get_body_temporary_file();
if (filePath.empty())
{
throw std::runtime_error("Unexpected.");
}
if (IsZipFile(filePath))
{
auto presetReader = PresetBundleReader::LoadPresetsFile(*(this->model), filePath);
presetReader->ExtractMediaFiles();
std::stringstream ss(presetReader->GetPresetJson());
json_reader reader(ss);
reader.read(&bankFile);
}
else
{
// legacy json format, no zip, no media files.
json_reader reader(req.get_body_input_stream());
reader.read(&bankFile);
}
uint64_t uploadAfter = -1;
std::string strUploadAfter = request_uri.query("uploadAfter");
@@ -1161,10 +1178,13 @@ public:
uploadAfter = std::stol(strUploadAfter);
}
uint64_t instanceId = model->UploadBank(bankFile, uploadAfter);
auto instanceId = ImportBankFile(*(this->model), filePath, uploadAfter);
res.set(HttpField::content_type, "application/json");
res.set(HttpField::cache_control, "no-cache");
std::stringstream sResult;
sResult << instanceId;
std::string result = sResult.str();
@@ -1187,7 +1207,7 @@ public:
int64_t instanceId;
{
std::istringstream ss{instanceIdString};
std::istringstream ss{ instanceIdString };
ss >> instanceId;
if (!ss)
{
@@ -1207,7 +1227,7 @@ public:
if (filename.ends_with(".zip"))
{
ExtensionChecker extensionChecker{request_uri.query("ext")};
ExtensionChecker extensionChecker{ request_uri.query("ext") };
namespace fs = std::filesystem;
try
@@ -1219,11 +1239,11 @@ public:
{
directory = (fs::path(directory) / fs::path(filename).filename().replace_extension("")).string();
}
for (const auto &inputFile : files)
for (const auto& inputFile : files)
{
if (!inputFile.ends_with("/")) // don't process directory entries.
{
fs::path inputPath{inputFile};
fs::path inputPath{ inputFile };
std::string extension = inputPath.extension();
if (extensionChecker.IsValidExtension(extension) || isInfoFile(inputFile))
{
@@ -1251,7 +1271,7 @@ public:
std::string returnPath = GetFirstFolderOrFile(files);
outputFileName = fs::path(directory) / returnPath;
}
catch (const std::exception &e)
catch (const std::exception& e)
{
Lv2Log::error(SS("Unzip failed. " << e.what()));
throw;
@@ -1269,7 +1289,7 @@ public:
}
result.path_ = outputFileName.string();
}
catch (const std::exception &e)
catch (const std::exception& e)
{
result.errorMessage_ = e.what();
}
@@ -1287,7 +1307,7 @@ public:
throw PiPedalException("Not found");
}
}
catch (const std::exception &e)
catch (const std::exception& e)
{
Lv2Log::error(SS("Error uploading file: " << e.what()));
if (strcmp(e.what(), "Not found") == 0)
@@ -1302,7 +1322,7 @@ public:
}
};
static std::string StripPortNumber(const std::string &fromAddress)
static std::string StripPortNumber(const std::string& fromAddress)
{
std::string address = fromAddress;
@@ -1335,19 +1355,19 @@ static std::string StripPortNumber(const std::string &fromAddress)
class InterceptConfig : public RequestHandler
{
private:
PiPedalModel&model;
PiPedalModel& model;
uint64_t maxUploadSize;
int portNumber;
public:
InterceptConfig(PiPedalModel&model,int portNumber, uint64_t maxUploadSize)
InterceptConfig(PiPedalModel& model, int portNumber, uint64_t maxUploadSize)
: RequestHandler("/var/config.json"),
model(model),
maxUploadSize(maxUploadSize),
portNumber(portNumber)
model(model),
maxUploadSize(maxUploadSize),
portNumber(portNumber)
{
}
std::string GetConfig(const std::string &fromAddress)
std::string GetConfig(const std::string& fromAddress)
{
std::string webSocketAddress = GetNonLinkLocalAddress(StripPortNumber(fromAddress));
Lv2Log::info(SS("Web Socket Address: " << webSocketAddress << ":" << portNumber));
@@ -1355,32 +1375,32 @@ public:
std::stringstream s;
s << "{ \"socket_server_port\": " << portNumber
<< ", \"socket_server_address\": \"" << webSocketAddress
<< "\", \"ui_plugins\": [ ], \"max_upload_size\": " << maxUploadSize
<< ", \"enable_auto_update\": " << (ENABLE_AUTO_UPDATE ? " true" : "false")
<< ", \"has_wifi_device\": " << (HotspotManager::HasWifiDevice() ? " true" : "false")
<< ", \"tone3000_A2_models\": " << (model.Configuration().GetTone3000A2Models() ? " true" : "false")
<< " }";
<< ", \"socket_server_address\": \"" << webSocketAddress
<< "\", \"ui_plugins\": [ ], \"max_upload_size\": " << maxUploadSize
<< ", \"enable_auto_update\": " << (ENABLE_AUTO_UPDATE ? " true" : "false")
<< ", \"has_wifi_device\": " << (HotspotManager::HasWifiDevice() ? " true" : "false")
<< ", \"tone3000_A2_models\": " << (model.Configuration().GetTone3000A2Models() ? " true" : "false")
<< " }";
return s.str();
}
virtual ~InterceptConfig() {}
virtual void head_response(
const uri &request_uri,
HttpRequest &req,
HttpResponse &res,
std::error_code &ec) override
const uri& request_uri,
HttpRequest& req,
HttpResponse& res,
std::error_code& ec) override
{
// intercepted. See the other overload.
}
virtual void head_response(
const std::string &fromAddress,
const uri &request_uri,
HttpRequest &req,
HttpResponse &res,
std::error_code &ec) override
const std::string& fromAddress,
const uri& request_uri,
HttpRequest& req,
HttpResponse& res,
std::error_code& ec) override
{
std::string response = GetConfig(fromAddress);
res.set(HttpField::content_type, "application/json");
@@ -1390,20 +1410,20 @@ public:
}
virtual void get_response(
const uri &request_uri,
HttpRequest &req,
HttpResponse &res,
std::error_code &ec) override
const uri& request_uri,
HttpRequest& req,
HttpResponse& res,
std::error_code& ec) override
{
// intercepted. see the other overload.
}
virtual void get_response(
const std::string &fromAddress,
const uri &request_uri,
HttpRequest &req,
HttpResponse &res,
std::error_code &ec) override
const std::string& fromAddress,
const uri& request_uri,
HttpRequest& req,
HttpResponse& res,
std::error_code& ec) override
{
std::string response = GetConfig(fromAddress);
res.set(HttpField::content_type, "application/json");
@@ -1414,12 +1434,12 @@ public:
};
void pipedal::ConfigureWebServer(
WebServer &server,
PiPedalModel &model,
WebServer& server,
PiPedalModel& model,
int port,
size_t maxUploadSize)
{
std::shared_ptr<RequestHandler> interceptConfig{new InterceptConfig(model,port, maxUploadSize)};
std::shared_ptr<RequestHandler> interceptConfig{ new InterceptConfig(model,port, maxUploadSize) };
server.AddRequestHandler(interceptConfig);
std::shared_ptr<DownloadIntercept> downloadIntercept = std::make_shared<DownloadIntercept>(&model);
+8 -72
View File
@@ -2,97 +2,33 @@ Create Factory Model.piBank.
Install procedure for upgrading of Factory Preset.
Relocate image files.
Prep readme files in Factory Presets.
A final solution for rate-limiting on Tone3000.
T3k links in the readme files. Can we start a Popup Flow from the given links?
Implement NAM Model Weight selection UI
NAM INput VU is f*ed up.
File Player Underrun is NOT CPU use related. There's an underrun somewhere.
Update Pi 4 Benchmark Results:
The benchmark is to run TooB Neural Amp Modeler with an A1 model to generate 100s of audio. Lower times are better.
TooB NAM has a compile-time switch that uses either the NeuralAudio NAM implementation or
the Neural Modeler Core NAM implementation.
Results
aarch64 (Raspberry PI 4, ARM Cortex A72, Raspberry PI OS Bookworm)
Neural Amp Modeler Core: 94.296s
NeuralAudio: 31.589s
Compiler options: "-Ofast" "-mcpu=cortex-a72" "-march=armv8-a" "-mtune=cortex-a72" "-DEIGEN_DEFAULT_L1_CACHE_SIZE=32768"
aarch64 (Raspberry PI 5, ARM Cortex A76, Rasperry PI OS Trixie)
Neural Amp Modeler Core: 16.084s
NeuralAudio: 10.766s
Compiler options: "-Ofast" "-mcpu=cortex-a76" "-march=armv8.2-a" "-mtune=cortex-a76" "-DEIGEN_DEFAULT_L1_CACHE_SIZE=65536"apt
amd64 Native (AMD Ryzen 7 7735HS, Ubuntu 24.04 amd64)
Neural Amp Modeler Core: 4.716s
NeuralAudio x64: 3.952s
Compiler options /Ofast, MMX, SSE, SSE2, no AVX.
amd64 AVX+ (AMD Ryzen 7 7735HS, Ubuntu 24.04 amd64)
Neural Amp Modeler Core: 4.97s
NeuralAudio x64: 4.032s
Compiler options /Ofast, "-march=sandybridge" "-mtune=sandybridge"
amd64 SSE2 (AMD Ryzen 7 7735HS, Ubuntu 24.04 amd64)
Neural Amp Modeler Core: 7.748s
NeuralAudio x64: 5.983s
Compiler options /Ofast (defaults to SSE2, no AVX)
The Model:
Package: Fender Deluxe Reverb %2765 Reissue %7c Clean %7c SM57 %2b Royer R-121 %2b Room
Model: Fender DRRI %7c Clean %7c Room Only %7c Full Rig
Downloaded from Tone3000.
The model file is attached.
summaries for Mono audio adapaters.
Check PWA on windows, edge and chrome.
Make sure Pi 4 default audio device is still hidden when selecting devices!
A final solution for rate-limiting on Tone3000.
A way to force input to mono?
Tooltip on File Property Select: add to release notes.
sAFEfILEnAMES: RENAME, &C. Safe bank names?
NEW BANK
WINDOW SIZE CALCUALTIONS ARE WRONG ON LINUX HIDEF DISPLAYS.
Carla Project icons.
check reload after change of LV2 plugins.
Exactly one underrun per seek in Toob Player
json nan/inf is fatal.
- pipewire aux in?