From 77e3b64736867712267430f70d664a1c3a8bfc35 Mon Sep 17 00:00:00 2001 From: Robin Davies Date: Tue, 11 Oct 2022 14:50:08 -0400 Subject: [PATCH] 1.0.16 Add authbind dependency. Fix crash when number of input channels < number of output channels. Add onboarding dialog for initial configuration. --- CMakeLists.txt | 6 +- README.md | 2 +- debian/control | 2 +- docs/Installing.md | 4 +- docs/_includes/pageIcon.html | 2 +- docs/_includes/pageIconL.html | 2 +- docs/download.md | 4 +- docs/index.md | 2 +- react/src/AppThemed.tsx | 36 ++++- react/src/PiPedalModel.tsx | 6 + react/src/SettingsDialog.tsx | 239 ++++++++++++++++++++-------------- src/AlsaDriver.cpp | 21 +-- src/ConfigMain.cpp | 8 +- src/PiPedalModel.cpp | 18 ++- 14 files changed, 221 insertions(+), 131 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f1823cf..1b75b61 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,10 +1,10 @@ cmake_minimum_required(VERSION 3.16.0) project(pipedal - VERSION 1.0.15 + VERSION 1.0.16 DESCRIPTION "PiPedal Guitar Effect Pedal For Raspberry Pi" HOMEPAGE_URL "https://rerdavies.github.io/pipedal" ) -set (DISPLAY_VERSION "v1.0.15") +set (DISPLAY_VERSION "v1.0.16") set (CMAKE_INSTALL_PREFIX "/usr/") @@ -86,7 +86,7 @@ set(CPACK_DEBIAN_PACKAGE_SECTION sound) set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) set(CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION TRUE) #set(CPACK_DEBIAN_PACKAGE_DEPENDS "jackd2, hostapd, dnsmasq" ) -set(CPACK_DEBIAN_PACKAGE_DEPENDS "hostapd, dnsmasq" ) +set(CPACK_DEBIAN_PACKAGE_DEPENDS "hostapd, dnsmasq authbind" ) #set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "arm64") set(CPACK_PACKAGING_INSTALL_PREFIX /usr) set(CPACK_PROJECT_NAME ${PROJECT_NAME}) diff --git a/README.md b/README.md index cd265ae..111d3e0 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -Download: v1.0.15      Website: [https://rerdavies.github.io/pipedal](https://rerdavies.github.io/pipedal). +Download: v1.0.16      Website: [https://rerdavies.github.io/pipedal](https://rerdavies.github.io/pipedal). Use your Raspberry Pi as a guitar effects pedal. Configure and control PiPedal with your phone or tablet. diff --git a/debian/control b/debian/control index 1e6f0b1..e6206ea 100644 --- a/debian/control +++ b/debian/control @@ -9,6 +9,6 @@ Package: pipedal Pre-Depends: hostapd;authbind Priority: optional Section: sound -Version: 1.0.15 +Version: 1.0.16 Installed-Size: 15147 diff --git a/docs/Installing.md b/docs/Installing.md index 4f1a3cb..4bf9901 100644 --- a/docs/Installing.md +++ b/docs/Installing.md @@ -13,14 +13,14 @@ page_icon: img/Install4.jpg Download the most recent Debian (.deb) package for your platform: -- [Ubuntu/Raspberry Pi OS (64-bit) v1.0.15](https://github.com/rerdavies/pipedal/releases/download/v1.0.15/pipedal_1.0.15_arm64.deb) +- [Ubuntu/Raspberry Pi OS (64-bit) v1.0.16](https://github.com/rerdavies/pipedal/releases/download/v1.0.16/pipedal_1.0.16_arm64.deb) Install the package by running ``` sudo apt update cd ~/Downloads - sudo dpkg --install pipedal_1.0.15_arm64.deb + sudo dpkg --install pipedal_1.0.16_arm64.deb ``` On Raspberry Pi OS, if you have a graphical desktop installed, you can also install the package by double-clicking on the downloaded package in the File Manager. diff --git a/docs/_includes/pageIcon.html b/docs/_includes/pageIcon.html index db40f10..4769925 100644 --- a/docs/_includes/pageIcon.html +++ b/docs/_includes/pageIcon.html @@ -3,6 +3,6 @@
-

Generated by DALL-E

+

Generated by DALL-E 2

diff --git a/docs/_includes/pageIconL.html b/docs/_includes/pageIconL.html index f5eb164..a15ccce 100644 --- a/docs/_includes/pageIconL.html +++ b/docs/_includes/pageIconL.html @@ -2,6 +2,6 @@
-

Generated by DALL-E

+

Generated by DALL-E 2

diff --git a/docs/download.md b/docs/download.md index dc0be58..931684d 100644 --- a/docs/download.md +++ b/docs/download.md @@ -4,14 +4,14 @@ Download the most recent Debian (.deb) package for your platform: -- [Ubuntu or Raspberry Pi OS (64-bit)](https://github.com/rerdavies/pipedal/releases/download/v1.0.15/pipedal_1.0.15_arm64.deb) v1.0.15 +- [Ubuntu or Raspberry Pi OS (64-bit)](https://github.com/rerdavies/pipedal/releases/download/v1.0.16/pipedal_1.0.16_arm64.deb) v1.0.16 Install the package by running ``` sudo apt update cd ~/Downloads - sudo apt-get install ./pipedal_1.0.15_arm64.deb + sudo apt-get install ./pipedal_1.0.16_arm64.deb ``` Follow the instructions in [_Configuring PiPedal After Installation_](https://rerdavies.github.io/pipedal/Configuring.html) to complete the installation. diff --git a/docs/index.md b/docs/index.md index 9a024c9..91fe4a6 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,7 +1,7 @@ -v1.0.15 +v1.0.16 Use your Raspberry Pi as a guitar effects pedal. Configure and control PiPedal with your phone or tablet. diff --git a/react/src/AppThemed.tsx b/react/src/AppThemed.tsx index 2180b3d..502df30 100644 --- a/react/src/AppThemed.tsx +++ b/react/src/AppThemed.tsx @@ -249,6 +249,7 @@ type AppState = { alertDialogOpen: boolean; alertDialogMessage: string; isSettingsDialogOpen: boolean; + onboarding: boolean; isDebug: boolean; renameBankDialogOpen: boolean; @@ -301,6 +302,7 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent< alertDialogMessage: "", presetName: this.model_.presets.get().getSelectedText(), isSettingsDialogOpen: false, + onboarding: false, isDebug: true, presetChanged: this.model_.presets.get().presetChanged, banks: this.model_.banks.get(), @@ -383,13 +385,24 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent< } handleSettingsDialogClose() { this.setState({ - isSettingsDialogOpen: false + isSettingsDialogOpen: false, + onboarding: false }); } handleDrawerSettingsClick() { this.setState({ isDrawerOpen: false, - isSettingsDialogOpen: true + isSettingsDialogOpen: true, + onboarding: false + }); + + } + + handDisplayOnboarding() { + this.setState({ + isDrawerOpen: false, + isSettingsDialogOpen: true, + onboarding: true }); } @@ -561,6 +574,9 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent< setErrorMessage(message: string): void { this.setState({ errorMessage: message }); } + + onboardingShown: boolean = false; + setDisplayState(newState: State): void { this.updateOverscroll(); @@ -568,6 +584,17 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent< displayState: newState, canFullScreen: supportsFullScreen() && !this.model_.isAndroidHosted() }); + if (newState == State.Ready) + { + if (!this.onboardingShown) + { + this.onboardingShown = true; + if (!this.model_.hasConfiguration()) + { + this.handDisplayOnboarding(); + } + } + } } showDrawer() { @@ -778,7 +805,10 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent< this.setState({ bankDialogOpen: false })} /> this.setState({ aboutDialogOpen: false })} /> - this.handleSettingsDialogClose()} /> + this.handleSettingsDialogClose()} /> { open: boolean; + onboarding: boolean; onClose: () => void; @@ -65,6 +67,7 @@ interface SettingsDialogState { jackServerSettings: JackServerSettings; jackStatus?: JackHostStatus; governorSettings: GovernorSettings; + continueDisabled: boolean; wifiConfigSettings: WifiConfigSettings; wifiDirectConfigSettings: WifiDirectConfigSettings; @@ -167,6 +170,7 @@ const SettingsDialog = withStyles(styles, { withTheme: true })( wifiConfigSettings: this.model.wifiConfigSettings.get(), wifiDirectConfigSettings: this.model.wifiDirectConfigSettings.get(), governorSettings: this.model.governorSettings.get(), + continueDisabled: true, showWifiConfigDialog: false, showWifiDirectConfigDialog: false, showGovernorSettingsDialog: false, @@ -270,7 +274,8 @@ const SettingsDialog = withStyles(styles, { withTheme: true })( } handleJackServerSettingsChanged(): void { this.setState({ - jackServerSettings: this.model.jackServerSettings.get() + jackServerSettings: this.model.jackServerSettings.get(), + continueDisabled: !this.model.jackServerSettings.get().valid }); } @@ -498,15 +503,30 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
- - - - - - Settings - - + { + this.props.onboarding ? + ( + + + Initial Configuration + + + + ) + : + ( + + + + + + Settings + + + + ) + }
- - STATUS - - {(!isConfigValid) ? - ( -
- Status: Not configured. - Governor: -
- ) : - ( -
- {JackHostStatus.getDisplayView("", this.state.jackStatus)} - {JackHostStatus.getCpuInfo("Governor:\u00A0", this.state.jackStatus)} -
- ) - } + {this.props.onboarding ? + ( +
+ + Select and configure an audio device. You may optionally configure MIDI inputs, and set up a Wi-Fi Direct Hotspot now as well. + + + Access and modify these settings later by selecting the Settings menu item on the main menu. + +
+ ): + ( +
+ + + STATUS + + {(!isConfigValid) ? + ( +
+ Status: Not configured. + Governor: +
+ ) : + ( +
+ {JackHostStatus.getDisplayView("", this.state.jackStatus)} + {JackHostStatus.getCpuInfo("Governor:\u00A0", this.state.jackStatus)} +
+ ) + } +
+ )} {this.state.jackConfiguration.errorState !== "" && ( @@ -650,79 +686,90 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
- -
- SYSTEM + { (!this.props.onboarding) ? ( +
+ + SYSTEM - this.handleShowGovernorSettingsDialogDialog()} > - -
- - CPU Governor - - {this.state.governorSettings.governor} - - -
-
- - { this.setState({ showStatusMonitorDialog: true }); }} > - -
-
-
- - Show status monitor on main screen. -
-
- { this.model.setShowStatusMonitor(e.target.checked); } - } - /> -
+ this.handleShowGovernorSettingsDialogDialog()} > + +
+ + CPU Governor + + {this.state.governorSettings.governor} +
-
- + - this.handleRestart()} > - -
- { - this.state.restarting ? ( - Rebooting... - ) : ( - Reboot PiPedal - ) - } -
-
+ { this.setState({ showStatusMonitorDialog: true }); }} > + +
+
+
+ + Show status monitor on main screen. +
+
+ { this.model.setShowStatusMonitor(e.target.checked); } + } + /> +
- this.handleShutdown()} > - -
- { - this.state.shuttingDown ? ( - Shutting down... - ) : ( - Shut down - ) - } -
-
-
+
+
+
+ + this.handleRestart()} > + +
+ { + this.state.restarting ? ( + Rebooting... + ) : ( + Reboot PiPedal + ) + } +
+
+ + this.handleShutdown()} > + +
+ { + this.state.shuttingDown ? ( + Shutting down... + ) : ( + Shut down + ) + } +
+
+
+ ): ( +
+ +
+ +
+
+ ) + } diff --git a/src/AlsaDriver.cpp b/src/AlsaDriver.cpp index 5cc9be8..9d97850 100644 --- a/src/AlsaDriver.cpp +++ b/src/AlsaDriver.cpp @@ -37,6 +37,7 @@ #include "Lv2Log.hpp" #include +#include "ss.hpp" #undef ALSADRIVER_CONFIG_DBG @@ -184,7 +185,7 @@ namespace pipedal private: void OnShutdown() { - Lv2Log::info("Jack Audio Server has shut down."); + Lv2Log::info("ALSA Audio Server has shut down."); } static void @@ -1091,9 +1092,10 @@ namespace pipedal int sourceIndex = IndexFromPortName(x); if (sourceIndex >= captureBuffers.size()) { - throw PiPedalArgumentException("Invalid input port."); + Lv2Log::error(SS("Invalid audio input port: " << x)); + } else { + this->activeCaptureBuffers[ix++] = this->captureBuffers[sourceIndex]; } - this->activeCaptureBuffers[ix++] = this->captureBuffers[sourceIndex]; } this->activePlaybackBuffers.resize(channelSelection.GetOutputAudioPorts().size()); @@ -1104,9 +1106,10 @@ namespace pipedal int sourceIndex = IndexFromPortName(x); if (sourceIndex >= playbackBuffers.size()) { - throw PiPedalArgumentException("Invalid output port."); + Lv2Log::error(SS("Invalid audio output port: " << x)); + } else { + this->activePlaybackBuffers[ix++] = this->playbackBuffers[sourceIndex]; } - this->activePlaybackBuffers[ix++] = this->playbackBuffers[sourceIndex]; } audioThread = new std::jthread([this]() @@ -1598,15 +1601,15 @@ namespace pipedal } inputAudioPorts.clear(); - for (unsigned int i = 0; i < playbackChannels; ++i) + for (unsigned int i = 0; i < captureChannels; ++i) { - inputAudioPorts.push_back(SS("system::playback_" << i)); + inputAudioPorts.push_back(SS("system::capture_" << i)); } outputAudioPorts.clear(); - for (unsigned int i = 0; i < captureChannels; ++i) + for (unsigned int i = 0; i < playbackChannels; ++i) { - outputAudioPorts.push_back(SS("system::capture_" << i)); + outputAudioPorts.push_back(SS("system::playback_" << i)); } result = true; diff --git a/src/ConfigMain.cpp b/src/ConfigMain.cpp index 854dcb1..2b1f4da 100644 --- a/src/ConfigMain.cpp +++ b/src/ConfigMain.cpp @@ -122,10 +122,10 @@ void EnableService() void DisableService() { #if INSTALL_JACK_SERVICE || UNINSTALL_JACK_SERVICE - if (sysExec(SYSTEMCTL_BIN " disable " JACK_SERVICE ".service") != EXIT_SUCCESS) + if (silentSysExec(SYSTEMCTL_BIN " disable " JACK_SERVICE ".service") != EXIT_SUCCESS) { #if INSTALL_JACK_SERVICE - cout << "Error: Failed to disable the " JACK_SERVICE " service."; + // cout << "Error: Failed to disable the " JACK_SERVICE " service."; #endif } #endif @@ -165,10 +165,10 @@ void StopService(bool excludeShutdownService = false) #endif } #if INSTALL_JACK_SERVICE || UNINSTALL_JACK_SERVICE - if (sysExec(SYSTEMCTL_BIN " stop " JACK_SERVICE ".service") != EXIT_SUCCESS) + if (silentSysExec(SYSTEMCTL_BIN " stop " JACK_SERVICE ".service") != EXIT_SUCCESS) { #if INSTALL_JACK_SERVICE - cout << PiPedalException("Failed to stop the " JACK_SERVICE " service."); + // cout << PiPedalException("Failed to stop the " JACK_SERVICE " service."); #endif } #endif diff --git a/src/PiPedalModel.cpp b/src/PiPedalModel.cpp index c2abee5..71d9fba 100644 --- a/src/PiPedalModel.cpp +++ b/src/PiPedalModel.cpp @@ -227,14 +227,18 @@ void PiPedalModel::Load() try { jackHost->Open(this->jackServerSettings, selection); - - std::shared_ptr lv2PedalBoard{this->lv2Host.CreateLv2PedalBoard(this->pedalBoard)}; - this->lv2PedalBoard = lv2PedalBoard; - jackHost->SetPedalBoard(lv2PedalBoard); - } - catch (PiPedalException &e) + try { + std::shared_ptr lv2PedalBoard{this->lv2Host.CreateLv2PedalBoard(this->pedalBoard)}; + this->lv2PedalBoard = lv2PedalBoard; + jackHost->SetPedalBoard(lv2PedalBoard); + } + catch (const std::exception &e) + { + Lv2Log::error("Failed to load initial plugin. (%s)", e.what()); + } + } catch (std::exception &e) { - Lv2Log::error("Failed to load initial plugin. (%s)", e.what()); + Lv2Log::error("Failed to start audio device. %s", e.what()); } } else