@@ -30,7 +30,7 @@ jobs:
|
|||||||
sudo apt install libasound2-dev
|
sudo apt install libasound2-dev
|
||||||
sudo apt install libwebsocketpp-dev authbind
|
sudo apt install libwebsocketpp-dev authbind
|
||||||
sudo apt install libsdbus-c++-dev libsdbus-c++-bin
|
sudo apt install libsdbus-c++-dev libsdbus-c++-bin
|
||||||
sudo apt install libavahi-client-dev libzip-dev libicu-dev
|
sudo apt install libavahi-client-dev libzip-dev libicu-dev apt
|
||||||
git submodule update --init --recursive
|
git submodule update --init --recursive
|
||||||
./react-config
|
./react-config
|
||||||
|
|
||||||
|
|||||||
Vendored
+32
@@ -172,6 +172,38 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "(gdb) profilePlugin Launch",
|
||||||
|
"type": "cppdbg",
|
||||||
|
"request": "launch",
|
||||||
|
// Resolved by CMake Tools:
|
||||||
|
"program": "${command:cmake.launchTargetPath}",
|
||||||
|
|
||||||
|
"args": [ "Nam_Profile", "--no-profile","-w" ],
|
||||||
|
|
||||||
|
"stopAtEntry": false,
|
||||||
|
"cwd": "${workspaceFolder}",
|
||||||
|
"environment": [
|
||||||
|
{
|
||||||
|
"name": "PATH",
|
||||||
|
"value": "$PATH:${command:cmake.launchTargetDirectory}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "OTHER_VALUE",
|
||||||
|
"value": "Something something"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"externalConsole": false,
|
||||||
|
"MIMode": "gdb",
|
||||||
|
"setupCommands": [
|
||||||
|
{
|
||||||
|
"description": "Enable pretty-printing for gdb",
|
||||||
|
"text": "-enable-pretty-printing",
|
||||||
|
"ignoreFailures": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|||||||
+2
-2
@@ -1,10 +1,10 @@
|
|||||||
cmake_minimum_required(VERSION 3.16.0)
|
cmake_minimum_required(VERSION 3.16.0)
|
||||||
project(pipedal
|
project(pipedal
|
||||||
VERSION 1.2.45
|
VERSION 1.2.47
|
||||||
DESCRIPTION "PiPedal Guitar Effect Pedal For Raspberry Pi"
|
DESCRIPTION "PiPedal Guitar Effect Pedal For Raspberry Pi"
|
||||||
HOMEPAGE_URL "https://rerdavies.github.io/pipedal"
|
HOMEPAGE_URL "https://rerdavies.github.io/pipedal"
|
||||||
)
|
)
|
||||||
set (DISPLAY_VERSION "PiPedal v1.2.45-Release")
|
set (DISPLAY_VERSION "PiPedal v1.2.47-Release")
|
||||||
set (PACKAGE_ARCHITECTURE "arm64")
|
set (PACKAGE_ARCHITECTURE "arm64")
|
||||||
set (CMAKE_INSTALL_PREFIX "/usr/")
|
set (CMAKE_INSTALL_PREFIX "/usr/")
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include "ss.hpp"
|
#include "ss.hpp"
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include "ofstream_synced.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace impl {
|
namespace impl {
|
||||||
@@ -72,7 +73,7 @@ public:
|
|||||||
f << "trace: " << message << std::endl;
|
f << "trace: " << message << std::endl;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
std::ofstream f;
|
pipedal::ofstream_synced f;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SystemdDBusLogger : public IDBusLogger {
|
class SystemdDBusLogger : public IDBusLogger {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include "ChannelInfo.hpp"
|
#include "ChannelInfo.hpp"
|
||||||
#include "DBusLog.hpp"
|
#include "DBusLog.hpp"
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include "ofstream_synced.hpp"
|
||||||
|
|
||||||
using namespace pipedal;
|
using namespace pipedal;
|
||||||
P2pSettings::P2pSettings(const std::filesystem::path&configDirectoryPath, const std::filesystem::path&varDirectoryPath)
|
P2pSettings::P2pSettings(const std::filesystem::path&configDirectoryPath, const std::filesystem::path&varDirectoryPath)
|
||||||
@@ -193,7 +194,7 @@ void P2pSettings::Load()
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void openWithPerms(
|
static void openWithPerms(
|
||||||
std::ofstream &f,
|
pipedal::ofstream_synced &f,
|
||||||
const std::filesystem::path &path,
|
const std::filesystem::path &path,
|
||||||
std::filesystem::perms perms =
|
std::filesystem::perms perms =
|
||||||
std::filesystem::perms::owner_read | std::filesystem::perms::owner_write |
|
std::filesystem::perms::owner_read | std::filesystem::perms::owner_write |
|
||||||
@@ -221,7 +222,7 @@ void P2pSettings::Save()
|
|||||||
{
|
{
|
||||||
auto filename = config_filename();
|
auto filename = config_filename();
|
||||||
try {
|
try {
|
||||||
std::ofstream f;
|
pipedal::ofstream_synced f;
|
||||||
openWithPerms(f,filename);
|
openWithPerms(f,filename);
|
||||||
|
|
||||||
if (!f.is_open())
|
if (!f.is_open())
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ message(STATUS "NMPIPEDAL CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}")
|
|||||||
|
|
||||||
# Use the sdbus-c++ target in SDBusCpp namespace
|
# Use the sdbus-c++ target in SDBusCpp namespace
|
||||||
add_library(PiPedalCommon STATIC
|
add_library(PiPedalCommon STATIC
|
||||||
|
ofstream_synced.cpp include/ofstream_synced.hpp
|
||||||
ConfigSerializer.cpp include/ConfigSerializer.hpp
|
ConfigSerializer.cpp include/ConfigSerializer.hpp
|
||||||
WifiRegs.cpp include/WifiRegs.hpp
|
WifiRegs.cpp include/WifiRegs.hpp
|
||||||
WifiRegulations.cpp include/WifiRegulations.hpp
|
WifiRegulations.cpp include/WifiRegulations.hpp
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
#include "ofstream_synced.hpp"
|
||||||
|
|
||||||
using namespace pipedal;
|
using namespace pipedal;
|
||||||
|
|
||||||
@@ -65,7 +66,7 @@ void ServiceConfiguration::Save()
|
|||||||
std::filesystem::create_directories(directory);
|
std::filesystem::create_directories(directory);
|
||||||
|
|
||||||
// make sure the file has correct permissions.
|
// make sure the file has correct permissions.
|
||||||
std::ofstream t;
|
pipedal::ofstream_synced t;
|
||||||
t.open(filename);
|
t.open(filename);
|
||||||
t.close();
|
t.close();
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include "WriteTemplateFile.hpp"
|
#include "WriteTemplateFile.hpp"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include "ofstream_synced.hpp"
|
||||||
|
|
||||||
using namespace pipedal;
|
using namespace pipedal;
|
||||||
|
|
||||||
@@ -37,7 +38,7 @@ void pipedal::WriteTemplateFile(
|
|||||||
const std::filesystem::path &inputFile,
|
const std::filesystem::path &inputFile,
|
||||||
const std::filesystem::path &outputFile)
|
const std::filesystem::path &outputFile)
|
||||||
{
|
{
|
||||||
std::ofstream out(outputFile);
|
pipedal::ofstream_synced out(outputFile);
|
||||||
std::ifstream in(inputFile);
|
std::ifstream in(inputFile);
|
||||||
|
|
||||||
if (!in.is_open())
|
if (!in.is_open())
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
#include "autoptr_vector.h"
|
#include "autoptr_vector.h"
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include "ofstream_synced.hpp"
|
||||||
|
|
||||||
namespace config_serializer
|
namespace config_serializer
|
||||||
{
|
{
|
||||||
@@ -256,7 +257,7 @@ namespace config_serializer
|
|||||||
}
|
}
|
||||||
void Save(const std::string &path)
|
void Save(const std::string &path)
|
||||||
{
|
{
|
||||||
std::ofstream f;
|
pipedal::ofstream_synced f;
|
||||||
f.open(path);
|
f.open(path);
|
||||||
if (!f.is_open())
|
if (!f.is_open())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
namespace pipedal
|
||||||
|
{
|
||||||
|
void FileSystemSync();
|
||||||
|
|
||||||
|
class ofstream_synced : public std::ofstream
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using super = std::ofstream;
|
||||||
|
ofstream_synced() {}
|
||||||
|
|
||||||
|
explicit ofstream_synced(const std::string &filename, ios_base::openmode mode = ios_base::out)
|
||||||
|
: std::ofstream(filename, mode)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
explicit ofstream_synced(const char *filename, ios_base::openmode mode = ios_base::out)
|
||||||
|
: std::ofstream(filename, mode)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void close();
|
||||||
|
~ofstream_synced();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
#include "ofstream_synced.hpp"
|
||||||
|
#include "unistd.h"
|
||||||
|
|
||||||
|
using namespace pipedal;
|
||||||
|
|
||||||
|
|
||||||
|
void pipedal::FileSystemSync()
|
||||||
|
{
|
||||||
|
::sync();
|
||||||
|
}
|
||||||
|
void ofstream_synced::close() {
|
||||||
|
if (is_open())
|
||||||
|
{
|
||||||
|
super::close();
|
||||||
|
::sync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ofstream_synced::~ofstream_synced()
|
||||||
|
{
|
||||||
|
ofstream_synced::close();
|
||||||
|
}
|
||||||
@@ -6,13 +6,13 @@
|
|||||||
<a href="https://rerdavies.github.io/pipedal/LicensePiPedal.html"><img src="https://img.shields.io/badge/MIT-MIT?label=license&color=%23808080"/></a>
|
<a href="https://rerdavies.github.io/pipedal/LicensePiPedal.html"><img src="https://img.shields.io/badge/MIT-MIT?label=license&color=%23808080"/></a>
|
||||||
<a href="https://github.com/rerdavies/pipedal/actions"><img src="https://img.shields.io/github/actions/workflow/status/rerdavies/pipedal/cmake.yml?branch=main"/></a>
|
<a href="https://github.com/rerdavies/pipedal/actions"><img src="https://img.shields.io/github/actions/workflow/status/rerdavies/pipedal/cmake.yml?branch=main"/></a>
|
||||||
|
|
||||||
Download: <a href='https://rerdavies.github.io/pipedal/download.html'>v1.2.45</a>
|
Download: <a href='https://rerdavies.github.io/pipedal/download.html'>v1.2.47</a>
|
||||||
Website: [https://rerdavies.github.io/pipedal](https://rerdavies.github.io/pipedal).
|
Website: [https://rerdavies.github.io/pipedal](https://rerdavies.github.io/pipedal).
|
||||||
Documentation: [https://rerdavies.github.io/pipedal/Documentation.html](https://rerdavies.github.io/pipedal/Documentation.html).
|
Documentation: [https://rerdavies.github.io/pipedal/Documentation.html](https://rerdavies.github.io/pipedal/Documentation.html).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#### NEW version 1.2.45 Release, providing support for Raspberry Pi OS Bookworm. See the [release notes](https://rerdavies.github.io/pipedal/ReleaseNotes) for details.
|
#### NEW version 1.2.47 Release, providing support for Raspberry Pi OS Bookworm. See the [release notes](https://rerdavies.github.io/pipedal/ReleaseNotes) for details.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ Run the following commands to install dependent libraries required by the PiPeda
|
|||||||
sudo apt install -y authbind
|
sudo apt install -y authbind
|
||||||
sudo apt install -y libavahi-client-dev
|
sudo apt install -y libavahi-client-dev
|
||||||
sudo apt install -y libnm-dev libicu-dev
|
sudo apt install -y libnm-dev libicu-dev
|
||||||
sudo apt install -y libsdbus-c++-dev libzip-dev
|
sudo apt install -y libsdbus-c++-dev libzip-dev google-perftools libgoogle-perftools-dev
|
||||||
|
|
||||||
|
|
||||||
### Installing Sources
|
### Installing Sources
|
||||||
|
|||||||
+3
-3
@@ -13,17 +13,17 @@ page_icon: img/Install4.jpg
|
|||||||
|
|
||||||
Download the most recent Debian (.deb) package for your platform:
|
Download the most recent Debian (.deb) package for your platform:
|
||||||
|
|
||||||
- [Raspberry Pi OS bookworm (64-bit) v1.2.45](https://github.com/rerdavies/pipedal/releases/download/)
|
- [Raspberry Pi OS bookworm (64-bit) v1.2.47](https://github.com/rerdavies/pipedal/releases/download/)
|
||||||
- [Ubuntu/Raspberry Pi OS bullseyeye (64-bit) v1.2.31](https://github.com/rerdavies/pipedal/releases/download/v1.1.31/pipedal_1.1.31_arm64.deb)
|
- [Ubuntu/Raspberry Pi OS bullseyeye (64-bit) v1.2.31](https://github.com/rerdavies/pipedal/releases/download/v1.1.31/pipedal_1.1.31_arm64.deb)
|
||||||
|
|
||||||
Version 1.2.45 has not yet been tested on Ubuntu or Raspberry Pi OS bullseye. On these platforms, we recommend that you use version 1.1.31.
|
Version 1.2.47 has not yet been tested on Ubuntu or Raspberry Pi OS bullseye. On these platforms, we recommend that you use version 1.1.31.
|
||||||
|
|
||||||
Install the package by running
|
Install the package by running
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo apt update
|
sudo apt update
|
||||||
cd ~/Downloads
|
cd ~/Downloads
|
||||||
sudo apt-get install pipedal_1.2.45_arm64.deb
|
sudo apt-get install pipedal_1.2.47_arm64.deb
|
||||||
```
|
```
|
||||||
Adjust accordingly if you have downloaded v1.1.31.
|
Adjust accordingly if you have downloaded v1.1.31.
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,13 @@
|
|||||||
# Release Notes
|
# Release Notes
|
||||||
|
## PiPedal 1.2.47 Release
|
||||||
|
|
||||||
|
This version fixes an significant and dangerous defect that may cause loss of presets, banks or configuration data if you remove power from your Raspberry Pi within up to five minutes of last saving data instead of performing an orderly shutdown or reboot. Users of PiPedal should upgrade immediately.
|
||||||
|
|
||||||
|
This release also fixes a significant performance issue with TooB Neural Amp Modeler.
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
- Explicity sync files to disk immiately after saving, so that they won't be lost if power is removed from the Raspberry Pi.
|
||||||
|
- Fixes a significant performance issue with TooB Neural Amp Modeler.
|
||||||
|
|
||||||
## PiPedal 1.2.45 Release
|
## PiPedal 1.2.45 Release
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -4,17 +4,17 @@
|
|||||||
|
|
||||||
Download the most recent Debian (.deb) package for your platform:
|
Download the most recent Debian (.deb) package for your platform:
|
||||||
|
|
||||||
- <a href="https://github.com/rerdavies/pipedal/releases/download/v1.2.45/pipedal_1.2.45_arm64.deb">Raspberry Pi OS Bookworm (64-bit) v1.2.45</a>
|
- <a href="https://github.com/rerdavies/pipedal/releases/download/v1.2.47/pipedal_1.2.47_arm64.deb">Raspberry Pi OS Bookworm (64-bit) v1.2.47</a>
|
||||||
- <a href="https://github.com/rerdavies/pipedal/releases/download/v1.1.31/pipedal_1.1.31_arm64.deb">Ubuntu 21.04 or Raspberry Pi OS bullseyeyeye (64-bit) v1.1.31</a>
|
- <a href="https://github.com/rerdavies/pipedal/releases/download/v1.1.31/pipedal_1.1.31_arm64.deb">Ubuntu 21.04 or Raspberry Pi OS bullseyeyeye (64-bit) v1.1.31</a>
|
||||||
|
|
||||||
v1.2.45 is does not currently support Ubuntu 21.04, or older versions of Raspberry Pi OS.
|
v1.2.47 is does not currently support Ubuntu 21.04, or older versions of Raspberry Pi OS.
|
||||||
|
|
||||||
Install the package by running
|
Install the package by running
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo apt update
|
sudo apt update
|
||||||
cd ~/Downloads
|
cd ~/Downloads
|
||||||
sudo apt-get install ./pipedal_1.2.45_arm64.deb
|
sudo apt-get install ./pipedal_1.2.47_arm64.deb
|
||||||
```
|
```
|
||||||
|
|
||||||
Follow the instructions in [_Configuring PiPedal After Installation_](https://rerdavies.github.io/pipedal/Configuring.html) to complete the installation.
|
Follow the instructions in [_Configuring PiPedal After Installation_](https://rerdavies.github.io/pipedal/Configuring.html) to complete the installation.
|
||||||
|
|||||||
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<img src="GithubBanner.png" width="100%"/>
|
<img src="GithubBanner.png" width="100%"/>
|
||||||
<a href="Installing.html"><i>v1.2.45</i></a>
|
<a href="Installing.html"><i>v1.2.47</i></a>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -9,7 +9,7 @@ To download PiPedal, click [here](download.md).
|
|||||||
To view PiPedal documentation, click [here](Documentation.md).
|
To view PiPedal documentation, click [here](Documentation.md).
|
||||||
|
|
||||||
|
|
||||||
#### NEW version 1.2.45 Release. See the [release notes](https://rerdavies.github.io/pipedal/ReleaseNotes) for details.
|
#### NEW version 1.2.47 Release. See the [release notes](https://rerdavies.github.io/pipedal/ReleaseNotes) for details.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ cabir:impulseFile3
|
|||||||
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
||||||
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
||||||
lv2:minorVersion 0 ;
|
lv2:minorVersion 0 ;
|
||||||
lv2:microVersion 45 ;
|
lv2:microVersion 47 ;
|
||||||
rdfs:comment """
|
rdfs:comment """
|
||||||
|
|
||||||
TooB Cab IR is a convolution-based guitar cabinet impulse response simulator.
|
TooB Cab IR is a convolution-based guitar cabinet impulse response simulator.
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ toob:frequencyResponseVector
|
|||||||
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
||||||
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
||||||
lv2:minorVersion 0 ;
|
lv2:minorVersion 0 ;
|
||||||
lv2:microVersion 45 ;
|
lv2:microVersion 47 ;
|
||||||
|
|
||||||
mod:brand "TooB";
|
mod:brand "TooB";
|
||||||
mod:label "TooB CabSim";
|
mod:label "TooB CabSim";
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ toobimpulse:impulseFile
|
|||||||
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
||||||
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
||||||
lv2:minorVersion 0 ;
|
lv2:minorVersion 0 ;
|
||||||
lv2:microVersion 45 ;
|
lv2:microVersion 47 ;
|
||||||
rdfs:comment """
|
rdfs:comment """
|
||||||
|
|
||||||
Convolution reverb is a notoriously compute-intensive effect. If you are having performance issues, use the Max T control to constrain the length of the impulse file to
|
Convolution reverb is a notoriously compute-intensive effect. If you are having performance issues, use the Max T control to constrain the length of the impulse file to
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ toobimpulse:impulseFile
|
|||||||
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
||||||
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
||||||
lv2:minorVersion 0 ;
|
lv2:minorVersion 0 ;
|
||||||
lv2:microVersion 45 ;
|
lv2:microVersion 47 ;
|
||||||
rdfs:comment """
|
rdfs:comment """
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ inputStage:filterGroup
|
|||||||
doap:license <https://two-play.com/TooB/licenses/isc> ;
|
doap:license <https://two-play.com/TooB/licenses/isc> ;
|
||||||
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
||||||
lv2:minorVersion 0 ;
|
lv2:minorVersion 0 ;
|
||||||
lv2:microVersion 45 ;
|
lv2:microVersion 47 ;
|
||||||
|
|
||||||
mod:brand "TooB";
|
mod:brand "TooB";
|
||||||
mod:label "TooB Input";
|
mod:label "TooB Input";
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ pstage:stage3
|
|||||||
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
||||||
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
||||||
lv2:minorVersion 0 ;
|
lv2:minorVersion 0 ;
|
||||||
lv2:microVersion 29 ;
|
lv2:microVersion 47 ;
|
||||||
|
|
||||||
mod:brand "TooB";
|
mod:brand "TooB";
|
||||||
mod:label "Power Stage";
|
mod:label "Power Stage";
|
||||||
|
|||||||
@@ -58,7 +58,7 @@
|
|||||||
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
||||||
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
||||||
lv2:minorVersion 0 ;
|
lv2:minorVersion 0 ;
|
||||||
lv2:microVersion 45 ;
|
lv2:microVersion 47 ;
|
||||||
rdfs:comment "TooB spectrum analyzer" ;
|
rdfs:comment "TooB spectrum analyzer" ;
|
||||||
|
|
||||||
mod:brand "TooB";
|
mod:brand "TooB";
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ tonestack:eqGroup
|
|||||||
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
||||||
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
||||||
lv2:minorVersion 0 ;
|
lv2:minorVersion 0 ;
|
||||||
lv2:microVersion 45 ;
|
lv2:microVersion 47 ;
|
||||||
|
|
||||||
uiext:ui <http://two-play.com/plugins/toob-tone-stack-ui>;
|
uiext:ui <http://two-play.com/plugins/toob-tone-stack-ui>;
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
ToobAmp.so.1.1.45
|
ToobAmp.so.1.1.47
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -40,7 +40,7 @@
|
|||||||
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
||||||
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
||||||
lv2:minorVersion 0 ;
|
lv2:minorVersion 0 ;
|
||||||
lv2:microVersion 45 ;
|
lv2:microVersion 47 ;
|
||||||
rdfs:comment """
|
rdfs:comment """
|
||||||
Emulation of a Boss CE-2 Chorus.
|
Emulation of a Boss CE-2 Chorus.
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@
|
|||||||
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
||||||
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
||||||
lv2:minorVersion 0 ;
|
lv2:minorVersion 0 ;
|
||||||
lv2:microVersion 45 ;
|
lv2:microVersion 47 ;
|
||||||
rdfs:comment """
|
rdfs:comment """
|
||||||
A straightforward no-frills digital delay.
|
A straightforward no-frills digital delay.
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@
|
|||||||
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
||||||
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
||||||
lv2:minorVersion 0 ;
|
lv2:minorVersion 0 ;
|
||||||
lv2:microVersion 45 ;
|
lv2:microVersion 47 ;
|
||||||
rdfs:comment """
|
rdfs:comment """
|
||||||
Emulation of a Boss BF-2 Flanger, based on circuit analysis and simulation of the original.
|
Emulation of a Boss BF-2 Flanger, based on circuit analysis and simulation of the original.
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@
|
|||||||
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
||||||
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
||||||
lv2:minorVersion 0 ;
|
lv2:minorVersion 0 ;
|
||||||
lv2:microVersion 45 ;
|
lv2:microVersion 47 ;
|
||||||
rdfs:comment """
|
rdfs:comment """
|
||||||
Digital emulation of a Boss BF-2 Flanger.
|
Digital emulation of a Boss BF-2 Flanger.
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@
|
|||||||
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
||||||
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
||||||
lv2:minorVersion 0 ;
|
lv2:minorVersion 0 ;
|
||||||
lv2:microVersion 45 ;
|
lv2:microVersion 47 ;
|
||||||
rdfs:comment """
|
rdfs:comment """
|
||||||
Toob Freeverb is an Lv2 implementation of the famous Freeverb reverb effect. FreeVerb delivers a well-balanced reverb with very little tonal coloration.
|
Toob Freeverb is an Lv2 implementation of the famous Freeverb reverb effect. FreeVerb delivers a well-balanced reverb with very little tonal coloration.
|
||||||
|
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ toobml:sagGroup
|
|||||||
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
||||||
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
||||||
lv2:minorVersion 0 ;
|
lv2:minorVersion 0 ;
|
||||||
lv2:microVersion 45 ;
|
lv2:microVersion 47 ;
|
||||||
rdfs:comment """
|
rdfs:comment """
|
||||||
The TooB ML Amplifier plugin provides emulation of a variety of amplifiers and overdrive pedals that are implemented
|
The TooB ML Amplifier plugin provides emulation of a variety of amplifiers and overdrive pedals that are implemented
|
||||||
using neural-network-based machine learning models of real amplifiers.
|
using neural-network-based machine learning models of real amplifiers.
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ toobNam:eqGroup
|
|||||||
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
||||||
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
||||||
lv2:minorVersion 0 ;
|
lv2:minorVersion 0 ;
|
||||||
lv2:microVersion 45 ;
|
lv2:microVersion 47 ;
|
||||||
rdfs:comment """
|
rdfs:comment """
|
||||||
A port of Steven Atkinson's Neural Amp Modeler to LV2.
|
A port of Steven Atkinson's Neural Amp Modeler to LV2.
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@
|
|||||||
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
||||||
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
||||||
lv2:minorVersion 0 ;
|
lv2:minorVersion 0 ;
|
||||||
lv2:microVersion 45 ;
|
lv2:microVersion 47 ;
|
||||||
rdfs:comment """
|
rdfs:comment """
|
||||||
TooB Tuner is a chromatic guitar tuner.
|
TooB Tuner is a chromatic guitar tuner.
|
||||||
""" ;
|
""" ;
|
||||||
|
|||||||
Executable
+3
@@ -0,0 +1,3 @@
|
|||||||
|
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||||
|
${SCRIPT_DIR}/../build/src/profilePlugin -w ToobNam_Profile -o /tmp/ToobNam.perf &&\
|
||||||
|
google-pprof --text ${SCRIPT_DIR}/../build/src/profilePlugin --add_lib /usr/lib/lv2/ToobAmp.lv2/ToobAmp.so /tmp/ToobNam.perf >./ToobNam.txt
|
||||||
Executable
+3
@@ -0,0 +1,3 @@
|
|||||||
|
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||||
|
${SCRIPT_DIR}/../build/src/profilePlugin -w Nam_Profile -o /tmp/nam.perf &&\
|
||||||
|
google-pprof --text ${SCRIPT_DIR}/../build/src/profilePlugin --add_lib /usr/lib/lv2/neural_amp_modeler.lv2/neural_amp_modeler.so /tmp/nam.perf >./nam.txt
|
||||||
@@ -9,6 +9,13 @@ set(CXX_STANDARD 20)
|
|||||||
|
|
||||||
include(FindPkgConfig)
|
include(FindPkgConfig)
|
||||||
|
|
||||||
|
|
||||||
|
if(DEFINED ENV{GITHUB_ACTIONS})
|
||||||
|
message(STATUS "Building in GitHub Actions environment")
|
||||||
|
set(GITHUB_ACTIONS TRUE)
|
||||||
|
else()
|
||||||
|
set(GITHUB_ACTIONS FALSE)
|
||||||
|
endif()
|
||||||
#################################################################
|
#################################################################
|
||||||
# ENABLE/DISABLE VST3 Support.
|
# ENABLE/DISABLE VST3 Support.
|
||||||
# Disabled, pending approval of Steinberg VST3 License.
|
# Disabled, pending approval of Steinberg VST3 License.
|
||||||
@@ -310,6 +317,17 @@ target_link_libraries(pipedaltest PRIVATE PiPedalCommon)
|
|||||||
target_include_directories(pipedaltest PRIVATE ${PIPEDAL_INCLUDES}
|
target_include_directories(pipedaltest PRIVATE ${PIPEDAL_INCLUDES}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (NOT GITHUB_ACTIONS) # Google perftools are not available on Github action servers.
|
||||||
|
|
||||||
|
|
||||||
|
add_executable(profilePlugin
|
||||||
|
profilePluginMain.cpp
|
||||||
|
)
|
||||||
|
target_link_libraries(profilePlugin PRIVATE profiler ${PIPEDAL_LIBS})
|
||||||
|
|
||||||
|
target_include_directories(profilePlugin PRIVATE ${PIPEDAL_INCLUDES}
|
||||||
|
)
|
||||||
|
endif()
|
||||||
add_executable(jsonTest
|
add_executable(jsonTest
|
||||||
testMain.cpp
|
testMain.cpp
|
||||||
jsonTest.cpp
|
jsonTest.cpp
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ namespace pipedal
|
|||||||
{
|
{
|
||||||
if (shortOption.length() != 0)
|
if (shortOption.length() != 0)
|
||||||
{
|
{
|
||||||
auto option = "-" + longOption;
|
auto option = "-" + shortOption;
|
||||||
options.push_back(new BooleanOption(option, pResult, true));
|
options.push_back(new BooleanOption(option, pResult, true));
|
||||||
options.push_back(new BooleanOption(option + "+", pResult, true));
|
options.push_back(new BooleanOption(option + "+", pResult, true));
|
||||||
options.push_back(new BooleanOption(option + "-", pResult, false));
|
options.push_back(new BooleanOption(option + "-", pResult, false));
|
||||||
|
|||||||
@@ -40,6 +40,8 @@
|
|||||||
#include "WifiChannelSelectors.hpp"
|
#include "WifiChannelSelectors.hpp"
|
||||||
#include "PiPedalConfiguration.hpp"
|
#include "PiPedalConfiguration.hpp"
|
||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
|
#include "ofstream_synced.hpp"
|
||||||
|
|
||||||
|
|
||||||
#if JACK_HOST
|
#if JACK_HOST
|
||||||
#define INSTALL_JACK_SERVICE 1
|
#define INSTALL_JACK_SERVICE 1
|
||||||
@@ -1346,10 +1348,12 @@ int main(int argc, char **argv)
|
|||||||
portOption = "0.0.0.0:" + portOption;
|
portOption = "0.0.0.0:" + portOption;
|
||||||
}
|
}
|
||||||
Install(prefix, portOption);
|
Install(prefix, portOption);
|
||||||
|
FileSystemSync();
|
||||||
}
|
}
|
||||||
else if (uninstall)
|
else if (uninstall)
|
||||||
{
|
{
|
||||||
Uninstall();
|
Uninstall();
|
||||||
|
FileSystemSync();
|
||||||
}
|
}
|
||||||
else if (stop)
|
else if (stop)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include "util.hpp"
|
#include "util.hpp"
|
||||||
|
#include "ofstream_synced.hpp"
|
||||||
|
|
||||||
using namespace pipedal;
|
using namespace pipedal;
|
||||||
using namespace pipedal::implementation;
|
using namespace pipedal::implementation;
|
||||||
@@ -101,7 +102,7 @@ FileBrowserFilesFeature::FileBrowserFilesFeature()
|
|||||||
}
|
}
|
||||||
void BrowserFilesVersionInfo::Save(std::filesystem::path &path)
|
void BrowserFilesVersionInfo::Save(std::filesystem::path &path)
|
||||||
{
|
{
|
||||||
std::ofstream f{path};
|
pipedal::ofstream_synced f{path};
|
||||||
if (!f.is_open())
|
if (!f.is_open())
|
||||||
return;
|
return;
|
||||||
f << version << std::endl;
|
f << version << std::endl;
|
||||||
|
|||||||
+18
-3
@@ -492,7 +492,7 @@ void PiPedalModel::FirePedalboardChanged(int64_t clientId, bool loadAudioThread)
|
|||||||
if (loadAudioThread)
|
if (loadAudioThread)
|
||||||
{
|
{
|
||||||
// notify the audio thread.
|
// notify the audio thread.
|
||||||
if (audioHost->IsOpen())
|
if (audioHost && audioHost->IsOpen())
|
||||||
{
|
{
|
||||||
LoadCurrentPedalboard();
|
LoadCurrentPedalboard();
|
||||||
|
|
||||||
@@ -2070,6 +2070,21 @@ void PiPedalModel::CheckForResourceInitialization(Pedalboard &pedalboard)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Pedalboard &PiPedalModel::GetPedalboard()
|
||||||
|
{
|
||||||
|
return this->pedalboard;
|
||||||
|
}
|
||||||
|
std::shared_ptr<Lv2Pedalboard> PiPedalModel::GetLv2Pedalboard()
|
||||||
|
{
|
||||||
|
// test only.
|
||||||
|
Lv2PedalboardErrorList errorMessages;
|
||||||
|
std::shared_ptr<Lv2Pedalboard> lv2Pedalboard{this->pluginHost.CreateLv2Pedalboard(this->pedalboard, errorMessages)};
|
||||||
|
if (errorMessages.size() != 0)
|
||||||
|
{
|
||||||
|
throw std::runtime_error(errorMessages[0].message);
|
||||||
|
}
|
||||||
|
return lv2Pedalboard;
|
||||||
|
}
|
||||||
bool PiPedalModel::LoadCurrentPedalboard()
|
bool PiPedalModel::LoadCurrentPedalboard()
|
||||||
{
|
{
|
||||||
Lv2PedalboardErrorList errorMessages;
|
Lv2PedalboardErrorList errorMessages;
|
||||||
@@ -2174,8 +2189,8 @@ UpdateStatus PiPedalModel::GetUpdateStatus()
|
|||||||
void PiPedalModel::UpdateNow(const std::string &updateUrl)
|
void PiPedalModel::UpdateNow(const std::string &updateUrl)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::recursive_mutex> lock(mutex);
|
std::lock_guard<std::recursive_mutex> lock(mutex);
|
||||||
std::filesystem::path fileName,signatureName;
|
std::filesystem::path fileName, signatureName;
|
||||||
updater.DownloadUpdate(updateUrl,&fileName,&signatureName);
|
updater.DownloadUpdate(updateUrl, &fileName, &signatureName);
|
||||||
|
|
||||||
adminClient.InstallUpdate(fileName);
|
adminClient.InstallUpdate(fileName);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -251,6 +251,9 @@ namespace pipedal
|
|||||||
|
|
||||||
|
|
||||||
void SetPedalboard(int64_t clientId, Pedalboard &pedalboard);
|
void SetPedalboard(int64_t clientId, Pedalboard &pedalboard);
|
||||||
|
Pedalboard&GetPedalboard();
|
||||||
|
std::shared_ptr<Lv2Pedalboard> GetLv2Pedalboard();
|
||||||
|
|
||||||
void UpdateCurrentPedalboard(int64_t clientId, Pedalboard &pedalboard);
|
void UpdateCurrentPedalboard(int64_t clientId, Pedalboard &pedalboard);
|
||||||
|
|
||||||
void GetPresets(PresetIndex *pResult);
|
void GetPresets(PresetIndex *pResult);
|
||||||
|
|||||||
+3
-3
@@ -740,9 +740,9 @@ namespace pipedal
|
|||||||
size_t maxBufferSize = 1024;
|
size_t maxBufferSize = 1024;
|
||||||
size_t maxAtomBufferSize = 16 * 1024;
|
size_t maxAtomBufferSize = 16 * 1024;
|
||||||
bool hasMidiInputChannel;
|
bool hasMidiInputChannel;
|
||||||
int numberOfAudioInputChannels = 2;
|
int numberOfAudioInputChannels = 1;
|
||||||
int numberOfAudioOutputChannels = 2;
|
int numberOfAudioOutputChannels = 1;
|
||||||
double sampleRate = 0;
|
double sampleRate = 48000;
|
||||||
|
|
||||||
std::string vst3CachePath;
|
std::string vst3CachePath;
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#include "SystemConfigFile.hpp"
|
#include "SystemConfigFile.hpp"
|
||||||
#include "SysExec.hpp"
|
#include "SysExec.hpp"
|
||||||
#include "WriteTemplateFile.hpp"
|
#include "WriteTemplateFile.hpp"
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
using namespace pipedal;
|
using namespace pipedal;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@@ -473,6 +474,7 @@ void pipedal::SetWifiConfig(const WifiConfigSettings &settings)
|
|||||||
sysExec(SYSTEMCTL_BIN " restart dnsmasq");
|
sysExec(SYSTEMCTL_BIN " restart dnsmasq");
|
||||||
sysExec(SYSTEMCTL_BIN " enable dnsmasq");
|
sysExec(SYSTEMCTL_BIN " enable dnsmasq");
|
||||||
}
|
}
|
||||||
|
::sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************************
|
/*********************************************************************************
|
||||||
@@ -563,6 +565,7 @@ void UninstallP2p()
|
|||||||
SetWifiDirectConfig(wifiDirectConfigSettings);
|
SetWifiDirectConfig(wifiDirectConfigSettings);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
::sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void RemoveDhcpcdConfig()
|
static void RemoveDhcpcdConfig()
|
||||||
@@ -679,6 +682,7 @@ void pipedal::SetWifiDirectConfig(const WifiDirectConfigSettings &settings)
|
|||||||
{
|
{
|
||||||
cout << e.what() << endl;
|
cout << e.what() << endl;
|
||||||
}
|
}
|
||||||
|
::sync();
|
||||||
}
|
}
|
||||||
void pipedal::OnWifiReinstall() {
|
void pipedal::OnWifiReinstall() {
|
||||||
WifiDirectConfigSettings settings;
|
WifiDirectConfigSettings settings;
|
||||||
@@ -686,6 +690,7 @@ void pipedal::OnWifiReinstall() {
|
|||||||
if (settings.enable_)
|
if (settings.enable_)
|
||||||
{
|
{
|
||||||
SetWifiDirectConfig(settings);
|
SetWifiDirectConfig(settings);
|
||||||
|
::sync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void pipedal::OnWifiUninstall(bool preserveState)
|
void pipedal::OnWifiUninstall(bool preserveState)
|
||||||
@@ -707,6 +712,7 @@ void pipedal::OnWifiUninstall(bool preserveState)
|
|||||||
settings.Save();
|
settings.Save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
::sync();
|
||||||
}
|
}
|
||||||
void pipedal::OnWifiInstallComplete()
|
void pipedal::OnWifiInstallComplete()
|
||||||
{
|
{
|
||||||
|
|||||||
+14
-13
@@ -31,6 +31,7 @@
|
|||||||
#include "PiPedalUI.hpp"
|
#include "PiPedalUI.hpp"
|
||||||
#include "PluginHost.hpp"
|
#include "PluginHost.hpp"
|
||||||
#include "ss.hpp"
|
#include "ss.hpp"
|
||||||
|
#include "ofstream_synced.hpp"
|
||||||
|
|
||||||
using namespace pipedal;
|
using namespace pipedal;
|
||||||
|
|
||||||
@@ -344,7 +345,7 @@ void Storage::SavePluginPresetIndex()
|
|||||||
if (pluginPresetIndexChanged)
|
if (pluginPresetIndexChanged)
|
||||||
{
|
{
|
||||||
pluginPresetIndexChanged = false;
|
pluginPresetIndexChanged = false;
|
||||||
std::ofstream os;
|
pipedal::ofstream_synced os;
|
||||||
auto path = GetPluginPresetsDirectory() / "index.json";
|
auto path = GetPluginPresetsDirectory() / "index.json";
|
||||||
os.open(path, std::ios_base::trunc);
|
os.open(path, std::ios_base::trunc);
|
||||||
if (os.fail())
|
if (os.fail())
|
||||||
@@ -359,7 +360,7 @@ void Storage::SavePluginPresetIndex()
|
|||||||
|
|
||||||
void Storage::SaveBankIndex()
|
void Storage::SaveBankIndex()
|
||||||
{
|
{
|
||||||
std::ofstream os;
|
pipedal::ofstream_synced os;
|
||||||
os.open(GetIndexFileName(), std::ios_base::trunc);
|
os.open(GetIndexFileName(), std::ios_base::trunc);
|
||||||
json_writer writer(os, false);
|
json_writer writer(os, false);
|
||||||
writer.write(this->bankIndex);
|
writer.write(this->bankIndex);
|
||||||
@@ -434,7 +435,7 @@ void Storage::SaveBankFile(const std::string &name, const BankFile &bankFile)
|
|||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::ofstream s;
|
pipedal::ofstream_synced s;
|
||||||
s.open(fileName, std::ios_base::trunc);
|
s.open(fileName, std::ios_base::trunc);
|
||||||
json_writer writer(s, false);
|
json_writer writer(s, false);
|
||||||
writer.write(bankFile);
|
writer.write(bankFile);
|
||||||
@@ -721,7 +722,7 @@ void Storage::SaveChannelSelection()
|
|||||||
auto fileName = this->GetChannelSelectionFileName();
|
auto fileName = this->GetChannelSelectionFileName();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::ofstream s(fileName);
|
pipedal::ofstream_synced s(fileName);
|
||||||
json_writer writer(s, false);
|
json_writer writer(s, false);
|
||||||
writer.write(this->jackChannelSelection);
|
writer.write(this->jackChannelSelection);
|
||||||
}
|
}
|
||||||
@@ -906,7 +907,7 @@ int64_t Storage::UploadBank(BankFile &bankFile, int64_t uploadAfter)
|
|||||||
bankFile.name(s.str());
|
bankFile.name(s.str());
|
||||||
}
|
}
|
||||||
std::filesystem::path path = this->GetBankFileName(bankFile.name());
|
std::filesystem::path path = this->GetBankFileName(bankFile.name());
|
||||||
std::ofstream f(path);
|
pipedal::ofstream_synced f(path);
|
||||||
if (!f.is_open())
|
if (!f.is_open())
|
||||||
{
|
{
|
||||||
throw PiPedalException("Can't write to bank file.");
|
throw PiPedalException("Can't write to bank file.");
|
||||||
@@ -928,7 +929,7 @@ void Storage::SaveUserSettings()
|
|||||||
{
|
{
|
||||||
std::filesystem::path path = this->dataRoot / USER_SETTINGS_FILENAME;
|
std::filesystem::path path = this->dataRoot / USER_SETTINGS_FILENAME;
|
||||||
{
|
{
|
||||||
std::ofstream f(path);
|
pipedal::ofstream_synced f(path);
|
||||||
if (!f.is_open())
|
if (!f.is_open())
|
||||||
{
|
{
|
||||||
throw PiPedalException("Unable to write to " + ((std::string)path));
|
throw PiPedalException("Unable to write to " + ((std::string)path));
|
||||||
@@ -964,7 +965,7 @@ void Storage::SetWifiConfigSettings(const WifiConfigSettings &wifiConfigSettings
|
|||||||
|
|
||||||
std::filesystem::path path = this->dataRoot / WIFI_CONFIG_SETTINGS_FILENAME;
|
std::filesystem::path path = this->dataRoot / WIFI_CONFIG_SETTINGS_FILENAME;
|
||||||
{
|
{
|
||||||
std::ofstream f(path);
|
pipedal::ofstream_synced f(path);
|
||||||
if (!f.is_open())
|
if (!f.is_open())
|
||||||
{
|
{
|
||||||
throw PiPedalException("Unable to write to " + ((std::string)path));
|
throw PiPedalException("Unable to write to " + ((std::string)path));
|
||||||
@@ -1077,7 +1078,7 @@ void Storage::SaveCurrentPreset(const CurrentPreset ¤tPreset)
|
|||||||
{
|
{
|
||||||
std::filesystem::path path = GetCurrentPresetPath();
|
std::filesystem::path path = GetCurrentPresetPath();
|
||||||
|
|
||||||
std::ofstream f(path);
|
pipedal::ofstream_synced f(path);
|
||||||
json_writer writer(f, false);
|
json_writer writer(f, false);
|
||||||
writer.write(currentPreset);
|
writer.write(currentPreset);
|
||||||
}
|
}
|
||||||
@@ -1152,7 +1153,7 @@ void Storage::SavePluginPresets(const std::string &pluginUri, const PluginPreset
|
|||||||
}
|
}
|
||||||
auto tempPath = path.string() + ".$$$";
|
auto tempPath = path.string() + ".$$$";
|
||||||
{
|
{
|
||||||
std::ofstream os;
|
pipedal::ofstream_synced os;
|
||||||
os.open(tempPath, std::ios_base::trunc);
|
os.open(tempPath, std::ios_base::trunc);
|
||||||
if (os.fail())
|
if (os.fail())
|
||||||
{
|
{
|
||||||
@@ -1396,7 +1397,7 @@ std::map<std::string, bool> Storage::GetFavorites() const
|
|||||||
void Storage::SetFavorites(const std::map<std::string, bool> &favorites)
|
void Storage::SetFavorites(const std::map<std::string, bool> &favorites)
|
||||||
{
|
{
|
||||||
std::filesystem::path fileName = this->dataRoot / "favorites.json";
|
std::filesystem::path fileName = this->dataRoot / "favorites.json";
|
||||||
std::ofstream f;
|
pipedal::ofstream_synced f;
|
||||||
f.open(fileName);
|
f.open(fileName);
|
||||||
if (f.is_open())
|
if (f.is_open())
|
||||||
{
|
{
|
||||||
@@ -1425,7 +1426,7 @@ pipedal::JackServerSettings Storage::GetJackServerSettings()
|
|||||||
void Storage::SetJackServerSettings(const pipedal::JackServerSettings &jackConfiguration)
|
void Storage::SetJackServerSettings(const pipedal::JackServerSettings &jackConfiguration)
|
||||||
{
|
{
|
||||||
std::filesystem::path fileName = this->dataRoot / "AudioConfig.json";
|
std::filesystem::path fileName = this->dataRoot / "AudioConfig.json";
|
||||||
std::ofstream f;
|
pipedal::ofstream_synced f;
|
||||||
f.open(fileName);
|
f.open(fileName);
|
||||||
if (f.is_open())
|
if (f.is_open())
|
||||||
{
|
{
|
||||||
@@ -1440,7 +1441,7 @@ void Storage::SetJackServerSettings(const pipedal::JackServerSettings &jackConfi
|
|||||||
void Storage::SetSystemMidiBindings(const std::vector<MidiBinding> &bindings)
|
void Storage::SetSystemMidiBindings(const std::vector<MidiBinding> &bindings)
|
||||||
{
|
{
|
||||||
std::filesystem::path fileName = this->dataRoot / "SystemMidiBindings.json";
|
std::filesystem::path fileName = this->dataRoot / "SystemMidiBindings.json";
|
||||||
std::ofstream f;
|
pipedal::ofstream_synced f;
|
||||||
f.open(fileName);
|
f.open(fileName);
|
||||||
if (f.is_open())
|
if (f.is_open())
|
||||||
{
|
{
|
||||||
@@ -1714,7 +1715,7 @@ std::string Storage::UploadUserFile(const std::string &directory, const std::str
|
|||||||
try {
|
try {
|
||||||
std::filesystem::create_directories(path.parent_path());
|
std::filesystem::create_directories(path.parent_path());
|
||||||
|
|
||||||
std::ofstream f(path, std::ios_base::trunc | std::ios_base::binary);
|
pipedal::ofstream_synced f(path, std::ios_base::trunc | std::ios_base::binary);
|
||||||
if (!f.is_open())
|
if (!f.is_open())
|
||||||
{
|
{
|
||||||
throw std::logic_error(SS("Can't create file " << path << "."));
|
throw std::logic_error(SS("Can't create file " << path << "."));
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include "Lv2Log.hpp"
|
#include "Lv2Log.hpp"
|
||||||
#include "ss.hpp"
|
#include "ss.hpp"
|
||||||
|
#include "ofstream_synced.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -40,7 +41,7 @@ void UpdateResults::Load()
|
|||||||
}
|
}
|
||||||
void UpdateResults::Save()
|
void UpdateResults::Save()
|
||||||
{
|
{
|
||||||
std::ofstream f {UPDATE_RESULT_PATH};
|
pipedal::ofstream_synced f {UPDATE_RESULT_PATH};
|
||||||
if (f.is_open())
|
if (f.is_open())
|
||||||
{
|
{
|
||||||
json_writer writer(f);
|
json_writer writer(f);
|
||||||
|
|||||||
+2
-1
@@ -34,6 +34,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "UpdaterSecurity.hpp"
|
#include "UpdaterSecurity.hpp"
|
||||||
#include "SysExec.hpp"
|
#include "SysExec.hpp"
|
||||||
|
#include "ofstream_synced.hpp"
|
||||||
|
|
||||||
using namespace pipedal;
|
using namespace pipedal;
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
@@ -88,7 +89,7 @@ static void SetCachedUpdateStatus(UpdateStatus &updateStatus)
|
|||||||
updateStatus.LastUpdateTime(std::chrono::system_clock::now());
|
updateStatus.LastUpdateTime(std::chrono::system_clock::now());
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::ofstream f{UPDATE_STATUS_CACHE_FILE};
|
pipedal::ofstream_synced f{UPDATE_STATUS_CACHE_FILE};
|
||||||
json_writer writer{f};
|
json_writer writer{f};
|
||||||
writer.write(updateStatus);
|
writer.write(updateStatus);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include "Ipv6Helpers.hpp"
|
#include "Ipv6Helpers.hpp"
|
||||||
#include "util.hpp"
|
#include "util.hpp"
|
||||||
|
#include "ofstream_synced.hpp"
|
||||||
|
|
||||||
#include "WebServer.hpp"
|
#include "WebServer.hpp"
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include "ZipFile.hpp"
|
#include "ZipFile.hpp"
|
||||||
#include "PiPedalUI.hpp"
|
#include "PiPedalUI.hpp"
|
||||||
|
#include "ofstream_synced.hpp"
|
||||||
|
|
||||||
|
|
||||||
#define PRESET_EXTENSION ".piPreset"
|
#define PRESET_EXTENSION ".piPreset"
|
||||||
@@ -439,6 +440,7 @@ public:
|
|||||||
Lv2Log::error(SS("Unzip failed. " << e.what()));
|
Lv2Log::error(SS("Unzip failed. " << e.what()));
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
FileSystemSync();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
outputFileName = this->model->UploadUserFile(directory,patchProperty,filename,req.get_body_input_stream(), req.content_length());
|
outputFileName = this->model->UploadUserFile(directory,patchProperty,filename,req.get_body_input_stream(), req.content_length());
|
||||||
|
|||||||
@@ -0,0 +1,255 @@
|
|||||||
|
#include "PiPedalModel.hpp"
|
||||||
|
#include "PiPedalConfiguration.hpp"
|
||||||
|
#include "Pedalboard.hpp"
|
||||||
|
#include "Lv2Log.hpp"
|
||||||
|
#include "RingBufferReader.hpp"
|
||||||
|
#include "CommandLineParser.hpp"
|
||||||
|
#include <thread>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
// apt install google-perftools
|
||||||
|
#include <gperftools/profiler.h>
|
||||||
|
|
||||||
|
using namespace pipedal;
|
||||||
|
using namespace std;
|
||||||
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
|
// discards data from the ring buffer without discarding it.
|
||||||
|
|
||||||
|
using WriterRingbuffer = RingBuffer<false, true>;
|
||||||
|
|
||||||
|
class RingBufferSink
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RingBufferSink(WriterRingbuffer &writerRingBuffer)
|
||||||
|
: writerRingbuffer(writerRingBuffer)
|
||||||
|
{
|
||||||
|
thread = std::make_unique<std::thread>(
|
||||||
|
[this]()
|
||||||
|
{
|
||||||
|
ThreadProc();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
void Close()
|
||||||
|
{
|
||||||
|
if (!closed)
|
||||||
|
{
|
||||||
|
closed = true;
|
||||||
|
writerRingbuffer.close();
|
||||||
|
terminateThread = true;
|
||||||
|
thread->join();
|
||||||
|
thread = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
~RingBufferSink()
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void ThreadProc()
|
||||||
|
{
|
||||||
|
std::vector<uint8_t> dataVector(1024);
|
||||||
|
uint8_t *data = dataVector.data();
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
RingBufferStatus status = writerRingbuffer.readWait_for(std::chrono::milliseconds(10));
|
||||||
|
if (status == RingBufferStatus::Closed)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (status == RingBufferStatus::Ready)
|
||||||
|
{
|
||||||
|
size_t available = writerRingbuffer.readSpace();
|
||||||
|
while (available != 0)
|
||||||
|
{
|
||||||
|
size_t thisTime = std::min(dataVector.size(), available);
|
||||||
|
writerRingbuffer.read(thisTime, data);
|
||||||
|
available -= thisTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool closed = false;
|
||||||
|
std::atomic<bool> terminateThread{false};
|
||||||
|
|
||||||
|
std::unique_ptr<std::thread> thread;
|
||||||
|
WriterRingbuffer &writerRingbuffer;
|
||||||
|
};
|
||||||
|
struct ProfileOptions
|
||||||
|
{
|
||||||
|
std::string presetName;
|
||||||
|
float benchmark_seconds = 20;
|
||||||
|
std::string outputFilename = "/tmp/profilePlugin.perf";
|
||||||
|
bool noProfile = false;
|
||||||
|
bool waitForWork = false;
|
||||||
|
size_t frameSize = 64;
|
||||||
|
};
|
||||||
|
|
||||||
|
void profilePlugin(const ProfileOptions &profileOptions)
|
||||||
|
{
|
||||||
|
size_t nFrames = profileOptions.frameSize;
|
||||||
|
Lv2Log::log_level(LogLevel::Info);
|
||||||
|
|
||||||
|
/*** Initialize the model */
|
||||||
|
PiPedalModel model;
|
||||||
|
fs::path doc_root = "/etc/pipedal/config";
|
||||||
|
PiPedalConfiguration configuration;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
configuration.Load(doc_root, "");
|
||||||
|
}
|
||||||
|
catch (const std::exception &e)
|
||||||
|
{
|
||||||
|
std::stringstream s;
|
||||||
|
s << "Unable to read configuration from '" << (doc_root / "config.json") << "'. (" << e.what() << ")";
|
||||||
|
throw std::runtime_error(s.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
model.Init(configuration);
|
||||||
|
|
||||||
|
model.LoadLv2PluginInfo();
|
||||||
|
|
||||||
|
// model.Load(); don't start audio.
|
||||||
|
|
||||||
|
/* *** Load the preset. */
|
||||||
|
PresetIndex presetIndex;
|
||||||
|
model.GetPresets(&presetIndex);
|
||||||
|
|
||||||
|
int64_t presetIndexId = 0;
|
||||||
|
bool presetIndexFound = false;
|
||||||
|
for (const auto &preset : presetIndex.presets())
|
||||||
|
{
|
||||||
|
if (preset.name() == profileOptions.presetName)
|
||||||
|
{
|
||||||
|
presetIndexId = preset.instanceId();
|
||||||
|
presetIndexFound = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!presetIndexFound)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Preset not found.");
|
||||||
|
}
|
||||||
|
model.LoadPreset(-1, presetIndexId);
|
||||||
|
|
||||||
|
auto pedalboard = model.GetCurrentPedalboardCopy();
|
||||||
|
cout << "uri: " << pedalboard.items()[0].uri() << endl;
|
||||||
|
/* *** Get and prepare the audio thread pedalboard. */
|
||||||
|
auto lv2Pedalboard = model.GetLv2Pedalboard();
|
||||||
|
|
||||||
|
lv2Pedalboard->Activate();
|
||||||
|
|
||||||
|
std::vector<float> inputBufferVector;
|
||||||
|
std::vector<float> outputBufferVector;
|
||||||
|
inputBufferVector.resize(nFrames);
|
||||||
|
outputBufferVector.resize(nFrames);
|
||||||
|
|
||||||
|
float *inputBuffers[2]{inputBufferVector.data(), nullptr};
|
||||||
|
float *outputBuffers[2] = {inputBufferVector.data(), nullptr};
|
||||||
|
|
||||||
|
WriterRingbuffer writerRingbuffer;
|
||||||
|
RealtimeRingBufferWriter ringBufferWriter(&writerRingbuffer);
|
||||||
|
|
||||||
|
RingBufferSink ringBufferSink(writerRingbuffer);
|
||||||
|
|
||||||
|
/* *** Pump the plugin for a bit if it is expected to do work on the scheduler thread when initializing */
|
||||||
|
if (profileOptions.waitForWork)
|
||||||
|
{
|
||||||
|
using clock = std::chrono::steady_clock;
|
||||||
|
|
||||||
|
// idle, pumping the plugin occasionally to allow inital scheduler work to complete.
|
||||||
|
auto waitStart = clock::now();
|
||||||
|
auto waitDuration = std::chrono::duration_cast<clock::duration>(std::chrono::seconds(3));
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
lv2Pedalboard->Run(inputBuffers, outputBuffers, nFrames, &ringBufferWriter);
|
||||||
|
|
||||||
|
auto elapsed = clock::now() - waitStart;
|
||||||
|
if (elapsed >= waitDuration)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(100)); // the scheduler thread runs.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* *** Run the benchmark */
|
||||||
|
if (!profileOptions.noProfile)
|
||||||
|
{
|
||||||
|
ProfilerStart(profileOptions.outputFilename.c_str());
|
||||||
|
}
|
||||||
|
auto startTime = std::chrono::system_clock::now();
|
||||||
|
|
||||||
|
size_t repetitions = static_cast<size_t>(48000 * profileOptions.benchmark_seconds / nFrames);
|
||||||
|
for (size_t i = 0; i < repetitions; ++i)
|
||||||
|
{
|
||||||
|
lv2Pedalboard->Run(inputBuffers, outputBuffers, nFrames, &ringBufferWriter);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto elapsedTime = std::chrono::high_resolution_clock::now() - startTime;
|
||||||
|
if (!profileOptions.noProfile)
|
||||||
|
{
|
||||||
|
ProfilerStop();
|
||||||
|
}
|
||||||
|
std::chrono::milliseconds us = std::chrono::duration_cast<chrono::milliseconds>(elapsedTime);
|
||||||
|
std::cout << "Ellapsed time: " << (us.count() / 1000.0) << "s" << endl;
|
||||||
|
|
||||||
|
ringBufferSink.Close();
|
||||||
|
|
||||||
|
lv2Pedalboard->Deactivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ProfileOptions profileOptions;
|
||||||
|
bool help = false;
|
||||||
|
CommandLineParser commandLineParser;
|
||||||
|
commandLineParser.AddOption("w", "wait-for-work", &profileOptions.waitForWork);
|
||||||
|
commandLineParser.AddOption("", "no-profile", &profileOptions.noProfile);
|
||||||
|
commandLineParser.AddOption("o", "output", &profileOptions.outputFilename);
|
||||||
|
commandLineParser.AddOption("s", "seconds", &profileOptions.benchmark_seconds);
|
||||||
|
commandLineParser.AddOption("h", "help", &help);
|
||||||
|
|
||||||
|
commandLineParser.Parse(argc, (const char **)argv);
|
||||||
|
|
||||||
|
if (commandLineParser.Arguments().size() != 1 || help)
|
||||||
|
{
|
||||||
|
cout << "profilePlugin - Generate profiling data for LV2 Plugins" << endl;
|
||||||
|
cout << "Copyright (c) 2024 Robin E. R. Davies" << endl;
|
||||||
|
cout << endl;
|
||||||
|
cout << "Syntax: profilePlugin preset_name [options...]" << endl;
|
||||||
|
cout << " where preset_name is the name of a PiPedal preset." << endl;
|
||||||
|
cout << endl;
|
||||||
|
cout << " A google-perf profile capture will be written to " << endl;
|
||||||
|
cout << " /tmp/profilePlugin.perf" << endl;
|
||||||
|
cout << endl;
|
||||||
|
cout << "Options:" << endl;
|
||||||
|
cout << " --no-profile:" << endl;
|
||||||
|
cout << " do NOT generate a perf file." << endl;
|
||||||
|
cout << " -o, --output filename:" << endl;
|
||||||
|
cout << " The file to which profiler data is written. " << endl;
|
||||||
|
cout << " Defaults to /tmp/profilePlugin.perf" << endl;
|
||||||
|
cout << " -w, --wait-for-work: " << endl;
|
||||||
|
cout << " Assume that the plugin will load data on the LV2 scheduler thread." << endl;
|
||||||
|
cout << " -s, --seconds time_in_seconds: " << endl;
|
||||||
|
cout << " The number of seconds of audio to process." << endl;
|
||||||
|
cout << " -h, --help: display this message." << endl;
|
||||||
|
cout << endl;
|
||||||
|
return help ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
profileOptions.presetName = commandLineParser.Arguments()[0];
|
||||||
|
|
||||||
|
profilePlugin(profileOptions);
|
||||||
|
}
|
||||||
|
catch (const std::exception &e)
|
||||||
|
{
|
||||||
|
cerr << "Error: " << e.what() << endl;
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user