V3 FactoryPresets
This commit is contained in:
Executable
+18
@@ -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>
|
||||
|
||||
|
||||
+98
@@ -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 head’s 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 @@
|
||||
2
|
||||
3
|
||||
|
||||
+356
-312
File diff suppressed because it is too large
Load Diff
@@ -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);
|
||||
|
||||
@@ -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
@@ -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 ¶m)
|
||||
int32_t ConvertThumbnailSize(const std::string& param)
|
||||
{
|
||||
if (param.empty())
|
||||
{
|
||||
@@ -117,7 +117,7 @@ int32_t ConvertThumbnailSize(const std::string ¶m)
|
||||
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);
|
||||
|
||||
@@ -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?
|
||||
|
||||
|
||||
Reference in New Issue
Block a user