Merge branch 'dev' of https://github.com/rerdavies/pipedal into dev
This commit is contained in:
+2
-2
@@ -1,13 +1,13 @@
|
|||||||
cmake_minimum_required(VERSION 3.16.0)
|
cmake_minimum_required(VERSION 3.16.0)
|
||||||
project(pipedal
|
project(pipedal
|
||||||
VERSION 1.4.79
|
VERSION 1.4.83
|
||||||
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"
|
||||||
)
|
)
|
||||||
|
|
||||||
EXECUTE_PROCESS( COMMAND dpkg --print-architecture COMMAND tr -d '\n' OUTPUT_VARIABLE DEBIAN_ARCHITECTURE )
|
EXECUTE_PROCESS( COMMAND dpkg --print-architecture COMMAND tr -d '\n' OUTPUT_VARIABLE DEBIAN_ARCHITECTURE )
|
||||||
|
|
||||||
set (DISPLAY_VERSION "PiPedal v1.4.79-Beta")
|
set (DISPLAY_VERSION "PiPedal v1.4.83-Experimental")
|
||||||
set (PACKAGE_ARCHITECTURE ${DEBIAN_ARCHITECTURE})
|
set (PACKAGE_ARCHITECTURE ${DEBIAN_ARCHITECTURE})
|
||||||
set (CMAKE_INSTALL_PREFIX "/usr/")
|
set (CMAKE_INSTALL_PREFIX "/usr/")
|
||||||
|
|
||||||
|
|||||||
@@ -259,6 +259,8 @@ namespace pipedal
|
|||||||
// Open sequencer in input mode
|
// Open sequencer in input mode
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
Lv2Log::debug("Opening ALSA Sequencer");
|
||||||
|
|
||||||
rc = snd_seq_open(&seqHandle, "default", SND_SEQ_OPEN_DUPLEX, 0);
|
rc = snd_seq_open(&seqHandle, "default", SND_SEQ_OPEN_DUPLEX, 0);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 Robin E. R. Davies
|
||||||
|
* All rights reserved.
|
||||||
|
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
// define restrict keyword for C++ compilers (which don't yet support it)
|
||||||
|
#ifndef restrict
|
||||||
|
#if defined(__GNUC__) || defined(__clang__)
|
||||||
|
#define restrict __restrict__
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#define restrict __restrict
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
@@ -9,11 +9,11 @@
|
|||||||
<img src="https://img.shields.io/github/downloads/rerdavies/pipedal/total?color=%23808080&link=https%3A%2F%2Frerdavies.github.io%2Fpipedal%2Fdownload.html"/>
|
<img src="https://img.shields.io/github/downloads/rerdavies/pipedal/total?color=%23808080&link=https%3A%2F%2Frerdavies.github.io%2Fpipedal%2Fdownload.html"/>
|
||||||
|
|
||||||
|
|
||||||
Download: <a href='https://rerdavies.github.io/pipedal/download.html'>v1.4.79</a>
|
Download: <a href='https://rerdavies.github.io/pipedal/download.html'>v1.4.83</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.4.79 Release. See the [release notes](https://rerdavies.github.io/pipedal/ReleaseNotes) for details. New Phaser and Graphic Equalizer plugins.
|
#### NEW version 1.4.83 Release. See the [release notes](https://rerdavies.github.io/pipedal/ReleaseNotes) for details. New Phaser and Graphic Equalizer plugins.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+5
-5
@@ -13,18 +13,18 @@ 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 (aarch64) v1.4.79](https://github.com/rerdavies/pipedal/releases/download/v1.4.79/pipedal_1.4.79_arm64.deb)
|
- [Raspberry Pi OS bookworm (aarch64) v1.4.83](https://github.com/rerdavies/pipedal/releases/download/v1.4.83/pipedal_1.4.83_arm64.deb)
|
||||||
- [Ubuntu 24.x (aarch64) v1.4.79](https://github.com/rerdavies/pipedal/releases/download/v1.4.79/pipedal_1.4.79_arm64.deb)
|
- [Ubuntu 24.x (aarch64) v1.4.83](https://github.com/rerdavies/pipedal/releases/download/v1.4.83/pipedal_1.4.83_arm64.deb)
|
||||||
- [Ubuntu 24.x (amd64) v1.4.79](https://github.com/rerdavies/pipedal/releases/download/v1.4.79/pipedal_1.4.79_amd64.deb)
|
- [Ubuntu 24.x (amd64) v1.4.83](https://github.com/rerdavies/pipedal/releases/download/v1.4.83/pipedal_1.4.83_amd64.deb)
|
||||||
|
|
||||||
|
|
||||||
Version 1.4.79 has been tested on Raspberry Pi OS bookworm, Ubuntu 24.04 (amd64), and Ubuntu 24.10 (aarch64). Download the appropriate package for your platform, and install using the following procedure:
|
Version 1.4.83 has been tested on Raspberry Pi OS bookworm, Ubuntu 24.04 (amd64), and Ubuntu 24.10 (aarch64). Download the appropriate package for your platform, and install using the following procedure:
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo apt update
|
sudo apt update
|
||||||
sudo apt upgrade
|
sudo apt upgrade
|
||||||
cd ~/Downloads
|
cd ~/Downloads
|
||||||
sudo apt-get install ./pipedal_1.4.79_arm64.deb
|
sudo apt-get install ./pipedal_1.4.83_arm64.deb
|
||||||
```
|
```
|
||||||
You MUST use `apt-get`. `apt` will not install downloaded packages; and `dpkg -i` will not install dependencies.
|
You MUST use `apt-get`. `apt` will not install downloaded packages; and `dpkg -i` will not install dependencies.
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,9 @@
|
|||||||
# Release Notes
|
# Release Notes
|
||||||
|
## Pipedal 1.4.79 Experimental
|
||||||
|
Bug fixes:
|
||||||
|
- Thread-per-plugin-instance for LV2_WORKER threads (see issue #339)
|
||||||
|
- Fixes for selection issues when modifying pedalboard structure.
|
||||||
|
|
||||||
## Pipedal 1.4.79 Beta
|
## Pipedal 1.4.79 Beta
|
||||||
|
|
||||||
The Big Feature:
|
The Big Feature:
|
||||||
|
|||||||
+4
-4
@@ -4,9 +4,9 @@
|
|||||||
|
|
||||||
Download the most recent Debian (.deb) package for your platform:
|
Download the most recent Debian (.deb) package for your platform:
|
||||||
|
|
||||||
- [Raspberry Pi OS bookworm (aarch64) v1.4.79 Beta](https://github.com/rerdavies/pipedal/releases/download/v1.4.79/pipedal_1.4.79_arm64.deb)
|
- [Raspberry Pi OS bookworm (aarch64) v1.4.83 Beta](https://github.com/rerdavies/pipedal/releases/download/v1.4.83/pipedal_1.4.83_arm64.deb)
|
||||||
- [Ubuntu 24.x (aarch64) v1.4.79 Alpha](https://github.com/rerdavies/pipedal/releases/download/v1.4.79/pipedal_1.4.79_arm64.deb)
|
- [Ubuntu 24.x (aarch64) v1.4.83 Alpha](https://github.com/rerdavies/pipedal/releases/download/v1.4.83/pipedal_1.4.83_arm64.deb)
|
||||||
- [Ubuntu 24.x (amd64) v1.4.79 Alpha](https://github.com/rerdavies/pipedal/releases/download/v1.4.79/pipedal_1.4.79_amd64.deb)
|
- [Ubuntu 24.x (amd64) v1.4.83 Alpha](https://github.com/rerdavies/pipedal/releases/download/v1.4.83/pipedal_1.4.83_amd64.deb)
|
||||||
|
|
||||||
|
|
||||||
Install the package by running
|
Install the package by running
|
||||||
@@ -14,7 +14,7 @@ Install the package by running
|
|||||||
```
|
```
|
||||||
sudo apt update
|
sudo apt update
|
||||||
cd ~/Downloads
|
cd ~/Downloads
|
||||||
sudo apt-get install ./pipedal_1.4.79_arm64.deb
|
sudo apt-get install ./pipedal_1.4.83_arm64.deb
|
||||||
```
|
```
|
||||||
You MUST use `apt-get` to install the package. `apt install` will NOT install the package correctly. The message about missing permissions given by `apt-get` is
|
You MUST use `apt-get` to install the package. `apt install` will NOT install the package correctly. The message about missing permissions given by `apt-get` is
|
||||||
expected, and can be safely ignored.
|
expected, and can be safely ignored.
|
||||||
|
|||||||
+136
-73
@@ -245,6 +245,8 @@ namespace pipedal
|
|||||||
class AlsaDriverImpl : public AudioDriver
|
class AlsaDriverImpl : public AudioDriver
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
std::recursive_mutex restartMutex;
|
||||||
|
|
||||||
pipedal::CpuUse cpuUse;
|
pipedal::CpuUse cpuUse;
|
||||||
|
|
||||||
#ifdef ALSADRIVER_CONFIG_DBG
|
#ifdef ALSADRIVER_CONFIG_DBG
|
||||||
@@ -378,16 +380,21 @@ namespace pipedal
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void AlsaCleanup()
|
void AlsaCloseAudio()
|
||||||
{
|
{
|
||||||
|
std::lock_guard lock{restartMutex};
|
||||||
|
|
||||||
if (captureHandle)
|
if (captureHandle)
|
||||||
{
|
{
|
||||||
|
Lv2Log::debug("ALSA capture handle closed.");
|
||||||
|
snd_pcm_drain(captureHandle);
|
||||||
snd_pcm_close(captureHandle);
|
snd_pcm_close(captureHandle);
|
||||||
captureHandle = nullptr;
|
captureHandle = nullptr;
|
||||||
}
|
}
|
||||||
if (playbackHandle)
|
if (playbackHandle)
|
||||||
{
|
{
|
||||||
|
Lv2Log::debug("ALSA playback handle closed.");
|
||||||
|
snd_pcm_drain(playbackHandle);
|
||||||
snd_pcm_close(playbackHandle);
|
snd_pcm_close(playbackHandle);
|
||||||
playbackHandle = nullptr;
|
playbackHandle = nullptr;
|
||||||
}
|
}
|
||||||
@@ -411,7 +418,11 @@ namespace pipedal
|
|||||||
snd_pcm_sw_params_free(playbackSwParams);
|
snd_pcm_sw_params_free(playbackSwParams);
|
||||||
playbackSwParams = nullptr;
|
playbackSwParams = nullptr;
|
||||||
}
|
}
|
||||||
this->alsaSequencer = nullptr;
|
|
||||||
|
}
|
||||||
|
void AlsaCleanup()
|
||||||
|
{
|
||||||
|
AlsaCloseAudio();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string discover_alsa_using_apps()
|
std::string discover_alsa_using_apps()
|
||||||
@@ -1085,6 +1096,34 @@ namespace pipedal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RestartAlsa()
|
||||||
|
{
|
||||||
|
std::lock_guard lock{restartMutex};
|
||||||
|
Lv2Log::info("Restarting ALSA devices.");
|
||||||
|
|
||||||
|
try {
|
||||||
|
AlsaCloseAudio();
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
Lv2Log::error(SS("Error cleaning up ALSA: " << e.what()));
|
||||||
|
throw std::runtime_error("Unable to restart the audio stream.");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
OpenAudio(this->jackServerSettings, this->channelSelection);
|
||||||
|
validate_capture_handle();
|
||||||
|
FillOutputBuffer();
|
||||||
|
audioRunning = true;
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
Lv2Log::error(SS("Error opening ALSA: " << e.what()));
|
||||||
|
throw std::runtime_error("Unable to restart the audio stream.");
|
||||||
|
}
|
||||||
|
int err;
|
||||||
|
if ((err = snd_pcm_start(captureHandle)) < 0)
|
||||||
|
{
|
||||||
|
throw PiPedalStateException("Unable to restart ALSA capture.");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void PrepareCaptureFunctions(snd_pcm_format_t captureFormat)
|
void PrepareCaptureFunctions(snd_pcm_format_t captureFormat)
|
||||||
{
|
{
|
||||||
this->captureFormat = captureFormat;
|
this->captureFormat = captureFormat;
|
||||||
@@ -1221,6 +1260,8 @@ namespace pipedal
|
|||||||
|
|
||||||
void OpenAudio(const JackServerSettings &jackServerSettings, const JackChannelSelection &channelSelection)
|
void OpenAudio(const JackServerSettings &jackServerSettings, const JackChannelSelection &channelSelection)
|
||||||
{
|
{
|
||||||
|
std::lock_guard lock{ restartMutex };
|
||||||
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
alsa_device_name = jackServerSettings.GetAlsaInputDevice();
|
alsa_device_name = jackServerSettings.GetAlsaInputDevice();
|
||||||
@@ -1389,18 +1430,25 @@ namespace pipedal
|
|||||||
void recover_from_output_underrun(snd_pcm_t *capture_handle, snd_pcm_t *playback_handle, int err)
|
void recover_from_output_underrun(snd_pcm_t *capture_handle, snd_pcm_t *playback_handle, int err)
|
||||||
{
|
{
|
||||||
validate_capture_handle();
|
validate_capture_handle();
|
||||||
if (err == -EPIPE)
|
try {
|
||||||
{
|
|
||||||
err = snd_pcm_prepare(playback_handle);
|
if (err == -EPIPE)
|
||||||
if (err < 0)
|
|
||||||
{
|
{
|
||||||
throw PiPedalStateException(SS("Can't recover from ALSA output underrun. (" << snd_strerror(err) << ")"));
|
err = snd_pcm_prepare(playback_handle);
|
||||||
|
if (err < 0)
|
||||||
|
{
|
||||||
|
throw PiPedalStateException(SS("Can't recover from ALSA output underrun. (" << snd_strerror(err) << ")"));
|
||||||
|
}
|
||||||
|
FillOutputBuffer();
|
||||||
}
|
}
|
||||||
FillOutputBuffer();
|
else
|
||||||
}
|
{
|
||||||
else
|
throw PiPedalStateException(SS("Can't recover from ALSA output error. (" << snd_strerror(err) << ")"));
|
||||||
{
|
}
|
||||||
throw PiPedalStateException(SS("Can't recover from ALSA output error. (" << snd_strerror(err) << ")"));
|
} catch (const std::exception &e) {
|
||||||
|
Lv2Log::info(SS("Soft audio restart failed. " << e.what()));
|
||||||
|
RestartAlsa();
|
||||||
|
audioRunning = true;
|
||||||
}
|
}
|
||||||
validate_capture_handle();
|
validate_capture_handle();
|
||||||
}
|
}
|
||||||
@@ -1408,72 +1456,79 @@ namespace pipedal
|
|||||||
{
|
{
|
||||||
validate_capture_handle();
|
validate_capture_handle();
|
||||||
|
|
||||||
if (err == -EPIPE)
|
try {
|
||||||
{
|
if (err == -EPIPE)
|
||||||
|
{
|
||||||
|
|
||||||
// Unlink the streams before recovery
|
// Unlink the streams before recovery
|
||||||
snd_pcm_unlink(capture_handle);
|
snd_pcm_unlink(capture_handle);
|
||||||
|
|
||||||
err = snd_pcm_drop(capture_handle);
|
err = snd_pcm_drop(capture_handle);
|
||||||
if (err < 0)
|
|
||||||
{
|
|
||||||
throw PiPedalStateException(SS("Can't recover from ALSA underrun. (" << snd_strerror(err) << ")"));
|
|
||||||
}
|
|
||||||
err = snd_pcm_drop(playback_handle);
|
|
||||||
if (err < 0)
|
|
||||||
{
|
|
||||||
throw PiPedalStateException(SS("Can't recover from ALSA underrun. (" << snd_strerror(err) << ")"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare both streams
|
|
||||||
if ((err = snd_pcm_prepare(playback_handle)) < 0)
|
|
||||||
{
|
|
||||||
throw std::runtime_error(SS("Cannot prepare playback stream: " << snd_strerror(err)));
|
|
||||||
}
|
|
||||||
if ((err = snd_pcm_prepare(capture_handle)) < 0)
|
|
||||||
{
|
|
||||||
throw std::runtime_error(SS("Cannot prepare capture stream: " << snd_strerror(err)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fill the playback buffer with silence
|
|
||||||
FillOutputBuffer();
|
|
||||||
|
|
||||||
// Resynchronize the streams
|
|
||||||
if ((err = snd_pcm_link(capture_handle, playback_handle)) < 0)
|
|
||||||
{
|
|
||||||
throw std::runtime_error(SS("Cannot relink streams: " << snd_strerror(err)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start the streams
|
|
||||||
if ((err = snd_pcm_start(capture_handle)) < 0)
|
|
||||||
{
|
|
||||||
throw std::runtime_error(SS("Cannot restart capture stream: " << snd_strerror(err)));
|
|
||||||
}
|
|
||||||
validate_capture_handle();
|
|
||||||
}
|
|
||||||
else if (err == ESTRPIPE)
|
|
||||||
{
|
|
||||||
audioRunning = false;
|
|
||||||
validate_capture_handle();
|
|
||||||
|
|
||||||
while ((err = snd_pcm_resume(capture_handle)) == -EAGAIN)
|
|
||||||
{
|
|
||||||
sleep(1);
|
|
||||||
}
|
|
||||||
if (err < 0)
|
|
||||||
{
|
|
||||||
err = snd_pcm_prepare(capture_handle);
|
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
{
|
{
|
||||||
throw PiPedalStateException(SS("Can't recover from ALSA suspend. (" << snd_strerror(err) << ")"));
|
throw PiPedalStateException(SS("Can't recover from ALSA underrun. (" << snd_strerror(err) << ")"));
|
||||||
}
|
}
|
||||||
|
err = snd_pcm_drop(playback_handle);
|
||||||
|
if (err < 0)
|
||||||
|
{
|
||||||
|
throw PiPedalStateException(SS("Can't recover from ALSA underrun. (" << snd_strerror(err) << ")"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare both streams
|
||||||
|
if ((err = snd_pcm_prepare(playback_handle)) < 0)
|
||||||
|
{
|
||||||
|
throw std::runtime_error(SS("Cannot prepare playback stream: " << snd_strerror(err)));
|
||||||
|
}
|
||||||
|
if ((err = snd_pcm_prepare(capture_handle)) < 0)
|
||||||
|
{
|
||||||
|
throw std::runtime_error(SS("Cannot prepare capture stream: " << snd_strerror(err)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill the playback buffer with silence
|
||||||
|
FillOutputBuffer();
|
||||||
|
|
||||||
|
// Resynchronize the streams
|
||||||
|
if ((err = snd_pcm_link(capture_handle, playback_handle)) < 0)
|
||||||
|
{
|
||||||
|
throw std::runtime_error(SS("Cannot relink streams: " << snd_strerror(err)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start the streams
|
||||||
|
if ((err = snd_pcm_start(capture_handle)) < 0)
|
||||||
|
{
|
||||||
|
throw std::runtime_error(SS("Cannot restart capture stream: " << snd_strerror(err)));
|
||||||
|
}
|
||||||
|
validate_capture_handle();
|
||||||
}
|
}
|
||||||
|
else if (err == ESTRPIPE)
|
||||||
|
{
|
||||||
|
audioRunning = false;
|
||||||
|
validate_capture_handle();
|
||||||
|
|
||||||
|
while ((err = snd_pcm_resume(capture_handle)) == -EAGAIN)
|
||||||
|
{
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
if (err < 0)
|
||||||
|
{
|
||||||
|
err = snd_pcm_prepare(capture_handle);
|
||||||
|
if (err < 0)
|
||||||
|
{
|
||||||
|
throw PiPedalStateException(SS("Can't recover from ALSA suspend. (" << snd_strerror(err) << ")"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
audioRunning = true;
|
||||||
|
validate_capture_handle();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw PiPedalStateException(SS("Can't recover from ALSA input error. (" << snd_strerror(err) << ")"));
|
||||||
|
}
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
Lv2Log::info(SS("Soft audio restart failed. " << e.what()));
|
||||||
|
RestartAlsa();
|
||||||
audioRunning = true;
|
audioRunning = true;
|
||||||
validate_capture_handle();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw std::runtime_error(SS("Can't restart audio: " << snd_strerror(err)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1526,6 +1581,11 @@ namespace pipedal
|
|||||||
AlsaMidiMessage message;
|
AlsaMidiMessage message;
|
||||||
|
|
||||||
midiEventCount = 0;
|
midiEventCount = 0;
|
||||||
|
auto alsaSequener = this->alsaSequencer; // take an addref
|
||||||
|
if (!alsaSequener)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
while (alsaSequencer->ReadMessage(message, 0))
|
while (alsaSequencer->ReadMessage(message, 0))
|
||||||
{
|
{
|
||||||
size_t messageSize = message.size;
|
size_t messageSize = message.size;
|
||||||
@@ -1675,11 +1735,11 @@ namespace pipedal
|
|||||||
Lv2Log::error(e.what());
|
Lv2Log::error(e.what());
|
||||||
Lv2Log::error("ALSA audio thread terminated abnormally.");
|
Lv2Log::error("ALSA audio thread terminated abnormally.");
|
||||||
}
|
}
|
||||||
this->driverHost->OnAlsaDriverStopped();
|
|
||||||
|
|
||||||
// if we terminated abnormally, pump messages until we have been terminated.
|
// if we terminated abnormally, pump messages until we have been terminated.
|
||||||
if (!terminateAudio())
|
if (!terminateAudio())
|
||||||
{
|
{
|
||||||
|
this->driverHost->OnAlsaDriverStopped();
|
||||||
// zero out input buffers.
|
// zero out input buffers.
|
||||||
for (size_t i = 0; i < this->captureBuffers.size(); ++i)
|
for (size_t i = 0; i < this->captureBuffers.size(); ++i)
|
||||||
{
|
{
|
||||||
@@ -1848,6 +1908,8 @@ namespace pipedal
|
|||||||
Deactivate();
|
Deactivate();
|
||||||
AlsaCleanup();
|
AlsaCleanup();
|
||||||
DeleteBuffers();
|
DeleteBuffers();
|
||||||
|
this->alsaSequencer = nullptr;
|
||||||
|
|
||||||
std::atomic_thread_fence(std::memory_order::release);
|
std::atomic_thread_fence(std::memory_order::release);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1940,7 +2002,7 @@ namespace pipedal
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
for (int retry = 0; retry < 2; ++retry)
|
for (int retry = 0; retry < 4; ++retry)
|
||||||
{
|
{
|
||||||
err = snd_pcm_open(&playbackHandle, alsaDeviceName.c_str(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
|
err = snd_pcm_open(&playbackHandle, alsaDeviceName.c_str(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
|
||||||
if (err < 0) // field report of a device that is present, but won't immediately open.
|
if (err < 0) // field report of a device that is present, but won't immediately open.
|
||||||
@@ -2202,6 +2264,7 @@ namespace pipedal
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void FreeAlsaGlobals()
|
void FreeAlsaGlobals()
|
||||||
{
|
{
|
||||||
snd_config_update_free_global(); // to get a clean Valgrind report.
|
snd_config_update_free_global(); // to get a clean Valgrind report.
|
||||||
|
|||||||
+4
-2
@@ -34,6 +34,7 @@
|
|||||||
#include "PluginHost.hpp"
|
#include "PluginHost.hpp"
|
||||||
#include "PatchPropertyWriter.hpp"
|
#include "PatchPropertyWriter.hpp"
|
||||||
#include "CpuTemperatureMonitor.hpp"
|
#include "CpuTemperatureMonitor.hpp"
|
||||||
|
#include "restrict.hpp"
|
||||||
|
|
||||||
using namespace pipedal;
|
using namespace pipedal;
|
||||||
|
|
||||||
@@ -618,7 +619,7 @@ private:
|
|||||||
{
|
{
|
||||||
for (size_t i = 0; i < audioDriver->OutputBufferCount(); ++i)
|
for (size_t i = 0; i < audioDriver->OutputBufferCount(); ++i)
|
||||||
{
|
{
|
||||||
float *out = (float *)audioDriver->GetOutputBuffer(i);
|
float * out = (float *)audioDriver->GetOutputBuffer(i);
|
||||||
if (out)
|
if (out)
|
||||||
{
|
{
|
||||||
ZeroBuffer(out, nframes);
|
ZeroBuffer(out, nframes);
|
||||||
@@ -1141,7 +1142,7 @@ private:
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
float *in, *out;
|
float * restrict in , * restrict out;
|
||||||
|
|
||||||
Lv2Pedalboard *pedalboard = nullptr;
|
Lv2Pedalboard *pedalboard = nullptr;
|
||||||
pedalboard = this->realtimeActivePedalboard;
|
pedalboard = this->realtimeActivePedalboard;
|
||||||
@@ -1724,6 +1725,7 @@ public:
|
|||||||
{
|
{
|
||||||
Close();
|
Close();
|
||||||
active = false;
|
active = false;
|
||||||
|
isOpen = false;
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+66
-28
@@ -40,6 +40,40 @@
|
|||||||
|
|
||||||
using namespace pipedal;
|
using namespace pipedal;
|
||||||
|
|
||||||
|
int avahiPollLockCount = 0;
|
||||||
|
static std::mutex avahiLockMutex;
|
||||||
|
class AvahiPollLock {
|
||||||
|
public:
|
||||||
|
AvahiPollLock() = delete;
|
||||||
|
AvahiPollLock(AvahiThreadedPoll*threadedPoll)
|
||||||
|
: threadedPoll(threadedPoll) {
|
||||||
|
std::lock_guard<std::mutex> lock(avahiLockMutex);
|
||||||
|
if (!threadedPoll) {
|
||||||
|
throw std::runtime_error("AvahiPollLock: threadedPoll is null.");
|
||||||
|
}
|
||||||
|
if (++avahiPollLockCount > 1) {
|
||||||
|
throw std::runtime_error("AvahiPollLock: nested locks are not allowed.");
|
||||||
|
}
|
||||||
|
avahi_threaded_poll_lock(threadedPoll);
|
||||||
|
}
|
||||||
|
void release() {
|
||||||
|
std::lock_guard<std::mutex> lock(avahiLockMutex);
|
||||||
|
if (threadedPoll)
|
||||||
|
{
|
||||||
|
if (avahiPollLockCount <= 0) {
|
||||||
|
throw std::runtime_error("AvahiPollLock: release called without a lock.");
|
||||||
|
}
|
||||||
|
--avahiPollLockCount;
|
||||||
|
avahi_threaded_poll_unlock(threadedPoll);
|
||||||
|
threadedPoll = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
~AvahiPollLock() {
|
||||||
|
release();
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
AvahiThreadedPoll *threadedPoll;
|
||||||
|
};
|
||||||
void AvahiService::Announce(
|
void AvahiService::Announce(
|
||||||
int portNumber,
|
int portNumber,
|
||||||
const std::string &name,
|
const std::string &name,
|
||||||
@@ -75,7 +109,7 @@ void AvahiService::Announce(
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// already started, so we have to use poll_lock instead.
|
// already started, so we have to use poll_lock instead.
|
||||||
avahi_threaded_poll_lock(threadedPoll);
|
AvahiPollLock lock(threadedPoll);
|
||||||
|
|
||||||
// all state that we have to protect with the lock now that the avahi serv3ce is running.
|
// all state that we have to protect with the lock now that the avahi serv3ce is running.
|
||||||
this->portNumber = portNumber;
|
this->portNumber = portNumber;
|
||||||
@@ -104,7 +138,7 @@ void AvahiService::Announce(
|
|||||||
Lv2Log::error("Failed to update mDNS service because of a synch problem.");
|
Lv2Log::error("Failed to update mDNS service because of a synch problem.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
avahi_threaded_poll_unlock(threadedPoll);
|
lock.release();
|
||||||
if (wait)
|
if (wait)
|
||||||
{
|
{
|
||||||
Wait();
|
Wait();
|
||||||
@@ -118,30 +152,31 @@ void AvahiService::Unannounce(bool wait)
|
|||||||
return;
|
return;
|
||||||
if (this->threadedPoll)
|
if (this->threadedPoll)
|
||||||
{
|
{
|
||||||
avahi_threaded_poll_lock(threadedPoll);
|
|
||||||
if (started)
|
|
||||||
{
|
{
|
||||||
if (this->createPending)
|
AvahiPollLock lock(threadedPoll);
|
||||||
|
if (started)
|
||||||
{
|
{
|
||||||
// if service is starting up, and we haven't yet made our first announcement,
|
if (this->createPending)
|
||||||
// just signal that we don't want to announc.
|
|
||||||
this->makeAnnouncement = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->makeAnnouncement = false;
|
|
||||||
// we have previously made a successful announcement. Retract it.
|
|
||||||
if (group)
|
|
||||||
{
|
{
|
||||||
int rc = avahi_entry_group_reset(group);
|
// if service is starting up, and we haven't yet made our first announcement,
|
||||||
if (rc < 0)
|
// just signal that we don't want to announc.
|
||||||
|
this->makeAnnouncement = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->makeAnnouncement = false;
|
||||||
|
// we have previously made a successful announcement. Retract it.
|
||||||
|
if (group)
|
||||||
{
|
{
|
||||||
Lv2Log::error("Avahi: failed to un-announce.");
|
int rc = avahi_entry_group_reset(group);
|
||||||
|
if (rc < 0)
|
||||||
|
{
|
||||||
|
Lv2Log::error("Avahi: failed to un-announce.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
avahi_threaded_poll_unlock(threadedPoll);
|
|
||||||
if (wait)
|
if (wait)
|
||||||
{
|
{
|
||||||
WaitForUnannounce();
|
WaitForUnannounce();
|
||||||
@@ -411,6 +446,7 @@ void AvahiService::Start()
|
|||||||
|
|
||||||
if (!client)
|
if (!client)
|
||||||
{
|
{
|
||||||
|
AvahiPollLock lock(threadedPoll);
|
||||||
/* Allocate a new client */
|
/* Allocate a new client */
|
||||||
client = avahi_client_new(avahi_threaded_poll_get(threadedPoll), AvahiClientFlags::AVAHI_CLIENT_NO_FAIL, client_callback, (void *)this, &error);
|
client = avahi_client_new(avahi_threaded_poll_get(threadedPoll), AvahiClientFlags::AVAHI_CLIENT_NO_FAIL, client_callback, (void *)this, &error);
|
||||||
/* Check wether creating the client object succeeded */
|
/* Check wether creating the client object succeeded */
|
||||||
@@ -442,20 +478,22 @@ void AvahiService::Stop()
|
|||||||
|
|
||||||
if (threadedPoll)
|
if (threadedPoll)
|
||||||
{
|
{
|
||||||
avahi_threaded_poll_lock(threadedPoll);
|
|
||||||
if (group)
|
|
||||||
{
|
{
|
||||||
avahi_entry_group_free(group);
|
AvahiPollLock lock(threadedPoll);
|
||||||
group = nullptr;
|
if (group)
|
||||||
|
{
|
||||||
|
avahi_entry_group_free(group);
|
||||||
|
group = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
avahi_threaded_poll_unlock(threadedPoll);
|
|
||||||
avahi_threaded_poll_lock(threadedPoll);
|
|
||||||
if (client)
|
|
||||||
{
|
{
|
||||||
avahi_client_free(client);
|
AvahiPollLock lock(threadedPoll);
|
||||||
client = nullptr;
|
if (client)
|
||||||
|
{
|
||||||
|
avahi_client_free(client);
|
||||||
|
client = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
avahi_threaded_poll_unlock(threadedPoll);
|
|
||||||
|
|
||||||
avahi_threaded_poll_stop(threadedPoll);
|
avahi_threaded_poll_stop(threadedPoll);
|
||||||
avahi_threaded_poll_free(threadedPoll);
|
avahi_threaded_poll_free(threadedPoll);
|
||||||
|
|||||||
+81
-94
@@ -59,8 +59,8 @@ find_package(sdbus-c++ REQUIRED)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
find_package(ICU REQUIRED COMPONENTS uc i18n )
|
find_package(ICU REQUIRED COMPONENTS uc i18n)
|
||||||
message(STATUS "ICU_LIBRARIES: ${ICU_LIBRARIES}")
|
message(STATUS "ICU_LIBRARIES: ${ICU_LIBRARIES}")
|
||||||
|
|
||||||
|
|
||||||
if(DEFINED ENV{GITHUB_ACTIONS})
|
if(DEFINED ENV{GITHUB_ACTIONS})
|
||||||
@@ -72,19 +72,19 @@ endif()
|
|||||||
#################################################################
|
#################################################################
|
||||||
# ENABLE/DISABLE VST3 Support.
|
# ENABLE/DISABLE VST3 Support.
|
||||||
# Disabled, pending approval of Steinberg VST3 License.
|
# Disabled, pending approval of Steinberg VST3 License.
|
||||||
# Do not enable unless you have non-GPL3 access to the Steinberg
|
# Do not enable unless you have non-GPL3 access to the Steinberg
|
||||||
# SDK.
|
# SDK.
|
||||||
#
|
#
|
||||||
# Plus, there don't seem to be any VST3 plugins for linux, as it
|
# Plus, there don't seem to be any VST3 plugins for linux, as it
|
||||||
# turns out. :-/ Status: not completely implemented due to lack
|
# turns out. :-/ Status: not completely implemented due to lack
|
||||||
# of test targets. Deprecated, and non-functional.
|
# of test targets. Deprecated, and non-functional.
|
||||||
#################################################################
|
#################################################################
|
||||||
|
|
||||||
set (ENABLE_VST3 0)
|
set (ENABLE_VST3 0)
|
||||||
|
|
||||||
|
|
||||||
if (ENABLE_VST3)
|
if (ENABLE_VST3)
|
||||||
set (VST3PATH "../../vst3sdk")
|
set (VST3PATH "../../vst3sdk")
|
||||||
message(STATUS " VST3 Support Enabled")
|
message(STATUS " VST3 Support Enabled")
|
||||||
set (VST3_INCLUDES "${VST3PATH}")
|
set (VST3_INCLUDES "${VST3PATH}")
|
||||||
set (VST3_LIBRARIES vst3_lib dl)
|
set (VST3_LIBRARIES vst3_lib dl)
|
||||||
@@ -129,11 +129,11 @@ pkg_check_modules(ZIP "lilv-0")
|
|||||||
set (LV2DEV_INCLUDE_DIRS ) # use lvt headers fro /usr/include
|
set (LV2DEV_INCLUDE_DIRS ) # use lvt headers fro /usr/include
|
||||||
|
|
||||||
|
|
||||||
# Use submodules/websocketpp heders taken from websocketpp/develop branch, because debian-provided
|
# Use submodules/websocketpp heders taken from websocketpp/develop branch, because debian-provided
|
||||||
# version of websocketpp cannot compile under GCC 12.x.
|
# version of websocketpp cannot compile under GCC 12.x.
|
||||||
|
|
||||||
set (WEBSOCKETPP_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/modules/websocketpp)
|
set (WEBSOCKETPP_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/modules/websocketpp)
|
||||||
message(STATUS "WEBSOCKETPP_INCLUDE_DIRS ${WEBSOCKETPP_INCLUDE_DIRS}" )
|
message(STATUS "WEBSOCKETPP_INCLUDE_DIRS ${WEBSOCKETPP_INCLUDE_DIRS}")
|
||||||
|
|
||||||
# pkg_check_modules(JACK "jack")
|
# pkg_check_modules(JACK "jack")
|
||||||
# if(!JACK_FOUND)
|
# if(!JACK_FOUND)
|
||||||
@@ -151,7 +151,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED True)
|
|||||||
if (!ENABLE_VST3)
|
if (!ENABLE_VST3)
|
||||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wno-psabi -DARCHITECTURE=${CPACK_SYSTEM_NAME}")
|
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wno-psabi -DARCHITECTURE=${CPACK_SYSTEM_NAME}")
|
||||||
else()
|
else()
|
||||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-multichar -Wno-psabi")
|
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-multichar -Wno-psabi")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
EXECUTE_PROCESS( COMMAND dpkg --print-architecture COMMAND tr -d '\n' OUTPUT_VARIABLE DEBIAN_ARCHITECTURE )
|
EXECUTE_PROCESS( COMMAND dpkg --print-architecture COMMAND tr -d '\n' OUTPUT_VARIABLE DEBIAN_ARCHITECTURE )
|
||||||
@@ -163,22 +163,22 @@ if (CMAKE_BUILD_TYPE MATCHES Debug)
|
|||||||
message(STATUS "Debug build")
|
message(STATUS "Debug build")
|
||||||
|
|
||||||
# Must not -D_GLIBCXX_DEBUG, since it conflict with SQLiteCpp.lol
|
# Must not -D_GLIBCXX_DEBUG, since it conflict with SQLiteCpp.lol
|
||||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g -DDEBUG " )
|
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g -DDEBUG " )
|
||||||
if (USE_SANITIZE)
|
if (USE_SANITIZE)
|
||||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -static-libasan " )
|
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -static-libasan " )
|
||||||
endif()
|
endif()
|
||||||
elseif(CMAKE_BUILD_TYPE MATCHES RelWithDebInfo)
|
elseif(CMAKE_BUILD_TYPE MATCHES RelWithDebInfo)
|
||||||
message(STATUS "RelWithgDebInfo build")
|
message(STATUS "RelWithgDebInfo build")
|
||||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O3 -DNDEBUG" )
|
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O3 -ffast-math -DNDEBUG" )
|
||||||
else()
|
else()
|
||||||
message(STATUS "Release build")
|
message(STATUS "Release build")
|
||||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -DNDEBUG" )
|
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -ffast-math -DNDEBUG" )
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (ENABLE_BACKTRACE)
|
if (ENABLE_BACKTRACE)
|
||||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -rdynamic")
|
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -rdynamic")
|
||||||
if (${DEBIAN_ARCHITECTURE} MATCHES arm64)
|
if (${DEBIAN_ARCHITECTURE} MATCHES arm64)
|
||||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -funwind-tables")
|
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -funwind-tables")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -189,11 +189,11 @@ endif()
|
|||||||
# message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
|
# message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
|
||||||
# set(CMAKE_ENABLE_EXPORTS 1)
|
# set(CMAKE_ENABLE_EXPORTS 1)
|
||||||
|
|
||||||
message (STATUS "Cxx flags: ${CMAKE_CXX_FLAGS}" )
|
message (STATUS "Cxx flags: ${CMAKE_CXX_FLAGS}")
|
||||||
|
|
||||||
add_definitions(-DBOOST_ERROR_CODE_HEADER_ONLY -DBOOST_BIND_GLOBAL_PLACEHOLDERS -DONBOARDING)
|
add_definitions(-DBOOST_ERROR_CODE_HEADER_ONLY -DBOOST_BIND_GLOBAL_PLACEHOLDERS -DONBOARDING)
|
||||||
|
|
||||||
|
|
||||||
if (VST3PATH)
|
if (VST3PATH)
|
||||||
set (VST3_SOURCES
|
set (VST3_SOURCES
|
||||||
vst3/Vst3Effect.hpp Vst3Effect.cpp
|
vst3/Vst3Effect.hpp Vst3Effect.cpp
|
||||||
@@ -233,8 +233,8 @@ set (PIPEDAL_SOURCES
|
|||||||
WebServerConfig.cpp WebServerConfig.hpp
|
WebServerConfig.cpp WebServerConfig.hpp
|
||||||
Locale.hpp Locale.cpp
|
Locale.hpp Locale.cpp
|
||||||
ZipFile.cpp ZipFile.hpp
|
ZipFile.cpp ZipFile.hpp
|
||||||
TemporaryFile.cpp TemporaryFile.hpp
|
TemporaryFile.cpp TemporaryFile.hpp
|
||||||
FilePropertyDirectoryTree.cpp FilePropertyDirectoryTree.hpp
|
FilePropertyDirectoryTree.cpp FilePropertyDirectoryTree.hpp
|
||||||
FileEntry.cpp FileEntry.hpp
|
FileEntry.cpp FileEntry.hpp
|
||||||
atom_object.hpp atom_object.cpp
|
atom_object.hpp atom_object.cpp
|
||||||
lv2ext/pipedal.lv2/ext/fileBrowser.h
|
lv2ext/pipedal.lv2/ext/fileBrowser.h
|
||||||
@@ -243,7 +243,7 @@ set (PIPEDAL_SOURCES
|
|||||||
DbDezipper.hpp DbDezipper.cpp
|
DbDezipper.hpp DbDezipper.cpp
|
||||||
WebServerLog.hpp
|
WebServerLog.hpp
|
||||||
WifiChannelSelectors.cpp WifiChannelSelectors.hpp
|
WifiChannelSelectors.cpp WifiChannelSelectors.hpp
|
||||||
|
|
||||||
PiPedalUI.hpp
|
PiPedalUI.hpp
|
||||||
PiPedalUI.cpp
|
PiPedalUI.cpp
|
||||||
MapPathFeature.hpp
|
MapPathFeature.hpp
|
||||||
@@ -319,15 +319,15 @@ set (PIPEDAL_SOURCES
|
|||||||
|
|
||||||
configure_file(config.hpp.in config.hpp)
|
configure_file(config.hpp.in config.hpp)
|
||||||
include_directories(
|
include_directories(
|
||||||
${pipedald_SOURCE_DIR}/.
|
${pipedald_SOURCE_DIR}/.
|
||||||
../build/src
|
../build/src
|
||||||
)
|
)
|
||||||
|
|
||||||
set (PIPEDAL_INCLUDES
|
set (PIPEDAL_INCLUDES
|
||||||
${LV2DEV_INCLUDE_DIRS}
|
${LV2DEV_INCLUDE_DIRS}
|
||||||
${JACK_INCLUDE_DIRS} ${LILV_0_INCLUDE_DIRS}
|
${JACK_INCLUDE_DIRS} ${LILV_0_INCLUDE_DIRS}
|
||||||
${VST3_INCLUDES}
|
${VST3_INCLUDES}
|
||||||
${WEBSOCKETPP_INCLUDE_DIRS}
|
${WEBSOCKETPP_INCLUDE_DIRS}
|
||||||
${PipeWire_INCLUDE_DIRS}
|
${PipeWire_INCLUDE_DIRS}
|
||||||
.
|
.
|
||||||
)
|
)
|
||||||
@@ -337,7 +337,7 @@ set(PIPEDAL_LIBS libpipedald zip
|
|||||||
PiPedalCommon
|
PiPedalCommon
|
||||||
pthread atomic stdc++fs asound avahi-common avahi-client systemd
|
pthread atomic stdc++fs asound avahi-common avahi-client systemd
|
||||||
${VST3_LIBRARIES}
|
${VST3_LIBRARIES}
|
||||||
${LILV_0_LIBRARIES}
|
${LILV_0_LIBRARIES}
|
||||||
asound
|
asound
|
||||||
# ${JACK_LIBRARIES} - pending delete for JACK support.
|
# ${JACK_LIBRARIES} - pending delete for JACK support.
|
||||||
)
|
)
|
||||||
@@ -345,16 +345,15 @@ set(PIPEDAL_LIBS libpipedald zip
|
|||||||
|
|
||||||
|
|
||||||
##########################
|
##########################
|
||||||
|
|
||||||
add_library(libpipedald STATIC ${PIPEDAL_SOURCES})
|
add_library(libpipedald STATIC ${PIPEDAL_SOURCES})
|
||||||
|
|
||||||
target_compile_definitions(libpipedald PUBLIC "_REENTRANT")
|
target_compile_definitions(libpipedald PUBLIC "_REENTRANT")
|
||||||
|
|
||||||
target_include_directories(libpipedald PUBLIC ${PIPEDAL_INCLUDES}
|
target_include_directories(libpipedald PUBLIC ${PIPEDAL_INCLUDES})
|
||||||
)
|
|
||||||
|
|
||||||
target_link_libraries(libpipedald
|
target_link_libraries(libpipedald
|
||||||
PUBLIC
|
PUBLIC
|
||||||
PiPedalCommon
|
PiPedalCommon
|
||||||
SQLiteCpp
|
SQLiteCpp
|
||||||
${PipeWire_LIBRARIES}
|
${PipeWire_LIBRARIES}
|
||||||
@@ -382,26 +381,23 @@ target_link_libraries(pipedal_kconfig
|
|||||||
PRIVATE PiPedalCommon
|
PRIVATE PiPedalCommon
|
||||||
asound
|
asound
|
||||||
systemd
|
systemd
|
||||||
)
|
)
|
||||||
|
|
||||||
#################################
|
#################################
|
||||||
add_executable(pipedald
|
add_executable(pipedald
|
||||||
asan_options.cpp # disable leak checking for sanitize=address.
|
asan_options.cpp # disable leak checking for sanitize=address.
|
||||||
main.cpp
|
main.cpp
|
||||||
)
|
)
|
||||||
target_include_directories(pipedald PRIVATE ${PIPEDAL_INCLUDES})
|
target_include_directories(pipedald PRIVATE ${PIPEDAL_INCLUDES})
|
||||||
|
|
||||||
target_compile_definitions(pipedald PRIVATE "ENABLE_BACKTRACE=${ENABLE_BACKTRACE}")
|
target_compile_definitions(pipedald PRIVATE "ENABLE_BACKTRACE=${ENABLE_BACKTRACE}")
|
||||||
|
|
||||||
|
|
||||||
target_link_libraries(pipedald PRIVATE PiPedalCommon
|
target_link_libraries(pipedald PRIVATE PiPedalCommon ${PIPEDAL_LIBS})
|
||||||
|
|
||||||
${PIPEDAL_LIBS}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
#################################
|
#################################
|
||||||
add_executable(hotspotManagerTest
|
add_executable(hotspotManagerTest
|
||||||
hotspotManagerTestMain.cpp
|
hotspotManagerTestMain.cpp
|
||||||
HotspotManager.cpp HotspotManager.hpp)
|
HotspotManager.cpp HotspotManager.hpp)
|
||||||
|
|
||||||
@@ -416,7 +412,7 @@ add_executable(AuxInTest
|
|||||||
AuxInTest.cpp
|
AuxInTest.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
add_executable(pipedaltest
|
add_executable(pipedaltest
|
||||||
testMain.cpp
|
testMain.cpp
|
||||||
|
|
||||||
ModGuiTest.cpp
|
ModGuiTest.cpp
|
||||||
@@ -427,9 +423,9 @@ add_executable(pipedaltest
|
|||||||
ModFileTypesTest.cpp
|
ModFileTypesTest.cpp
|
||||||
jsonTest.cpp
|
jsonTest.cpp
|
||||||
UpdaterTest.cpp
|
UpdaterTest.cpp
|
||||||
|
|
||||||
utilTest.cpp
|
utilTest.cpp
|
||||||
|
|
||||||
AlsaDriverTest.cpp
|
AlsaDriverTest.cpp
|
||||||
AvahiServiceTest.cpp
|
AvahiServiceTest.cpp
|
||||||
WifiChannelsTest.cpp
|
WifiChannelsTest.cpp
|
||||||
@@ -448,29 +444,23 @@ add_executable(pipedaltest
|
|||||||
MemDebug.hpp
|
MemDebug.hpp
|
||||||
)
|
)
|
||||||
target_link_libraries(pipedaltest PRIVATE ${PIPEDAL_LIBS} ${ICU_LIBRARIES})
|
target_link_libraries(pipedaltest PRIVATE ${PIPEDAL_LIBS} ${ICU_LIBRARIES})
|
||||||
target_include_directories(pipedaltest PRIVATE ${PIPEDAL_INCLUDES}
|
target_include_directories(pipedaltest PRIVATE ${PIPEDAL_INCLUDES})
|
||||||
)
|
|
||||||
|
|
||||||
set_target_properties(pipedaltest PROPERTIES EXCLUDE_FROM_ALL ${PIPEDAL_EXCLUDE_TESTS})
|
set_target_properties(pipedaltest PROPERTIES EXCLUDE_FROM_ALL ${PIPEDAL_EXCLUDE_TESTS})
|
||||||
|
|
||||||
if (NOT GITHUB_ACTIONS) # Google perftools are not available on Github action servers.
|
if (NOT GITHUB_ACTIONS) # Google perftools are not available on Github action servers.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
add_executable(pipedalProfilePlugin
|
add_executable(pipedalProfilePlugin
|
||||||
profilePluginMain.cpp ArmPerformanceCounters.hpp
|
profilePluginMain.cpp ArmPerformanceCounters.hpp
|
||||||
)
|
)
|
||||||
target_link_libraries(pipedalProfilePlugin PRIVATE profiler ${PIPEDAL_LIBS})
|
target_link_libraries(pipedalProfilePlugin PRIVATE profiler ${PIPEDAL_LIBS})
|
||||||
|
|
||||||
target_include_directories(pipedalProfilePlugin PRIVATE ${PIPEDAL_INCLUDES}
|
target_include_directories(pipedalProfilePlugin PRIVATE ${PIPEDAL_INCLUDES}
|
||||||
)
|
)
|
||||||
if (${DEBIAN_ARCHITECTURE} MATCHES arm64)
|
if (${DEBIAN_ARCHITECTURE} MATCHES arm64)
|
||||||
target_compile_definitions(pipedalProfilePlugin PRIVATE "PIPEDAL_AARCH64")
|
target_compile_definitions(pipedalProfilePlugin PRIVATE "PIPEDAL_AARCH64")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_executable(jsonTest
|
add_executable(jsonTest
|
||||||
testMain.cpp
|
testMain.cpp
|
||||||
jsonTest.cpp
|
jsonTest.cpp
|
||||||
@@ -484,8 +474,7 @@ add_executable(jsonTest
|
|||||||
PromiseTest.cpp
|
PromiseTest.cpp
|
||||||
)
|
)
|
||||||
target_link_libraries(jsonTest PRIVATE PiPedalCommon)
|
target_link_libraries(jsonTest PRIVATE PiPedalCommon)
|
||||||
target_include_directories(jsonTest PRIVATE ${PIPEDAL_INCLUDES}
|
target_include_directories(jsonTest PRIVATE ${PIPEDAL_INCLUDES})
|
||||||
)
|
|
||||||
|
|
||||||
set_target_properties(jsonTest PROPERTIES EXCLUDE_FROM_ALL ${PIPEDAL_EXCLUDE_TESTS})
|
set_target_properties(jsonTest PROPERTIES EXCLUDE_FROM_ALL ${PIPEDAL_EXCLUDE_TESTS})
|
||||||
|
|
||||||
@@ -498,7 +487,7 @@ add_test(NAME jsonTest COMMAND jsonTest)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
include_directories( ${pipedald_SOURCE_DIR}/. ../build/src)
|
include_directories( ${pipedald_SOURCE_DIR}/. ../build/src)
|
||||||
|
|
||||||
if(${USE_PCH})
|
if(${USE_PCH})
|
||||||
target_precompile_headers(pipedaltest PRIVATE pch.h)
|
target_precompile_headers(pipedaltest PRIVATE pch.h)
|
||||||
@@ -508,25 +497,25 @@ endif()
|
|||||||
target_include_directories(pipedaltest PRIVATE ${PIPEDAL_INCLUDES}
|
target_include_directories(pipedaltest PRIVATE ${PIPEDAL_INCLUDES}
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(pipedaltest PRIVATE ${PIPEDAL_LIBS}
|
target_link_libraries(pipedaltest PRIVATE ${PIPEDAL_LIBS}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
#########################################################
|
#########################################################
|
||||||
# VST3 Source.
|
# VST3 Source.
|
||||||
#
|
#
|
||||||
# VST3 support is optional, because it poses unfortunate
|
# VST3 support is optional, because it poses unfortunate
|
||||||
# licensing problems.
|
# licensing problems.
|
||||||
|
|
||||||
# There's no easy way to get the VST SDK to build without
|
# There's no easy way to get the VST SDK to build without
|
||||||
# GCC c++11 linkage, which is not compatible with pipedal's
|
# GCC c++11 linkage, which is not compatible with pipedal's
|
||||||
# use of C++20 features (strictly a link time breakage).
|
# use of C++20 features (strictly a link time breakage).
|
||||||
#
|
#
|
||||||
# So pipedal rebuilds the VST3 SDK using pipedal-compatible
|
# So pipedal rebuilds the VST3 SDK using pipedal-compatible
|
||||||
# compile flags.
|
# compile flags.
|
||||||
#
|
#
|
||||||
# The current build supports only Linux builds. Refer to the
|
# The current build supports only Linux builds. Refer to the
|
||||||
# original VST3 SDK build for details on how to build
|
# original VST3 SDK build for details on how to build
|
||||||
# for other platforms.
|
# for other platforms.
|
||||||
#
|
#
|
||||||
#########################################################
|
#########################################################
|
||||||
@@ -566,12 +555,12 @@ if(ENABLE_VST3)
|
|||||||
${VST3_BASEPATH}/source/timer.h
|
${VST3_BASEPATH}/source/timer.h
|
||||||
${VST3_BASEPATH}/source/updatehandler.cpp
|
${VST3_BASEPATH}/source/updatehandler.cpp
|
||||||
${VST3_BASEPATH}/source/updatehandler.h
|
${VST3_BASEPATH}/source/updatehandler.h
|
||||||
|
|
||||||
${VST3_BASEPATH}/thread/include/fcondition.h
|
${VST3_BASEPATH}/thread/include/fcondition.h
|
||||||
${VST3_BASEPATH}/thread/include/flock.h
|
${VST3_BASEPATH}/thread/include/flock.h
|
||||||
${VST3_BASEPATH}/thread/source/fcondition.cpp
|
${VST3_BASEPATH}/thread/source/fcondition.cpp
|
||||||
${VST3_BASEPATH}/thread/source/flock.cpp
|
${VST3_BASEPATH}/thread/source/flock.cpp
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# sdk_common files.
|
# sdk_common files.
|
||||||
@@ -615,7 +604,7 @@ if(ENABLE_VST3)
|
|||||||
${VST3_PLUGININTERFACES_BASE_PATH}/ucolorspec.h
|
${VST3_PLUGININTERFACES_BASE_PATH}/ucolorspec.h
|
||||||
${VST3_PLUGININTERFACES_BASE_PATH}/ustring.cpp
|
${VST3_PLUGININTERFACES_BASE_PATH}/ustring.cpp
|
||||||
${VST3_PLUGININTERFACES_BASE_PATH}/ustring.h
|
${VST3_PLUGININTERFACES_BASE_PATH}/ustring.h
|
||||||
|
|
||||||
|
|
||||||
# sdk files.
|
# sdk files.
|
||||||
# ${VST3_SRCPATH}/main/moduleinit.cpp
|
# ${VST3_SRCPATH}/main/moduleinit.cpp
|
||||||
@@ -664,7 +653,7 @@ if(ENABLE_VST3)
|
|||||||
${VST3_SRCPATH}/vst/hosting/module.cpp
|
${VST3_SRCPATH}/vst/hosting/module.cpp
|
||||||
${VST3_SRCPATH}/vst/hosting/module.h
|
${VST3_SRCPATH}/vst/hosting/module.h
|
||||||
${VST3_SRCPATH}/vst/hosting/parameterchanges.cpp
|
${VST3_SRCPATH}/vst/hosting/parameterchanges.cpp
|
||||||
${VST3_SRCPATH}/vst/hosting/parameterchanges.h
|
${VST3_SRCPATH}/vst/hosting/parameterchanges.h
|
||||||
${VST3_SRCPATH}/vst/hosting/pluginterfacesupport.cpp
|
${VST3_SRCPATH}/vst/hosting/pluginterfacesupport.cpp
|
||||||
${VST3_SRCPATH}/vst/hosting/pluginterfacesupport.h
|
${VST3_SRCPATH}/vst/hosting/pluginterfacesupport.h
|
||||||
${VST3_SRCPATH}/vst/hosting/plugprovider.cpp
|
${VST3_SRCPATH}/vst/hosting/plugprovider.cpp
|
||||||
@@ -693,10 +682,10 @@ if(ENABLE_VST3)
|
|||||||
|
|
||||||
add_library(vst3_lib STATIC ${vst3_sources})
|
add_library(vst3_lib STATIC ${vst3_sources})
|
||||||
|
|
||||||
target_include_directories(vst3_lib PRIVATE ${VST3_INCLUDES}
|
target_include_directories(vst3_lib PRIVATE ${VST3_INCLUDES}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# add_executable(vst3test Vst3test.cpp
|
# add_executable(vst3test Vst3test.cpp
|
||||||
|
|
||||||
# MemDebug.cpp
|
# MemDebug.cpp
|
||||||
@@ -705,16 +694,15 @@ if(ENABLE_VST3)
|
|||||||
# Vst3SdkRepro.cpp
|
# Vst3SdkRepro.cpp
|
||||||
|
|
||||||
# ${VST3_FILES}
|
# ${VST3_FILES}
|
||||||
|
|
||||||
# #vst3/Vst3PresetFile.hpp Vst3PresetFile.cpp
|
# #vst3/Vst3PresetFile.hpp Vst3PresetFile.cpp
|
||||||
# asan_options.cpp
|
# asan_options.cpp
|
||||||
# )
|
# )
|
||||||
|
|
||||||
target_include_directories(vst3test PRIVATE ${PIPEDAL_INCLUDES}
|
target_include_directories(vst3test PRIVATE ${PIPEDAL_INCLUDES})
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
target_link_libraries(vst3test PRIVATE ${PIPEDAL_LIBS}
|
target_link_libraries(vst3test PRIVATE ${PIPEDAL_LIBS}
|
||||||
vst3_lib dl pthread
|
vst3_lib dl pthread
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -733,11 +721,11 @@ add_test(NAME DevTest COMMAND pipedaltest "[Dev]")
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
add_executable(pipedalconfig
|
add_executable(pipedalconfig
|
||||||
PrettyPrinter.hpp
|
PrettyPrinter.hpp
|
||||||
SetWifiConfig.cpp SetWifiConfig.hpp
|
SetWifiConfig.cpp SetWifiConfig.hpp
|
||||||
CommandLineParser.hpp
|
CommandLineParser.hpp
|
||||||
PiPedalException.hpp
|
PiPedalException.hpp
|
||||||
ConfigMain.cpp
|
ConfigMain.cpp
|
||||||
alsaCheck.cpp
|
alsaCheck.cpp
|
||||||
alsaCheck.hpp
|
alsaCheck.hpp
|
||||||
@@ -773,13 +761,12 @@ add_executable(pipedal_latency_test
|
|||||||
CpuUse.cpp
|
CpuUse.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(pipedal_latency_test PRIVATE pthread asound PiPedalCommon
|
target_link_libraries(pipedal_latency_test PRIVATE pthread asound PiPedalCommon)
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
add_executable(pipedal_alsa_info
|
add_executable(pipedal_alsa_info
|
||||||
alsaCheck.cpp alsaCheck.hpp
|
alsaCheck.cpp alsaCheck.hpp
|
||||||
alsaCheckMain.cpp
|
alsaCheckMain.cpp
|
||||||
)
|
)
|
||||||
target_link_libraries(pipedal_alsa_info PRIVATE asound)
|
target_link_libraries(pipedal_alsa_info PRIVATE asound)
|
||||||
|
|
||||||
@@ -788,7 +775,7 @@ add_executable(capturepresets
|
|||||||
Storage.cpp
|
Storage.cpp
|
||||||
Storage.hpp
|
Storage.hpp
|
||||||
CommandLineParser.hpp
|
CommandLineParser.hpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(capturepresets PRIVATE ${PIPEDAL_INCLUDES})
|
target_include_directories(capturepresets PRIVATE ${PIPEDAL_INCLUDES})
|
||||||
|
|
||||||
@@ -797,7 +784,7 @@ target_link_libraries(capturepresets ${PIPEDAL_LIBS})
|
|||||||
add_executable(makeRelease
|
add_executable(makeRelease
|
||||||
makeReleaseMain.cpp
|
makeReleaseMain.cpp
|
||||||
CommandLineParser.hpp
|
CommandLineParser.hpp
|
||||||
)
|
)
|
||||||
target_include_directories(makeRelease PRIVATE ${PIPEDAL_INCLUDES})
|
target_include_directories(makeRelease PRIVATE ${PIPEDAL_INCLUDES})
|
||||||
|
|
||||||
target_link_libraries(makeRelease ${PIPEDAL_LIBS})
|
target_link_libraries(makeRelease ${PIPEDAL_LIBS})
|
||||||
@@ -807,14 +794,14 @@ target_link_libraries(makeRelease ${PIPEDAL_LIBS})
|
|||||||
|
|
||||||
|
|
||||||
add_executable(pipedal_update
|
add_executable(pipedal_update
|
||||||
UpdateMain.cpp
|
UpdateMain.cpp
|
||||||
UpdateResults.cpp UpdateResults.hpp
|
UpdateResults.cpp UpdateResults.hpp
|
||||||
Lv2SystemdLogger.cpp Lv2SystemdLogger.hpp
|
Lv2SystemdLogger.cpp Lv2SystemdLogger.hpp
|
||||||
TemporaryFile.cpp TemporaryFile.hpp
|
TemporaryFile.cpp TemporaryFile.hpp
|
||||||
AdminInstallUpdate.cpp AdminInstallUpdate.hpp
|
AdminInstallUpdate.cpp AdminInstallUpdate.hpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(pipedal_update PRIVATE stdc++fs systemd PiPedalCommon )
|
target_link_libraries(pipedal_update PRIVATE stdc++fs systemd PiPedalCommon )
|
||||||
|
|
||||||
|
|
||||||
add_executable(pipedaladmind AdminMain.cpp CommandLineParser.hpp
|
add_executable(pipedaladmind AdminMain.cpp CommandLineParser.hpp
|
||||||
@@ -824,7 +811,7 @@ add_executable(pipedaladmind AdminMain.cpp CommandLineParser.hpp
|
|||||||
JackServerSettings.hpp JackServerSettings.cpp
|
JackServerSettings.hpp JackServerSettings.cpp
|
||||||
Lv2SystemdLogger.hpp Lv2SystemdLogger.cpp
|
Lv2SystemdLogger.hpp Lv2SystemdLogger.cpp
|
||||||
|
|
||||||
SystemConfigFile.hpp SystemConfigFile.cpp
|
SystemConfigFile.hpp SystemConfigFile.cpp
|
||||||
CpuGovernor.cpp CpuGovernor.hpp
|
CpuGovernor.cpp CpuGovernor.hpp
|
||||||
asan_options.cpp
|
asan_options.cpp
|
||||||
|
|
||||||
@@ -832,9 +819,9 @@ add_executable(pipedaladmind AdminMain.cpp CommandLineParser.hpp
|
|||||||
target_link_libraries(pipedaladmind PRIVATE PiPedalCommon pthread atomic stdc++fs systemd )
|
target_link_libraries(pipedaladmind PRIVATE PiPedalCommon pthread atomic stdc++fs systemd )
|
||||||
|
|
||||||
add_executable(processcopyrights copyrightMain.cpp
|
add_executable(processcopyrights copyrightMain.cpp
|
||||||
CommandLineParser.hpp
|
CommandLineParser.hpp
|
||||||
PiPedalException.hpp
|
PiPedalException.hpp
|
||||||
asan_options.cpp )
|
asan_options.cpp)
|
||||||
target_link_libraries(processcopyrights PRIVATE PiPedalCommon stdc++fs)
|
target_link_libraries(processcopyrights PRIVATE PiPedalCommon stdc++fs)
|
||||||
|
|
||||||
set (REACT_BUILD_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../build/react/build/)
|
set (REACT_BUILD_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../build/react/build/)
|
||||||
@@ -854,13 +841,13 @@ elseif(EXISTS "/usr/share/doc/libboost1.67-dev")
|
|||||||
set (BOOST_COPYRIGHT_DIR "libboost1.67-dev")
|
set (BOOST_COPYRIGHT_DIR "libboost1.67-dev")
|
||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "Boost libary version has changed. Please update me.")
|
message(FATAL_ERROR "Boost libary version has changed. Please update me.")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
add_custom_command(OUTPUT ${REACT_NOTICES_FILE}
|
add_custom_command(OUTPUT ${REACT_NOTICES_FILE}
|
||||||
COMMAND "$<TARGET_FILE:processcopyrights>"
|
COMMAND "$<TARGET_FILE:processcopyrights>"
|
||||||
--output ${REACT_NOTICES_FILE}
|
--output ${REACT_NOTICES_FILE}
|
||||||
--projectCopyright ${DEBIAN_COPYRIGHT_FILE}
|
--projectCopyright ${DEBIAN_COPYRIGHT_FILE}
|
||||||
liblilv-0-0 ${BOOST_COPYRIGHT_DIR} lv2-dev libsdbus-c++-dev librsvg2-2 libpango-1.0-0 libx11-6 libxrandr2
|
liblilv-0-0 ${BOOST_COPYRIGHT_DIR} lv2-dev libsdbus-c++-dev librsvg2-2 libpango-1.0-0 libx11-6 libxrandr2
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
DEPENDS ${DEBIAN_COPYRIGHT_FILE} "$<TARGET_FILE:processcopyrights>"
|
DEPENDS ${DEBIAN_COPYRIGHT_FILE} "$<TARGET_FILE:processcopyrights>"
|
||||||
@@ -869,14 +856,14 @@ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
|||||||
|
|
||||||
add_custom_target (
|
add_custom_target (
|
||||||
CopyrightBuild ALL
|
CopyrightBuild ALL
|
||||||
DEPENDS ${REACT_NOTICES_FILE}
|
DEPENDS ${REACT_NOTICES_FILE}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
install (TARGETS pipedalconfig pipedal_kconfig pipedal_latency_test DESTINATION ${CMAKE_INSTALL_PREFIX}/bin
|
install (TARGETS pipedalconfig pipedal_kconfig pipedal_latency_test DESTINATION ${CMAKE_INSTALL_PREFIX}/bin
|
||||||
EXPORT pipedalTargets)
|
EXPORT pipedalTargets)
|
||||||
|
|
||||||
install (TARGETS pipedald pipedaladmind pipedal_update DESTINATION ${CMAKE_INSTALL_PREFIX}/sbin
|
install (TARGETS pipedald pipedaladmind pipedal_update DESTINATION ${CMAKE_INSTALL_PREFIX}/sbin
|
||||||
EXPORT pipedalSbinTargets)
|
EXPORT pipedalSbinTargets)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+18
-17
@@ -18,6 +18,7 @@
|
|||||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
|
#include "restrict.hpp"
|
||||||
#include "Lv2Effect.hpp"
|
#include "Lv2Effect.hpp"
|
||||||
#include "PiPedalException.hpp"
|
#include "PiPedalException.hpp"
|
||||||
#include <lv2/lv2plug.in/ns/ext/worker/worker.h>
|
#include <lv2/lv2plug.in/ns/ext/worker/worker.h>
|
||||||
@@ -514,15 +515,15 @@ int Lv2Effect::GetControlIndex(const std::string &key) const
|
|||||||
|
|
||||||
Lv2Effect::~Lv2Effect()
|
Lv2Effect::~Lv2Effect()
|
||||||
{
|
{
|
||||||
if (activated)
|
|
||||||
{
|
|
||||||
Deactivate();
|
|
||||||
}
|
|
||||||
if (worker)
|
if (worker)
|
||||||
{
|
{
|
||||||
worker->Close();
|
worker->Close();
|
||||||
worker = nullptr; // delete the worker first!
|
worker = nullptr; // delete the worker first!
|
||||||
}
|
}
|
||||||
|
if (activated)
|
||||||
|
{
|
||||||
|
Deactivate();
|
||||||
|
}
|
||||||
if (pInstance)
|
if (pInstance)
|
||||||
{
|
{
|
||||||
lilv_instance_free(pInstance);
|
lilv_instance_free(pInstance);
|
||||||
@@ -635,7 +636,7 @@ void Lv2Effect::Deactivate()
|
|||||||
lilv_instance_deactivate(pInstance);
|
lilv_instance_deactivate(pInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void CopyBuffer(float *input, float *output, uint32_t frames)
|
static inline void CopyBuffer(float *restrict input, float *restrict output, uint32_t frames)
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < frames; ++i)
|
for (uint32_t i = 0; i < frames; ++i)
|
||||||
{
|
{
|
||||||
@@ -673,7 +674,7 @@ void Lv2Effect::Run(uint32_t samples, RealtimeRingBufferWriter *realtimeRingBuff
|
|||||||
{
|
{
|
||||||
for (size_t i = 0; i < this->outputMixBuffers.size(); ++i)
|
for (size_t i = 0; i < this->outputMixBuffers.size(); ++i)
|
||||||
{
|
{
|
||||||
float *__restrict input;
|
float *restrict input;
|
||||||
if (i >= this->inputAudioBuffers.size())
|
if (i >= this->inputAudioBuffers.size())
|
||||||
{
|
{
|
||||||
if (this->inputAudioBuffers.size() == 0)
|
if (this->inputAudioBuffers.size() == 0)
|
||||||
@@ -686,8 +687,8 @@ void Lv2Effect::Run(uint32_t samples, RealtimeRingBufferWriter *realtimeRingBuff
|
|||||||
{
|
{
|
||||||
input = this->inputAudioBuffers[i];
|
input = this->inputAudioBuffers[i];
|
||||||
}
|
}
|
||||||
float *__restrict pluginOutput = this->outputMixBuffers[i].data();
|
float *restrict pluginOutput = this->outputMixBuffers[i].data();
|
||||||
float *__restrict finalOutput = this->outputAudioBuffers[i];
|
float *restrict finalOutput = this->outputAudioBuffers[i];
|
||||||
|
|
||||||
for (uint32_t i = 0; i < samples; ++i)
|
for (uint32_t i = 0; i < samples; ++i)
|
||||||
{
|
{
|
||||||
@@ -698,11 +699,11 @@ void Lv2Effect::Run(uint32_t samples, RealtimeRingBufferWriter *realtimeRingBuff
|
|||||||
else if (this->outputAudioPortIndices.size() == 1 && this->outputAudioBuffers.size() == 2)
|
else if (this->outputAudioPortIndices.size() == 1 && this->outputAudioBuffers.size() == 2)
|
||||||
{
|
{
|
||||||
// 1 plugin output into 2 outputs.
|
// 1 plugin output into 2 outputs.
|
||||||
float *__restrict pluginOutput = this->outputMixBuffers[0].data();
|
float *restrict pluginOutput = this->outputMixBuffers[0].data();
|
||||||
for (size_t i = 0; i < this->outputMixBuffers.size(); ++i)
|
for (size_t i = 0; i < this->outputMixBuffers.size(); ++i)
|
||||||
{
|
{
|
||||||
float *__restrict input = this->inputAudioBuffers[i];
|
float *restrict input = this->inputAudioBuffers[i];
|
||||||
float *__restrict finalOutput = this->outputAudioBuffers[i];
|
float *restrict finalOutput = this->outputAudioBuffers[i];
|
||||||
|
|
||||||
for (uint32_t i = 0; i < samples; ++i)
|
for (uint32_t i = 0; i < samples; ++i)
|
||||||
{
|
{
|
||||||
@@ -750,8 +751,8 @@ void Lv2Effect::Run(uint32_t samples, RealtimeRingBufferWriter *realtimeRingBuff
|
|||||||
|
|
||||||
if (this->outputAudioBuffers.size() == 1)
|
if (this->outputAudioBuffers.size() == 1)
|
||||||
{
|
{
|
||||||
float *input = this->inputAudioBuffers[0];
|
float * restrict input = this->inputAudioBuffers[0];
|
||||||
float *output = this->outputAudioBuffers[0];
|
float * restrict output = this->outputAudioBuffers[0];
|
||||||
for (uint32_t i = 0; i < samples; ++i)
|
for (uint32_t i = 0; i < samples; ++i)
|
||||||
{
|
{
|
||||||
output[i] = currentBypass * output[i] + (1 - currentBypass) * input[i];
|
output[i] = currentBypass * output[i] + (1 - currentBypass) * input[i];
|
||||||
@@ -766,8 +767,8 @@ void Lv2Effect::Run(uint32_t samples, RealtimeRingBufferWriter *realtimeRingBuff
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
float *inputL;
|
float * restrict inputL;
|
||||||
float *inputR;
|
float * restrict inputR;
|
||||||
if (this->inputAudioBuffers.size() == 1)
|
if (this->inputAudioBuffers.size() == 1)
|
||||||
{
|
{
|
||||||
inputL = inputR = inputAudioBuffers[0];
|
inputL = inputR = inputAudioBuffers[0];
|
||||||
@@ -777,8 +778,8 @@ void Lv2Effect::Run(uint32_t samples, RealtimeRingBufferWriter *realtimeRingBuff
|
|||||||
inputL = inputAudioBuffers[0];
|
inputL = inputAudioBuffers[0];
|
||||||
inputR = inputAudioBuffers[1];
|
inputR = inputAudioBuffers[1];
|
||||||
}
|
}
|
||||||
float *outputL = outputAudioBuffers[0];
|
float * restrict outputL = outputAudioBuffers[0];
|
||||||
float *outputR = outputAudioBuffers[1];
|
float * restrict outputR = outputAudioBuffers[1];
|
||||||
for (uint32_t i = 0; i < samples; ++i)
|
for (uint32_t i = 0; i < samples; ++i)
|
||||||
{
|
{
|
||||||
outputL[i] = currentBypass * outputL[i] + (1 - currentBypass) * inputL[i];
|
outputL[i] = currentBypass * outputL[i] + (1 - currentBypass) * inputL[i];
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
#include "Lv2EventBufferWriter.hpp"
|
#include "Lv2EventBufferWriter.hpp"
|
||||||
#include "Lv2Log.hpp"
|
#include "Lv2Log.hpp"
|
||||||
#include "CrashGuard.hpp"
|
#include "CrashGuard.hpp"
|
||||||
|
#include "restrict.hpp"
|
||||||
|
|
||||||
using namespace pipedal;
|
using namespace pipedal;
|
||||||
|
|
||||||
@@ -417,7 +418,7 @@ void Lv2Pedalboard::Deactivate()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Copy(float *input, float *output, uint32_t samples)
|
static void Copy(float *restrict input, float *restrict output, uint32_t samples)
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < samples; ++i)
|
for (uint32_t i = 0; i < samples; ++i)
|
||||||
{
|
{
|
||||||
@@ -434,6 +435,7 @@ bool Lv2Pedalboard::Run(float **inputBuffers, float **outputBuffers, uint32_t sa
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < samples; ++i)
|
for (size_t i = 0; i < samples; ++i)
|
||||||
{
|
{
|
||||||
float volume = this->inputVolume.Tick();
|
float volume = this->inputVolume.Tick();
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ static void SetPriority(int realtimePriority, const char *priorityName)
|
|||||||
int result = sched_setscheduler(0, SCHED_RR, ¶m);
|
int result = sched_setscheduler(0, SCHED_RR, ¶m);
|
||||||
if (result == 0)
|
if (result == 0)
|
||||||
{
|
{
|
||||||
Lv2Log::debug("Service thread priority successfully boosted.");
|
Lv2Log::debug(SS("Service thread priority successfully boosted. (" << priorityName << ")"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
+14
-10
@@ -143,6 +143,7 @@ bool Worker::EmitResponses()
|
|||||||
|
|
||||||
void Worker::WaitForAllResponses()
|
void Worker::WaitForAllResponses()
|
||||||
{
|
{
|
||||||
|
// do what we can to clear the response queue in order to avoid memory/object leaks
|
||||||
using Clock = std::chrono::steady_clock;
|
using Clock = std::chrono::steady_clock;
|
||||||
auto startTime = Clock::now();
|
auto startTime = Clock::now();
|
||||||
while (true)
|
while (true)
|
||||||
@@ -157,11 +158,14 @@ void Worker::WaitForAllResponses()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::chrono::seconds waitDuration = std::chrono::duration_cast<std::chrono::seconds>(Clock::now()-startTime);
|
// pump the plugin with a zero-length buffer.
|
||||||
if (waitDuration.count() > 5) {
|
|
||||||
throw std::logic_error("Timed out waiting for a Worker task to complete.");
|
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||||
|
std::chrono::milliseconds waitDuration = std::chrono::duration_cast<std::chrono::milliseconds>(Clock::now()-startTime);
|
||||||
|
if (waitDuration.count() > 1500) {
|
||||||
|
Lv2Log::error("Timed out waiting for a Worker task to complete.");
|
||||||
|
// better to leak than to terminate the application.
|
||||||
}
|
}
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(15));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,21 +264,16 @@ bool HostWorkerThread::StartThread()
|
|||||||
void HostWorkerThread::Close()
|
void HostWorkerThread::Close()
|
||||||
{
|
{
|
||||||
|
|
||||||
bool sendClose = false;
|
|
||||||
{
|
{
|
||||||
std::lock_guard lock{submitMutex};
|
std::lock_guard lock{submitMutex};
|
||||||
if (pThread) {
|
if (pThread) {
|
||||||
if (!closed)
|
if (!closed)
|
||||||
{
|
{
|
||||||
closed = true;
|
closed = true;
|
||||||
sendClose = true;
|
ScheduleWorkNoLock(nullptr, 0, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sendClose)
|
|
||||||
{
|
|
||||||
ScheduleWork(nullptr, 0, nullptr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
HostWorkerThread::~HostWorkerThread()
|
HostWorkerThread::~HostWorkerThread()
|
||||||
{
|
{
|
||||||
@@ -302,6 +301,11 @@ LV2_Worker_Status HostWorkerThread::ScheduleWork(Worker *worker, size_t size, co
|
|||||||
{
|
{
|
||||||
exiting = true;
|
exiting = true;
|
||||||
}
|
}
|
||||||
|
return ScheduleWorkNoLock(worker, size, data);
|
||||||
|
|
||||||
|
}
|
||||||
|
LV2_Worker_Status HostWorkerThread::ScheduleWorkNoLock(Worker *worker, size_t size, const void *data)
|
||||||
|
{
|
||||||
|
|
||||||
if (requestRingBuffer.writeSpace() < sizeof(worker) + sizeof(size) + size)
|
if (requestRingBuffer.writeSpace() < sizeof(worker) + sizeof(size) + size)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ namespace pipedal {
|
|||||||
bool Closed() const { return closed || pThread == nullptr; }
|
bool Closed() const { return closed || pThread == nullptr; }
|
||||||
LV2_Worker_Status ScheduleWork(Worker*worker, size_t size, const void*data);
|
LV2_Worker_Status ScheduleWork(Worker*worker, size_t size, const void*data);
|
||||||
private:
|
private:
|
||||||
|
LV2_Worker_Status ScheduleWorkNoLock(Worker*worker, size_t size, const void*data);
|
||||||
std::atomic<bool> closed = false;
|
std::atomic<bool> closed = false;
|
||||||
std::unique_ptr<std::thread> pThread;
|
std::unique_ptr<std::thread> pThread;
|
||||||
void ThreadProc() noexcept;
|
void ThreadProc() noexcept;
|
||||||
|
|||||||
@@ -1844,6 +1844,7 @@ export class PiPedalModel //implements PiPedalModel
|
|||||||
newPedalboard.deleteItem(fromInstanceId);
|
newPedalboard.deleteItem(fromInstanceId);
|
||||||
|
|
||||||
newPedalboard.addBefore(fromItem, toInstanceId);
|
newPedalboard.addBefore(fromItem, toInstanceId);
|
||||||
|
newPedalboard.selectedPlugin = fromItem.instanceId;
|
||||||
this.setModelPedalboard(newPedalboard);
|
this.setModelPedalboard(newPedalboard);
|
||||||
this.updateServerPedalboard();
|
this.updateServerPedalboard();
|
||||||
|
|
||||||
@@ -1863,7 +1864,7 @@ export class PiPedalModel //implements PiPedalModel
|
|||||||
newPedalboard.deleteItem(fromInstanceId);
|
newPedalboard.deleteItem(fromInstanceId);
|
||||||
|
|
||||||
newPedalboard.addAfter(fromItem, toInstanceId);
|
newPedalboard.addAfter(fromItem, toInstanceId);
|
||||||
|
newPedalboard.selectedPlugin = fromItem.instanceId;
|
||||||
this.setModelPedalboard(newPedalboard);
|
this.setModelPedalboard(newPedalboard);
|
||||||
this.updateServerPedalboard();
|
this.updateServerPedalboard();
|
||||||
}
|
}
|
||||||
@@ -1885,6 +1886,7 @@ export class PiPedalModel //implements PiPedalModel
|
|||||||
|
|
||||||
newPedalboard.addToStart(fromItem);
|
newPedalboard.addToStart(fromItem);
|
||||||
|
|
||||||
|
newPedalboard.selectedPlugin = fromItem.instanceId;
|
||||||
this.setModelPedalboard(newPedalboard);
|
this.setModelPedalboard(newPedalboard);
|
||||||
this.updateServerPedalboard();
|
this.updateServerPedalboard();
|
||||||
}
|
}
|
||||||
@@ -1904,6 +1906,7 @@ export class PiPedalModel //implements PiPedalModel
|
|||||||
|
|
||||||
newPedalboard.addToEnd(fromItem);
|
newPedalboard.addToEnd(fromItem);
|
||||||
|
|
||||||
|
newPedalboard.selectedPlugin = fromItem.instanceId;
|
||||||
this.setModelPedalboard(newPedalboard);
|
this.setModelPedalboard(newPedalboard);
|
||||||
|
|
||||||
this.updateServerPedalboard();
|
this.updateServerPedalboard();
|
||||||
@@ -1931,7 +1934,7 @@ export class PiPedalModel //implements PiPedalModel
|
|||||||
let emptyItem = newPedalboard.createEmptyItem();
|
let emptyItem = newPedalboard.createEmptyItem();
|
||||||
newPedalboard.replaceItem(fromInstanceId, emptyItem);
|
newPedalboard.replaceItem(fromInstanceId, emptyItem);
|
||||||
newPedalboard.replaceItem(toInstanceId, fromItem);
|
newPedalboard.replaceItem(toInstanceId, fromItem);
|
||||||
|
newPedalboard.selectedPlugin = fromItem.instanceId;
|
||||||
this.setModelPedalboard(newPedalboard);
|
this.setModelPedalboard(newPedalboard);
|
||||||
this.updateServerPedalboard();
|
this.updateServerPedalboard();
|
||||||
|
|
||||||
@@ -1955,6 +1958,7 @@ export class PiPedalModel //implements PiPedalModel
|
|||||||
}
|
}
|
||||||
let newItem = newPedalboard.createEmptyItem();
|
let newItem = newPedalboard.createEmptyItem();
|
||||||
newPedalboard.addItem(newItem, instanceId, append);
|
newPedalboard.addItem(newItem, instanceId, append);
|
||||||
|
newPedalboard.selectedPlugin = newItem.instanceId;
|
||||||
this.setModelPedalboard(newPedalboard);
|
this.setModelPedalboard(newPedalboard);
|
||||||
this.updateServerPedalboard();
|
this.updateServerPedalboard();
|
||||||
return newItem.instanceId;
|
return newItem.instanceId;
|
||||||
@@ -1980,6 +1984,8 @@ export class PiPedalModel //implements PiPedalModel
|
|||||||
}
|
}
|
||||||
let newItem = newPedalboard.createEmptySplit();
|
let newItem = newPedalboard.createEmptySplit();
|
||||||
newPedalboard.addItem(newItem, instanceId, append);
|
newPedalboard.addItem(newItem, instanceId, append);
|
||||||
|
newPedalboard.selectedPlugin = newItem.instanceId;
|
||||||
|
|
||||||
this.setModelPedalboard(newPedalboard);
|
this.setModelPedalboard(newPedalboard);
|
||||||
this.updateServerPedalboard();
|
this.updateServerPedalboard();
|
||||||
return newItem.instanceId;
|
return newItem.instanceId;
|
||||||
@@ -1998,6 +2004,7 @@ export class PiPedalModel //implements PiPedalModel
|
|||||||
newPedalboard.setItemEmpty(item);
|
newPedalboard.setItemEmpty(item);
|
||||||
|
|
||||||
|
|
||||||
|
newPedalboard.selectedPlugin = item.instanceId;
|
||||||
this.setModelPedalboard(newPedalboard);
|
this.setModelPedalboard(newPedalboard);
|
||||||
this.updateServerPedalboard();
|
this.updateServerPedalboard();
|
||||||
return item.instanceId;
|
return item.instanceId;
|
||||||
|
|||||||
Reference in New Issue
Block a user