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:
|
private:
|
||||||
void FillSampleDirectoryTree(FilePropertyDirectoryTree*node, const std::filesystem::path&directory) const;
|
void FillSampleDirectoryTree(FilePropertyDirectoryTree*node, const std::filesystem::path&directory) const;
|
||||||
|
void UpgradeV1FactoryPresets();
|
||||||
|
void UpgradeV2FactoryPresets();
|
||||||
void UpgradeFactoryPresets();
|
void UpgradeFactoryPresets();
|
||||||
void MaybeCopyDefaultPresets();
|
void MaybeCopyDefaultPresets();
|
||||||
static std::string SafeEncodeName(const std::string& name);
|
static std::string SafeEncodeName(const std::string& name);
|
||||||
|
|||||||
@@ -145,6 +145,7 @@ namespace pipedal
|
|||||||
const std::string &errorMessage) = 0;
|
const std::string &errorMessage) = 0;
|
||||||
|
|
||||||
virtual std::string Tone3000ThumbnailDirectory() = 0;
|
virtual std::string Tone3000ThumbnailDirectory() = 0;
|
||||||
|
virtual std::string OldTone3000ThumbnailDirectory() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
using self = Tone3000Downloader;
|
using self = Tone3000Downloader;
|
||||||
|
|||||||
+161
-141
@@ -48,7 +48,7 @@
|
|||||||
#define BANK_EXTENSION ".piBank"
|
#define BANK_EXTENSION ".piBank"
|
||||||
#define PLUGIN_PRESETS_EXTENSION ".piPluginPresets"
|
#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 PLUGIN_PRESETS_MIME_TYPE = "application/vnd.pipedal.pluginPresets";
|
||||||
static const std::string PRESET_MIME_TYPE = "application/vnd.pipedal.preset";
|
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_REFERENCE(UserUploadResponse, path)
|
||||||
JSON_MAP_END()
|
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();
|
std::string extension = path.extension();
|
||||||
const MimeTypes &mimeTypes = MimeTypes::instance();
|
const MimeTypes& mimeTypes = MimeTypes::instance();
|
||||||
auto result = mimeTypes.MimeTypeFromExtension(extension);
|
auto result = mimeTypes.MimeTypeFromExtension(extension);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -108,7 +108,7 @@ static bool IsSafeThumbnailPath(const fs::path path)
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
int32_t ConvertThumbnailSize(const std::string ¶m)
|
int32_t ConvertThumbnailSize(const std::string& param)
|
||||||
{
|
{
|
||||||
if (param.empty())
|
if (param.empty())
|
||||||
{
|
{
|
||||||
@@ -117,7 +117,7 @@ int32_t ConvertThumbnailSize(const std::string ¶m)
|
|||||||
return static_cast<int32_t>(std::stoi(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);
|
std::ifstream f(path);
|
||||||
if (!f.is_open())
|
if (!f.is_open())
|
||||||
@@ -135,15 +135,15 @@ static bool IsZipFile(const std::filesystem::path &path)
|
|||||||
class ExtensionChecker
|
class ExtensionChecker
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ExtensionChecker(const std::string &extensionList)
|
ExtensionChecker(const std::string& extensionList)
|
||||||
: extensions(split(extensionList, ','))
|
: extensions(split(extensionList, ','))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
bool IsValidExtension(const std::string &extension)
|
bool IsValidExtension(const std::string& extension)
|
||||||
{
|
{
|
||||||
if (extensions.size() == 0)
|
if (extensions.size() == 0)
|
||||||
return true;
|
return true;
|
||||||
for (const auto &ext : extensions)
|
for (const auto& ext : extensions)
|
||||||
{
|
{
|
||||||
if (ext == extension)
|
if (ext == extension)
|
||||||
return true;
|
return true;
|
||||||
@@ -155,7 +155,7 @@ private:
|
|||||||
std::vector<std::string> extensions;
|
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;
|
std::string stem = id;
|
||||||
// find a file in thumbnailDirectory which has a filename of {stem}.*.
|
// 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 {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &entry : fs::directory_iterator(thumbnailDirectory))
|
for (const auto& entry : fs::directory_iterator(thumbnailDirectory))
|
||||||
{
|
{
|
||||||
if (!entry.is_regular_file())
|
if (!entry.is_regular_file())
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const auto &path = entry.path();
|
const auto& path = entry.path();
|
||||||
if (path.stem() == stem)
|
if (path.stem() == stem)
|
||||||
{
|
{
|
||||||
return path;
|
return path;
|
||||||
@@ -179,18 +179,50 @@ static fs::path GetTone3000ThumbnailFile(const fs::path &thumbnailDirectory, con
|
|||||||
return {};
|
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
|
class DownloadIntercept : public RequestHandler
|
||||||
{
|
{
|
||||||
PiPedalModel *model;
|
PiPedalModel* model;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DownloadIntercept(PiPedalModel *model)
|
DownloadIntercept(PiPedalModel* model)
|
||||||
: RequestHandler("/var"),
|
: 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")
|
if (request_uri.segment_count() != 2 || request_uri.segment(0) != "var")
|
||||||
{
|
{
|
||||||
@@ -304,7 +336,7 @@ public:
|
|||||||
return false;
|
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::string fileName = name.substr(0, 64) + extension;
|
||||||
std::stringstream s;
|
std::stringstream s;
|
||||||
@@ -314,7 +346,7 @@ public:
|
|||||||
return result;
|
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");
|
std::string pluginUri = request_uri.query("id");
|
||||||
auto plugin = model->GetPluginHost().GetPluginInfo(pluginUri);
|
auto plugin = model->GetPluginHost().GetPluginInfo(pluginUri);
|
||||||
@@ -327,7 +359,7 @@ public:
|
|||||||
writer.write(pluginPresets);
|
writer.write(pluginPresets);
|
||||||
*pContent = s.str();
|
*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");
|
std::string strInstanceId = request_uri.query("id");
|
||||||
int64_t instanceId = std::stol(strInstanceId);
|
int64_t instanceId = std::stol(strInstanceId);
|
||||||
@@ -345,7 +377,7 @@ public:
|
|||||||
*pContent = s.str();
|
*pContent = s.str();
|
||||||
*pName = pedalboard.name();
|
*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");
|
std::string strInstanceId = request_uri.query("id");
|
||||||
int64_t instanceId = std::stol(strInstanceId);
|
int64_t instanceId = std::stol(strInstanceId);
|
||||||
@@ -360,10 +392,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void head_response(
|
virtual void head_response(
|
||||||
const uri &request_uri,
|
const uri& request_uri,
|
||||||
HttpRequest &req,
|
HttpRequest& req,
|
||||||
HttpResponse &res,
|
HttpResponse& res,
|
||||||
std::error_code &ec) override
|
std::error_code& ec) override
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -392,7 +424,11 @@ public:
|
|||||||
fs::path path = GetTone3000ThumbnailFile(this->model->Tone3000ThumbnailDirectory(), id);
|
fs::path path = GetTone3000ThumbnailFile(this->model->Tone3000ThumbnailDirectory(), id);
|
||||||
if (!fs::exists(path))
|
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);
|
auto mimeType = GetMimeType(path);
|
||||||
if (mimeType.empty())
|
if (mimeType.empty())
|
||||||
@@ -447,7 +483,7 @@ public:
|
|||||||
std::string content;
|
std::string content;
|
||||||
GetPluginPresets(request_uri, &name, &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::ptr presetbundleWriter = PresetBundleWriter::CreatePluginPresetsFile(*(this->model), content);
|
||||||
presetbundleWriter->WriteToFile(tmpFile.Path());
|
presetbundleWriter->WriteToFile(tmpFile.Path());
|
||||||
size_t contentLength = std::filesystem::file_size(tmpFile.Path());
|
size_t contentLength = std::filesystem::file_size(tmpFile.Path());
|
||||||
@@ -465,7 +501,7 @@ public:
|
|||||||
std::string content;
|
std::string content;
|
||||||
GetPreset(request_uri, &name, &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::ptr presetbundleWriter = PresetBundleWriter::CreatePresetsFile(*(this->model), content);
|
||||||
presetbundleWriter->WriteToFile(tmpFile.Path());
|
presetbundleWriter->WriteToFile(tmpFile.Path());
|
||||||
size_t contentLength = std::filesystem::file_size(tmpFile.Path());
|
size_t contentLength = std::filesystem::file_size(tmpFile.Path());
|
||||||
@@ -482,7 +518,7 @@ public:
|
|||||||
std::string content;
|
std::string content;
|
||||||
GetBank(request_uri, &name, &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::ptr presetbundleWriter = PresetBundleWriter::CreatePresetsFile(*(this->model), content);
|
||||||
presetbundleWriter->WriteToFile(tmpFile.Path());
|
presetbundleWriter->WriteToFile(tmpFile.Path());
|
||||||
size_t contentLength = std::filesystem::file_size(tmpFile.Path());
|
size_t contentLength = std::filesystem::file_size(tmpFile.Path());
|
||||||
@@ -495,7 +531,7 @@ public:
|
|||||||
}
|
}
|
||||||
throw PiPedalException("Not found.");
|
throw PiPedalException("Not found.");
|
||||||
}
|
}
|
||||||
catch (const std::exception &e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
if (strcmp(e.what(), "Not found") == 0)
|
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);
|
auto lastModified = std::filesystem::last_write_time(path);
|
||||||
res.set(HttpField::LastModified, HtmlHelper::timeToHttpDate(lastModified));
|
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,
|
return AudioDirectoryInfo::Create(path,
|
||||||
GetShadowIndexDirectory(
|
GetShadowIndexDirectory(
|
||||||
this->model->GetPluginUploadDirectory(),
|
this->model->GetPluginUploadDirectory(),
|
||||||
path));
|
path));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isInfoFile(const fs::path &path)
|
bool isInfoFile(const fs::path& path)
|
||||||
{
|
{
|
||||||
auto extension = path.extension();
|
auto extension = path.extension();
|
||||||
if (extension == ".pdf")
|
if (extension == ".pdf")
|
||||||
@@ -546,24 +582,24 @@ public:
|
|||||||
std::string T3kResponse()
|
std::string T3kResponse()
|
||||||
{
|
{
|
||||||
return "<html>\n"
|
return "<html>\n"
|
||||||
"<head>\n"
|
"<head>\n"
|
||||||
"<script>\n"
|
"<script>\n"
|
||||||
" window.close();"
|
" window.close();"
|
||||||
"</script>\n"
|
"</script>\n"
|
||||||
"</head>\n"
|
"</head>\n"
|
||||||
"<body>\n"
|
"<body>\n"
|
||||||
"</body>\n"
|
"</body>\n"
|
||||||
"</html>\n";
|
"</html>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void DownloadTone3000Tone(const uri &requestUri)
|
void DownloadTone3000Tone(const uri& requestUri)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
virtual void get_response(
|
virtual void get_response(
|
||||||
const uri &request_uri,
|
const uri& request_uri,
|
||||||
HttpRequest &req,
|
HttpRequest& req,
|
||||||
HttpResponse &res,
|
HttpResponse& res,
|
||||||
std::error_code &ec) override
|
std::error_code& ec) override
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -690,7 +726,7 @@ public:
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
auto files = audioDirectory->GetFiles();
|
auto files = audioDirectory->GetFiles();
|
||||||
for (const auto &file : files)
|
for (const auto& file : files)
|
||||||
{
|
{
|
||||||
std::string fileNameOnly = path.filename();
|
std::string fileNameOnly = path.filename();
|
||||||
if (file.fileName() == fileNameOnly)
|
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());
|
Lv2Log::error("Error getting audio directory info: %s - (%s)", path.c_str(), e.what());
|
||||||
throw e;
|
throw e;
|
||||||
@@ -761,7 +797,7 @@ public:
|
|||||||
|
|
||||||
thumbnailTemporaryFile = audioDirectory->GetThumbnail(path.filename(), width, height);
|
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";
|
fs::path defaultThumbnail = model->GetWebRoot() / "img/missing_thumbnail.jpg";
|
||||||
thumbnailTemporaryFile.SetNonDeletedPath(defaultThumbnail, "image/jpeg");
|
thumbnailTemporaryFile.SetNonDeletedPath(defaultThumbnail, "image/jpeg");
|
||||||
@@ -776,7 +812,7 @@ public:
|
|||||||
res.setBodyFile(t, thumbnailTemporaryFile.DeleteFile());
|
res.setBodyFile(t, thumbnailTemporaryFile.DeleteFile());
|
||||||
thumbnailTemporaryFile.Detach();
|
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());
|
Lv2Log::error("Error getting thumbnail: %s - (%s)", request_uri.str().c_str(), e.what());
|
||||||
throw e;
|
throw e;
|
||||||
@@ -809,7 +845,7 @@ public:
|
|||||||
|
|
||||||
res.setBody(ss.str());
|
res.setBody(ss.str());
|
||||||
}
|
}
|
||||||
catch (const std::exception &e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
res.setBody("\"\"");
|
res.setBody("\"\"");
|
||||||
}
|
}
|
||||||
@@ -841,7 +877,7 @@ public:
|
|||||||
|
|
||||||
res.setBody(ss.str());
|
res.setBody(ss.str());
|
||||||
}
|
}
|
||||||
catch (const std::exception &e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
res.setBody("\"\"");
|
res.setBody("\"\"");
|
||||||
}
|
}
|
||||||
@@ -852,7 +888,7 @@ public:
|
|||||||
throw PiPedalException("Not found");
|
throw PiPedalException("Not found");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (const std::exception &e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
if (strcmp(e.what(), "Not found") == 0)
|
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('/');
|
size_t nPos = fileName.find('/');
|
||||||
if (nPos != std::string::npos)
|
if (nPos != std::string::npos)
|
||||||
@@ -883,11 +919,11 @@ public:
|
|||||||
return fileNames[0];
|
return fileNames[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static bool HasSingleRootDirectory(ZipFileReader &zipFile)
|
static bool HasSingleRootDirectory(ZipFileReader& zipFile)
|
||||||
{
|
{
|
||||||
bool hasDirectory = false;
|
bool hasDirectory = false;
|
||||||
std::string previousDirectory;
|
std::string previousDirectory;
|
||||||
for (auto &file : zipFile.GetFiles())
|
for (auto& file : zipFile.GetFiles())
|
||||||
{
|
{
|
||||||
auto pos = file.find('/');
|
auto pos = file.find('/');
|
||||||
if (pos == std::string::npos)
|
if (pos == std::string::npos)
|
||||||
@@ -916,15 +952,15 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void UploadEmbeddedZipFile(
|
void UploadEmbeddedZipFile(
|
||||||
PiPedalModel *model,
|
PiPedalModel* model,
|
||||||
pipedal::zip_file_input_stream &si,
|
pipedal::zip_file_input_stream& si,
|
||||||
const std::string &inputFileName,
|
const std::string& inputFileName,
|
||||||
fs::path directory,
|
fs::path directory,
|
||||||
ExtensionChecker &extensionChecker,
|
ExtensionChecker& extensionChecker,
|
||||||
int64_t instanceId,
|
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.
|
// Extract the zip_file_input_stream to the temporary file.
|
||||||
{
|
{
|
||||||
std::ofstream out(tempFile.Path(), std::ios::binary);
|
std::ofstream out(tempFile.Path(), std::ios::binary);
|
||||||
@@ -955,11 +991,11 @@ public:
|
|||||||
{
|
{
|
||||||
directory = (fs::path(directory) / fs::path(inputFileName).filename().stem()).string();
|
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.
|
if (!inputFile.ends_with("/")) // don't process directory entries.
|
||||||
{
|
{
|
||||||
fs::path inputPath{inputFile};
|
fs::path inputPath{ inputFile };
|
||||||
std::string extension = inputPath.extension();
|
std::string extension = inputPath.extension();
|
||||||
if (extensionChecker.IsValidExtension(extension) || isInfoFile(inputFile))
|
if (extensionChecker.IsValidExtension(extension) || isInfoFile(inputFile))
|
||||||
{
|
{
|
||||||
@@ -985,10 +1021,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void post_response(
|
virtual void post_response(
|
||||||
const uri &request_uri,
|
const uri& request_uri,
|
||||||
HttpRequest &req,
|
HttpRequest& req,
|
||||||
HttpResponse &res,
|
HttpResponse& res,
|
||||||
std::error_code &ec) override
|
std::error_code& ec) override
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -1004,7 +1040,7 @@ public:
|
|||||||
{
|
{
|
||||||
throw std::runtime_error("Invalid path");
|
throw std::runtime_error("Invalid path");
|
||||||
}
|
}
|
||||||
if (!IsSafeMediaPath(targetPath) && !IsSafeThumbnailPath(targetPath))
|
if (!IsSafeMediaPath(targetPath) && !IsSafeThumbnailPath(targetPath))
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Unsafe path.");
|
throw std::runtime_error("Unsafe path.");
|
||||||
}
|
}
|
||||||
@@ -1024,24 +1060,26 @@ public:
|
|||||||
fs::rename(req.get_body_temporary_file(), targetPath);
|
fs::rename(req.get_body_temporary_file(), targetPath);
|
||||||
req.detach_body_temporary_file();
|
req.detach_body_temporary_file();
|
||||||
|
|
||||||
} catch (const std::exception &e) {
|
}
|
||||||
|
catch (const std::exception& e) {
|
||||||
// ok Copy into place instead.
|
// ok Copy into place instead.
|
||||||
fs::copy(req.get_body_temporary_file(), targetPath);
|
fs::copy(req.get_body_temporary_file(), targetPath);
|
||||||
}
|
}
|
||||||
// set target permissions to "pipedal_d:pipedald -rw-rw-r-- if we can.
|
// set target permissions to "pipedal_d:pipedald -rw-rw-r-- if we can.
|
||||||
try {
|
try {
|
||||||
fs::permissions(targetPath, fs::perms::owner_read | fs::perms::owner_write |
|
fs::permissions(targetPath, fs::perms::owner_read | fs::perms::owner_write |
|
||||||
fs::perms::group_read | fs::perms::group_write |
|
fs::perms::group_read | fs::perms::group_write |
|
||||||
fs::perms::others_read,
|
fs::perms::others_read,
|
||||||
fs::perm_options::replace);
|
fs::perm_options::replace);
|
||||||
} catch (const std::exception&)
|
}
|
||||||
|
catch (const std::exception&)
|
||||||
{
|
{
|
||||||
// ignore.
|
// ignore.
|
||||||
}
|
}
|
||||||
|
|
||||||
responseText = "{\"ok\": true}";
|
responseText = "{\"ok\": true}";
|
||||||
}
|
}
|
||||||
catch (const std::exception &e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
std::string jsonString = json_writer::encode_string(e.what());
|
std::string jsonString = json_writer::encode_string(e.what());
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
@@ -1131,28 +1169,7 @@ public:
|
|||||||
else if (segment == "uploadBank")
|
else if (segment == "uploadBank")
|
||||||
{
|
{
|
||||||
|
|
||||||
BankFile bankFile;
|
|
||||||
|
|
||||||
fs::path filePath = req.get_body_temporary_file();
|
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;
|
uint64_t uploadAfter = -1;
|
||||||
std::string strUploadAfter = request_uri.query("uploadAfter");
|
std::string strUploadAfter = request_uri.query("uploadAfter");
|
||||||
@@ -1161,10 +1178,13 @@ public:
|
|||||||
uploadAfter = std::stol(strUploadAfter);
|
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::content_type, "application/json");
|
||||||
res.set(HttpField::cache_control, "no-cache");
|
res.set(HttpField::cache_control, "no-cache");
|
||||||
|
|
||||||
|
|
||||||
std::stringstream sResult;
|
std::stringstream sResult;
|
||||||
sResult << instanceId;
|
sResult << instanceId;
|
||||||
std::string result = sResult.str();
|
std::string result = sResult.str();
|
||||||
@@ -1187,7 +1207,7 @@ public:
|
|||||||
|
|
||||||
int64_t instanceId;
|
int64_t instanceId;
|
||||||
{
|
{
|
||||||
std::istringstream ss{instanceIdString};
|
std::istringstream ss{ instanceIdString };
|
||||||
ss >> instanceId;
|
ss >> instanceId;
|
||||||
if (!ss)
|
if (!ss)
|
||||||
{
|
{
|
||||||
@@ -1207,7 +1227,7 @@ public:
|
|||||||
|
|
||||||
if (filename.ends_with(".zip"))
|
if (filename.ends_with(".zip"))
|
||||||
{
|
{
|
||||||
ExtensionChecker extensionChecker{request_uri.query("ext")};
|
ExtensionChecker extensionChecker{ request_uri.query("ext") };
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -1219,11 +1239,11 @@ public:
|
|||||||
{
|
{
|
||||||
directory = (fs::path(directory) / fs::path(filename).filename().replace_extension("")).string();
|
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.
|
if (!inputFile.ends_with("/")) // don't process directory entries.
|
||||||
{
|
{
|
||||||
fs::path inputPath{inputFile};
|
fs::path inputPath{ inputFile };
|
||||||
std::string extension = inputPath.extension();
|
std::string extension = inputPath.extension();
|
||||||
if (extensionChecker.IsValidExtension(extension) || isInfoFile(inputFile))
|
if (extensionChecker.IsValidExtension(extension) || isInfoFile(inputFile))
|
||||||
{
|
{
|
||||||
@@ -1251,7 +1271,7 @@ public:
|
|||||||
std::string returnPath = GetFirstFolderOrFile(files);
|
std::string returnPath = GetFirstFolderOrFile(files);
|
||||||
outputFileName = fs::path(directory) / returnPath;
|
outputFileName = fs::path(directory) / returnPath;
|
||||||
}
|
}
|
||||||
catch (const std::exception &e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
Lv2Log::error(SS("Unzip failed. " << e.what()));
|
Lv2Log::error(SS("Unzip failed. " << e.what()));
|
||||||
throw;
|
throw;
|
||||||
@@ -1269,7 +1289,7 @@ public:
|
|||||||
}
|
}
|
||||||
result.path_ = outputFileName.string();
|
result.path_ = outputFileName.string();
|
||||||
}
|
}
|
||||||
catch (const std::exception &e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
result.errorMessage_ = e.what();
|
result.errorMessage_ = e.what();
|
||||||
}
|
}
|
||||||
@@ -1287,7 +1307,7 @@ public:
|
|||||||
throw PiPedalException("Not found");
|
throw PiPedalException("Not found");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (const std::exception &e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
Lv2Log::error(SS("Error uploading file: " << e.what()));
|
Lv2Log::error(SS("Error uploading file: " << e.what()));
|
||||||
if (strcmp(e.what(), "Not found") == 0)
|
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;
|
std::string address = fromAddress;
|
||||||
|
|
||||||
@@ -1335,19 +1355,19 @@ static std::string StripPortNumber(const std::string &fromAddress)
|
|||||||
class InterceptConfig : public RequestHandler
|
class InterceptConfig : public RequestHandler
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
PiPedalModel&model;
|
PiPedalModel& model;
|
||||||
uint64_t maxUploadSize;
|
uint64_t maxUploadSize;
|
||||||
int portNumber;
|
int portNumber;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
InterceptConfig(PiPedalModel&model,int portNumber, uint64_t maxUploadSize)
|
InterceptConfig(PiPedalModel& model, int portNumber, uint64_t maxUploadSize)
|
||||||
: RequestHandler("/var/config.json"),
|
: RequestHandler("/var/config.json"),
|
||||||
model(model),
|
model(model),
|
||||||
maxUploadSize(maxUploadSize),
|
maxUploadSize(maxUploadSize),
|
||||||
portNumber(portNumber)
|
portNumber(portNumber)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
std::string GetConfig(const std::string &fromAddress)
|
std::string GetConfig(const std::string& fromAddress)
|
||||||
{
|
{
|
||||||
std::string webSocketAddress = GetNonLinkLocalAddress(StripPortNumber(fromAddress));
|
std::string webSocketAddress = GetNonLinkLocalAddress(StripPortNumber(fromAddress));
|
||||||
Lv2Log::info(SS("Web Socket Address: " << webSocketAddress << ":" << portNumber));
|
Lv2Log::info(SS("Web Socket Address: " << webSocketAddress << ":" << portNumber));
|
||||||
@@ -1355,32 +1375,32 @@ public:
|
|||||||
std::stringstream s;
|
std::stringstream s;
|
||||||
|
|
||||||
s << "{ \"socket_server_port\": " << portNumber
|
s << "{ \"socket_server_port\": " << portNumber
|
||||||
<< ", \"socket_server_address\": \"" << webSocketAddress
|
<< ", \"socket_server_address\": \"" << webSocketAddress
|
||||||
<< "\", \"ui_plugins\": [ ], \"max_upload_size\": " << maxUploadSize
|
<< "\", \"ui_plugins\": [ ], \"max_upload_size\": " << maxUploadSize
|
||||||
<< ", \"enable_auto_update\": " << (ENABLE_AUTO_UPDATE ? " true" : "false")
|
<< ", \"enable_auto_update\": " << (ENABLE_AUTO_UPDATE ? " true" : "false")
|
||||||
<< ", \"has_wifi_device\": " << (HotspotManager::HasWifiDevice() ? " true" : "false")
|
<< ", \"has_wifi_device\": " << (HotspotManager::HasWifiDevice() ? " true" : "false")
|
||||||
<< ", \"tone3000_A2_models\": " << (model.Configuration().GetTone3000A2Models() ? " true" : "false")
|
<< ", \"tone3000_A2_models\": " << (model.Configuration().GetTone3000A2Models() ? " true" : "false")
|
||||||
<< " }";
|
<< " }";
|
||||||
|
|
||||||
return s.str();
|
return s.str();
|
||||||
}
|
}
|
||||||
virtual ~InterceptConfig() {}
|
virtual ~InterceptConfig() {}
|
||||||
|
|
||||||
virtual void head_response(
|
virtual void head_response(
|
||||||
const uri &request_uri,
|
const uri& request_uri,
|
||||||
HttpRequest &req,
|
HttpRequest& req,
|
||||||
HttpResponse &res,
|
HttpResponse& res,
|
||||||
std::error_code &ec) override
|
std::error_code& ec) override
|
||||||
{
|
{
|
||||||
// intercepted. See the other overload.
|
// intercepted. See the other overload.
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void head_response(
|
virtual void head_response(
|
||||||
const std::string &fromAddress,
|
const std::string& fromAddress,
|
||||||
const uri &request_uri,
|
const uri& request_uri,
|
||||||
HttpRequest &req,
|
HttpRequest& req,
|
||||||
HttpResponse &res,
|
HttpResponse& res,
|
||||||
std::error_code &ec) override
|
std::error_code& ec) override
|
||||||
{
|
{
|
||||||
std::string response = GetConfig(fromAddress);
|
std::string response = GetConfig(fromAddress);
|
||||||
res.set(HttpField::content_type, "application/json");
|
res.set(HttpField::content_type, "application/json");
|
||||||
@@ -1390,20 +1410,20 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void get_response(
|
virtual void get_response(
|
||||||
const uri &request_uri,
|
const uri& request_uri,
|
||||||
HttpRequest &req,
|
HttpRequest& req,
|
||||||
HttpResponse &res,
|
HttpResponse& res,
|
||||||
std::error_code &ec) override
|
std::error_code& ec) override
|
||||||
{
|
{
|
||||||
// intercepted. see the other overload.
|
// intercepted. see the other overload.
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void get_response(
|
virtual void get_response(
|
||||||
const std::string &fromAddress,
|
const std::string& fromAddress,
|
||||||
const uri &request_uri,
|
const uri& request_uri,
|
||||||
HttpRequest &req,
|
HttpRequest& req,
|
||||||
HttpResponse &res,
|
HttpResponse& res,
|
||||||
std::error_code &ec) override
|
std::error_code& ec) override
|
||||||
{
|
{
|
||||||
std::string response = GetConfig(fromAddress);
|
std::string response = GetConfig(fromAddress);
|
||||||
res.set(HttpField::content_type, "application/json");
|
res.set(HttpField::content_type, "application/json");
|
||||||
@@ -1414,12 +1434,12 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
void pipedal::ConfigureWebServer(
|
void pipedal::ConfigureWebServer(
|
||||||
WebServer &server,
|
WebServer& server,
|
||||||
PiPedalModel &model,
|
PiPedalModel& model,
|
||||||
int port,
|
int port,
|
||||||
size_t maxUploadSize)
|
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);
|
server.AddRequestHandler(interceptConfig);
|
||||||
|
|
||||||
std::shared_ptr<DownloadIntercept> downloadIntercept = std::make_shared<DownloadIntercept>(&model);
|
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.
|
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?
|
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.
|
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.
|
summaries for Mono audio adapaters.
|
||||||
Check PWA on windows, edge and chrome.
|
Check PWA on windows, edge and chrome.
|
||||||
Make sure Pi 4 default audio device is still hidden when selecting devices!
|
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?
|
sAFEfILEnAMES: RENAME, &C. Safe bank names?
|
||||||
NEW BANK
|
NEW BANK
|
||||||
WINDOW SIZE CALCUALTIONS ARE WRONG ON LINUX HIDEF DISPLAYS.
|
WINDOW SIZE CALCUALTIONS ARE WRONG ON LINUX HIDEF DISPLAYS.
|
||||||
|
|
||||||
Carla Project icons.
|
|
||||||
check reload after change of LV2 plugins.
|
check reload after change of LV2 plugins.
|
||||||
|
|
||||||
Exactly one underrun per seek in Toob Player
|
|
||||||
|
|
||||||
|
|
||||||
json nan/inf is fatal.
|
|
||||||
|
|
||||||
- pipewire aux in?
|
- pipewire aux in?
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user