+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.3.54
|
VERSION 1.3.55
|
||||||
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.3.54-Release")
|
set (DISPLAY_VERSION "PiPedal v1.3.55-Release")
|
||||||
set (PACKAGE_ARCHITECTURE "arm64")
|
set (PACKAGE_ARCHITECTURE "arm64")
|
||||||
set (CMAKE_INSTALL_PREFIX "/usr/")
|
set (CMAKE_INSTALL_PREFIX "/usr/")
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ static int ToOsSignalType(SignalHandler::SignalType signalType)
|
|||||||
case SignalHandler::Hangup: result = SIGHUP; break;
|
case SignalHandler::Hangup: result = SIGHUP; break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw std::runtime_error("INvalid signal type");
|
throw std::runtime_error("Invalid signal type");
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.3.54</a>
|
Download: <a href='https://rerdavies.github.io/pipedal/download.html'>v1.3.55</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.3.54 Release, providing [snapshots](https://rerdavies.github.io/pipedal/Snaphots.html), and a new Performance View. See the [release notes](https://rerdavies.github.io/pipedal/ReleaseNotes) for details.
|
#### NEW version 1.3.55 Release, providing [snapshots](https://rerdavies.github.io/pipedal/Snaphots.html), and a new Performance View. See the [release notes](https://rerdavies.github.io/pipedal/ReleaseNotes) for details.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+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.3.54](https://github.com/rerdavies/pipedal/releases/download/)
|
- [Raspberry Pi OS bookworm (64-bit) v1.3.55](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.3.54 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.3.55 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.3.54_arm64.deb
|
sudo apt-get install pipedal_1.3.55_arm64.deb
|
||||||
```
|
```
|
||||||
Adjust accordingly if you have downloaded v1.1.31.
|
Adjust accordingly if you have downloaded v1.1.31.
|
||||||
|
|
||||||
|
|||||||
+11
-1
@@ -1,4 +1,14 @@
|
|||||||
# Release Notes
|
# Release Notes
|
||||||
|
|
||||||
|
## PiPedal 1.3.55 Release
|
||||||
|
|
||||||
|
More snapshot problems.
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
- Crashes related to snapshots and split controls.
|
||||||
|
- Loading/reloading/error screens go on top of Snapshot dialogs.
|
||||||
|
|
||||||
|
|
||||||
## PiPedal 1.3.54 Release
|
## PiPedal 1.3.54 Release
|
||||||
|
|
||||||
Improvements to and fixes for hotspot functionality. Fixes for problems with snapshots.
|
Improvements to and fixes for hotspot functionality. Fixes for problems with snapshots.
|
||||||
@@ -8,7 +18,7 @@ Minor features;
|
|||||||
|
|
||||||
- Uploaded .zip files create a top-level directory with the name of the zip file if the zip file doesn't contain a single root-level directory. (released in 1.3.53)
|
- Uploaded .zip files create a top-level directory with the name of the zip file if the zip file doesn't contain a single root-level directory. (released in 1.3.53)
|
||||||
|
|
||||||
Bug fixes.
|
Bug fixes:
|
||||||
- Various crashes related to snapshots.
|
- Various crashes related to snapshots.
|
||||||
|
|
||||||
- Applying changes to Wi-Fi hotspot configuration would not change the configuration until PiPedal was rebooted (a regression).
|
- Applying changes to Wi-Fi hotspot configuration would not change the configuration until PiPedal was rebooted (a regression).
|
||||||
|
|||||||
+2
-2
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
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.3.54/pipedal_1.3.54_arm64.deb">Raspberry Pi OS Bookworm (64-bit) v1.3.54</a>
|
- <a href="https://github.com/rerdavies/pipedal/releases/download/v1.3.55/pipedal_1.3.55_arm64.deb">Raspberry Pi OS Bookworm (64-bit) v1.3.55</a>
|
||||||
|
|
||||||
|
|
||||||
Install the package by running
|
Install the package by running
|
||||||
@@ -12,7 +12,7 @@ Install the package by running
|
|||||||
```
|
```
|
||||||
sudo apt update
|
sudo apt update
|
||||||
cd ~/Downloads
|
cd ~/Downloads
|
||||||
sudo apt-get install ./pipedal_1.3.54_arm64.deb
|
sudo apt-get install ./pipedal_1.3.55_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.3.54</i></a>
|
<a href="Installing.html"><i>v1.3.55</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.3.54 Release. See the [release notes](https://rerdavies.github.io/pipedal/ReleaseNotes) for details.
|
#### NEW version 1.3.55 Release. See the [release notes](https://rerdavies.github.io/pipedal/ReleaseNotes) for details.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+136
-123
@@ -17,12 +17,12 @@
|
|||||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
// 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.
|
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
import { SyntheticEvent } from 'react';
|
|
||||||
import { WithStyles } from '@mui/styles';
|
import { WithStyles } from '@mui/styles';
|
||||||
|
|
||||||
import './AppThemed.css';
|
import './AppThemed.css';
|
||||||
|
//import {alpha} from '@mui/material/styles';
|
||||||
import AppBar from '@mui/material/AppBar';
|
import AppBar from '@mui/material/AppBar';
|
||||||
|
import Modal from '@mui/material/Modal';
|
||||||
import Toolbar from '@mui/material/Toolbar';
|
import Toolbar from '@mui/material/Toolbar';
|
||||||
import CssBaseline from '@mui/material/CssBaseline';
|
import CssBaseline from '@mui/material/CssBaseline';
|
||||||
import Typography from '@mui/material/Typography';
|
import Typography from '@mui/material/Typography';
|
||||||
@@ -36,7 +36,9 @@ import FullscreenIcon from '@mui/icons-material/Fullscreen';
|
|||||||
import FullscreenExitIcon from '@mui/icons-material/FullscreenExit';
|
import FullscreenExitIcon from '@mui/icons-material/FullscreenExit';
|
||||||
import List from '@mui/material/List';
|
import List from '@mui/material/List';
|
||||||
import Divider from '@mui/material/Divider';
|
import Divider from '@mui/material/Divider';
|
||||||
import ListItem from '@mui/material/ListItem';
|
// import ListItem from '@mui/material/ListItem';
|
||||||
|
import ListItemButton from '@mui/material/ListItemButton';
|
||||||
|
|
||||||
import ListItemIcon from '@mui/material/ListItemIcon';
|
import ListItemIcon from '@mui/material/ListItemIcon';
|
||||||
import ListItemText from '@mui/material/ListItemText';
|
import ListItemText from '@mui/material/ListItemText';
|
||||||
import CircularProgress from '@mui/material/CircularProgress';
|
import CircularProgress from '@mui/material/CircularProgress';
|
||||||
@@ -92,6 +94,17 @@ const appStyles = (theme: Theme) => createStyles({
|
|||||||
listSubheader: {
|
listSubheader: {
|
||||||
backgroundImage: "linear-gradient(255,255,255,0.15),rgba(255,255,255,0.15)"
|
backgroundImage: "linear-gradient(255,255,255,0.15),rgba(255,255,255,0.15)"
|
||||||
},
|
},
|
||||||
|
loadingMask: {
|
||||||
|
position: "absolute",
|
||||||
|
minHeight: "10em",
|
||||||
|
left: "0px",
|
||||||
|
top: "0px",
|
||||||
|
right: "0px",
|
||||||
|
bottom: "0px",
|
||||||
|
opacity: 0.8,
|
||||||
|
background:
|
||||||
|
isDarkMode() ? "#222" : "#DDD",
|
||||||
|
},
|
||||||
loadingContent: {
|
loadingContent: {
|
||||||
display: "block",
|
display: "block",
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
@@ -100,7 +113,6 @@ const appStyles = (theme: Theme) => createStyles({
|
|||||||
top: "0px",
|
top: "0px",
|
||||||
width: "100%",
|
width: "100%",
|
||||||
height: "100%",
|
height: "100%",
|
||||||
background: isDarkMode() ? "#222" : "#DDD",
|
|
||||||
opacity: "0.95",
|
opacity: "0.95",
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
@@ -166,22 +178,22 @@ const appStyles = (theme: Theme) => createStyles({
|
|||||||
|
|
||||||
},
|
},
|
||||||
loadingBox: {
|
loadingBox: {
|
||||||
position: "relative",
|
display: "flex",
|
||||||
|
flexFlow: "column nowrap",
|
||||||
|
position: "absolute",
|
||||||
top: "20%",
|
top: "20%",
|
||||||
|
left: 0, right: 0,
|
||||||
color: isDarkMode() ? theme.palette.text.secondary : "#888",
|
color: isDarkMode() ? theme.palette.text.secondary : "#888",
|
||||||
// border: "3px solid #888",
|
// border: "3px solid #888",
|
||||||
borderRadius: "12px",
|
alignItems: "center",
|
||||||
padding: "12px",
|
|
||||||
justifyContent: "center",
|
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
opacity: 0.8,
|
opacity: 0.8,
|
||||||
zIndex: 2010
|
|
||||||
|
|
||||||
},
|
},
|
||||||
loadingBoxItem: {
|
loadingBoxItem: {
|
||||||
justifyContent: "center",
|
display: "flex", flexFlow: "row nowrap",
|
||||||
|
alignItems: "center",
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
zIndex: 2010
|
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -247,9 +259,8 @@ function setFullScreen(value: boolean) {
|
|||||||
|
|
||||||
if (docEl.requestFullscren) // the latest offical api.
|
if (docEl.requestFullscren) // the latest offical api.
|
||||||
{
|
{
|
||||||
if (value)
|
if (value) {
|
||||||
{
|
window.document.documentElement.requestFullscreen({ navigationUI: "show" });
|
||||||
window.document.documentElement.requestFullscreen({navigationUI: "show"});
|
|
||||||
} else {
|
} else {
|
||||||
window.document.exitFullscreen();
|
window.document.exitFullscreen();
|
||||||
}
|
}
|
||||||
@@ -267,10 +278,10 @@ function setFullScreen(value: boolean) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function preventDefault(e: SyntheticEvent): void {
|
// function preventDefault(e: SyntheticEvent): void {
|
||||||
e.stopPropagation();
|
// e.stopPropagation();
|
||||||
e.preventDefault();
|
// e.preventDefault();
|
||||||
}
|
// }
|
||||||
|
|
||||||
type AppState = {
|
type AppState = {
|
||||||
zoomedControlInfo: ZoomedControlInfo | undefined;
|
zoomedControlInfo: ZoomedControlInfo | undefined;
|
||||||
@@ -403,7 +414,8 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
onOpenBank(bankId: number) {
|
handleSpecificBank(bankId: number) {
|
||||||
|
|
||||||
this.model_.openBank(bankId)
|
this.model_.openBank(bankId)
|
||||||
.catch((error) => this.model_.showAlert(error.toString()));
|
.catch((error) => this.model_.showAlert(error.toString()));
|
||||||
|
|
||||||
@@ -491,17 +503,15 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
|||||||
|
|
||||||
}
|
}
|
||||||
handleDrawerSelectBank() {
|
handleDrawerSelectBank() {
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
isDrawerOpen: false,
|
|
||||||
bankDialogOpen: true,
|
bankDialogOpen: true,
|
||||||
editBankDialogOpen: false
|
editBankDialogOpen: false
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
handleDrawerDonationClick() {
|
handleDrawerDonationClick() {
|
||||||
this.setState({
|
this.hideDrawer(false);
|
||||||
isDrawerOpen: false,
|
|
||||||
});
|
|
||||||
if (this.model_.isAndroidHosted()) {
|
if (this.model_.isAndroidHosted()) {
|
||||||
this.model_.showAndroidDonationActivity();
|
this.model_.showAndroidDonationActivity();
|
||||||
} else {
|
} else {
|
||||||
@@ -514,14 +524,12 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
|||||||
|
|
||||||
handleDrawerAboutClick() {
|
handleDrawerAboutClick() {
|
||||||
this.setState({
|
this.setState({
|
||||||
isDrawerOpen: false,
|
|
||||||
aboutDialogOpen: true
|
aboutDialogOpen: true
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
handleDrawerRenameBank() {
|
handleDrawerRenameBank() {
|
||||||
this.setState({
|
this.setState({
|
||||||
isDrawerOpen: false,
|
|
||||||
renameBankDialogOpen: true,
|
renameBankDialogOpen: true,
|
||||||
saveBankAsDialogOpen: false
|
saveBankAsDialogOpen: false
|
||||||
});
|
});
|
||||||
@@ -529,7 +537,6 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
|||||||
}
|
}
|
||||||
handleDrawerSaveBankAs() {
|
handleDrawerSaveBankAs() {
|
||||||
this.setState({
|
this.setState({
|
||||||
isDrawerOpen: false,
|
|
||||||
renameBankDialogOpen: false,
|
renameBankDialogOpen: false,
|
||||||
saveBankAsDialogOpen: true
|
saveBankAsDialogOpen: true
|
||||||
});
|
});
|
||||||
@@ -657,6 +664,8 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
|||||||
let bankEntries = Math.floor((height - K) / ENTRY_HEIGHT);
|
let bankEntries = Math.floor((height - K) / ENTRY_HEIGHT);
|
||||||
if (bankEntries < 1) bankEntries = 1;
|
if (bankEntries < 1) bankEntries = 1;
|
||||||
if (bankEntries > 7) bankEntries = 7;
|
if (bankEntries > 7) bankEntries = 7;
|
||||||
|
if (bankEntries === 2) bankEntries = 1;
|
||||||
|
|
||||||
this.setState({ bankDisplayItems: bankEntries });
|
this.setState({ bankDisplayItems: bankEntries });
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -686,27 +695,33 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
|||||||
}
|
}
|
||||||
|
|
||||||
shortBankList(banks: BankIndex): BankIndexEntry[] {
|
shortBankList(banks: BankIndex): BankIndexEntry[] {
|
||||||
let n = this.state.bankDisplayItems;
|
let nDisplayEntries = this.state.bankDisplayItems;
|
||||||
let entries = banks.entries;
|
let entries = banks.entries;
|
||||||
if (entries.length < n + 1) { // +1 for the .... entry.
|
let nListEntries = entries.length;
|
||||||
return entries;
|
|
||||||
}
|
|
||||||
let result: BankIndexEntry[] = [];
|
let result: BankIndexEntry[] = [];
|
||||||
let selectedIndex = -1;
|
|
||||||
for (let i = 0; i < entries.length; ++i) {
|
if (nListEntries <= nDisplayEntries) {
|
||||||
if (entries[i].instanceId === banks.selectedBank) {
|
for (let i = 0; i < nListEntries; ++i) {
|
||||||
selectedIndex = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (n > entries.length) n = entries.length;
|
|
||||||
if (selectedIndex > n) {
|
|
||||||
for (let i = 0; i < n - 1; ++i) {
|
|
||||||
result.push(entries[i]);
|
result.push(entries[i]);
|
||||||
}
|
}
|
||||||
result.push(entries[selectedIndex]);
|
|
||||||
} else {
|
} else {
|
||||||
for (let i = 0; i < n; ++i) {
|
// a subset of the list CENTERED on the currently selected entry.
|
||||||
|
let selectedIndex = 0;
|
||||||
|
for (let i = 0; i < nListEntries; ++i) {
|
||||||
|
if (entries[i].instanceId === banks.selectedBank) {
|
||||||
|
selectedIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let minN = selectedIndex - Math.floor(nDisplayEntries / 2);
|
||||||
|
if (minN < 0) minN = 0;
|
||||||
|
let maxN = minN + nDisplayEntries;
|
||||||
|
if (maxN > entries.length) {
|
||||||
|
maxN = entries.length;
|
||||||
|
}
|
||||||
|
for (let i = minN; i < maxN; ++i) {
|
||||||
result.push(entries[i]);
|
result.push(entries[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -747,7 +762,7 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
|||||||
<div style={{
|
<div style={{
|
||||||
colorScheme: isDarkMode() ? "dark" : "light", // affects scrollbar color
|
colorScheme: isDarkMode() ? "dark" : "light", // affects scrollbar color
|
||||||
minHeight: 300, minWidth: 300,
|
minHeight: 300, minWidth: 300,
|
||||||
position: "absolute", left:0, top: 0, right:0,bottom:0,
|
position: "absolute", left: 0, top: 0, right: 0, bottom: 0,
|
||||||
overscrollBehavior: this.state.isDebug ? "auto" : "none"
|
overscrollBehavior: this.state.isDebug ? "auto" : "none"
|
||||||
}}
|
}}
|
||||||
onContextMenu={(e) => {
|
onContextMenu={(e) => {
|
||||||
@@ -831,11 +846,11 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<TemporaryDrawer position='left' title="PiPedal"
|
<TemporaryDrawer position='left' title="PiPedal"
|
||||||
is_open={this.state.isDrawerOpen} onClose={() => { this.hideDrawer(); }} >
|
is_open={this.state.isDrawerOpen} onClose={() => { this.hideDrawer(false); }} >
|
||||||
|
|
||||||
<List>
|
<List>
|
||||||
<ListItem button key='PerformanceView'
|
<ListItemButton key='PerformanceView'
|
||||||
onClick={(ev) => {
|
onClick={(ev: any) => {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
this.hideDrawer(true);
|
this.hideDrawer(true);
|
||||||
this.setState({ performanceView: true });
|
this.setState({ performanceView: true });
|
||||||
@@ -844,7 +859,7 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
|||||||
<FxAmplifierIcon color='inherit' className={classes.menuIcon} style={{ width: 24, height: 24 }} />
|
<FxAmplifierIcon color='inherit' className={classes.menuIcon} style={{ width: 24, height: 24 }} />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText primary='Performance View' />
|
<ListItemText primary='Performance View' />
|
||||||
</ListItem>
|
</ListItemButton>
|
||||||
</List>
|
</List>
|
||||||
<Divider />
|
<Divider />
|
||||||
<ListSubheader className="listSubheader" component="div" id="xnested-list-subheader" style={{ lineHeight: "24px", height: 24, background: "rgba(12,12,12,0.0)" }}
|
<ListSubheader className="listSubheader" component="div" id="xnested-list-subheader" style={{ lineHeight: "24px", height: 24, background: "rgba(12,12,12,0.0)" }}
|
||||||
@@ -856,20 +871,24 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
|||||||
{
|
{
|
||||||
shortBankList.map((bank) => {
|
shortBankList.map((bank) => {
|
||||||
return (
|
return (
|
||||||
<ListItem button key={'bank' + bank.instanceId} selected={bank.instanceId === this.state.banks.selectedBank}
|
<ListItemButton key={'bank' + bank.instanceId} selected={bank.instanceId === this.state.banks.selectedBank}
|
||||||
onClick={() => this.onOpenBank(bank.instanceId)}
|
onClick={(ev: any) => {
|
||||||
|
ev.stopPropagation();
|
||||||
|
this.hideDrawer(false);
|
||||||
|
this.handleSpecificBank(bank.instanceId);
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
|
|
||||||
<ListItemText primary={bank.name} />
|
<ListItemText primary={bank.name} />
|
||||||
</ListItem>
|
</ListItemButton>
|
||||||
|
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
showBankSelectDialog && (
|
showBankSelectDialog && (
|
||||||
<ListItem button key={'bankDOTDOTDOT'} selected={false}
|
<ListItemButton key={'bankDOTDOTDOT'} selected={false}
|
||||||
onClick={(ev) => {
|
onClick={(ev: any) => {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
this.hideDrawer(true);
|
this.hideDrawer(true);
|
||||||
this.handleDrawerSelectBank();
|
this.handleDrawerSelectBank();
|
||||||
@@ -877,7 +896,7 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
|||||||
>
|
>
|
||||||
|
|
||||||
<ListItemText primary={"..."} />
|
<ListItemText primary={"..."} />
|
||||||
</ListItem>
|
</ListItemButton>
|
||||||
|
|
||||||
|
|
||||||
)
|
)
|
||||||
@@ -885,8 +904,8 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
|||||||
</List>
|
</List>
|
||||||
<Divider />
|
<Divider />
|
||||||
<List>
|
<List>
|
||||||
<ListItem button key='RenameBank'
|
<ListItemButton key='RenameBank'
|
||||||
onClick={(ev) => {
|
onClick={(ev: any) => {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
this.hideDrawer(true);
|
this.hideDrawer(true);
|
||||||
this.handleDrawerRenameBank()
|
this.handleDrawerRenameBank()
|
||||||
@@ -895,9 +914,9 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
|||||||
<RenameOutlineIcon color='inherit' className={classes.menuIcon} />
|
<RenameOutlineIcon color='inherit' className={classes.menuIcon} />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText primary='Rename bank' />
|
<ListItemText primary='Rename bank' />
|
||||||
</ListItem>
|
</ListItemButton>
|
||||||
<ListItem button key='SaveBank'
|
<ListItemButton key='SaveBank'
|
||||||
onClick={(ev) => {
|
onClick={(ev: any) => {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
this.hideDrawer(true);
|
this.hideDrawer(true);
|
||||||
this.handleDrawerSaveBankAs();
|
this.handleDrawerSaveBankAs();
|
||||||
@@ -906,9 +925,9 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
|||||||
<SaveBankAsIcon color="inherit" className={classes.menuIcon} />
|
<SaveBankAsIcon color="inherit" className={classes.menuIcon} />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText primary='Save as new bank' />
|
<ListItemText primary='Save as new bank' />
|
||||||
</ListItem>
|
</ListItemButton>
|
||||||
<ListItem button key='EditBanks'
|
<ListItemButton key='EditBanks'
|
||||||
onClick={(ev) => {
|
onClick={(ev: any) => {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
this.hideDrawer(true);
|
this.hideDrawer(true);
|
||||||
this.handleDrawerManageBanks();
|
this.handleDrawerManageBanks();
|
||||||
@@ -917,12 +936,12 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
|||||||
<EditBanksIcon color="inherit" className={classes.menuIcon} />
|
<EditBanksIcon color="inherit" className={classes.menuIcon} />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText primary='Manage banks...' />
|
<ListItemText primary='Manage banks...' />
|
||||||
</ListItem>
|
</ListItemButton>
|
||||||
</List>
|
</List>
|
||||||
<Divider />
|
<Divider />
|
||||||
<List>
|
<List>
|
||||||
<ListItem button key='Settings'
|
<ListItemButton key='Settings'
|
||||||
onClick={(ev) => {
|
onClick={(ev: any) => {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
this.hideDrawer(true);
|
this.hideDrawer(true);
|
||||||
this.handleDrawerSettingsClick()
|
this.handleDrawerSettingsClick()
|
||||||
@@ -931,9 +950,9 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
|||||||
<SettingsIcon color="inherit" className={classes.menuIcon} />
|
<SettingsIcon color="inherit" className={classes.menuIcon} />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText primary='Settings' />
|
<ListItemText primary='Settings' />
|
||||||
</ListItem>
|
</ListItemButton>
|
||||||
<ListItem button key='About'
|
<ListItemButton key='About'
|
||||||
onClick={(ev) => {
|
onClick={(ev: any) => {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
this.hideDrawer(true);
|
this.hideDrawer(true);
|
||||||
this.handleDrawerAboutClick();
|
this.handleDrawerAboutClick();
|
||||||
@@ -942,18 +961,17 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
|||||||
<HelpOutlineIcon color="inherit" className={classes.menuIcon} />
|
<HelpOutlineIcon color="inherit" className={classes.menuIcon} />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText primary='About' />
|
<ListItemText primary='About' />
|
||||||
</ListItem>
|
</ListItemButton>
|
||||||
<ListItem button key='Donations'
|
<ListItemButton key='Donations'
|
||||||
onClick={(ev) => {
|
onClick={(ev: any) => {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
this.hideDrawer(true);
|
|
||||||
this.handleDrawerDonationClick();
|
this.handleDrawerDonationClick();
|
||||||
}}>
|
}}>
|
||||||
<ListItemIcon >
|
<ListItemIcon >
|
||||||
<VolunteerActivismIcon className={classes.menuIcon} color="inherit" />
|
<VolunteerActivismIcon className={classes.menuIcon} color="inherit" />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText primary='Donations' />
|
<ListItemText primary='Donations' />
|
||||||
</ListItem>
|
</ListItemButton>
|
||||||
</List>
|
</List>
|
||||||
|
|
||||||
</TemporaryDrawer>
|
</TemporaryDrawer>
|
||||||
@@ -1040,67 +1058,62 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
|||||||
</DialogEx>
|
</DialogEx>
|
||||||
|
|
||||||
|
|
||||||
<div className={classes.errorContent} style={{ zIndex: 1200, display: this.state.displayState === State.Error ? "flex" : "none" }}
|
<Modal open={this.state.displayState === State.Error}
|
||||||
onMouseDown={preventDefault} onKeyDown={preventDefault}
|
aria-label="fatal-error"
|
||||||
|
aria-describedby="aria-error-text"
|
||||||
>
|
>
|
||||||
<div className={classes.errorContentMask} />
|
<div style={{
|
||||||
<div style={{ flex: "2 2 3px", height: 20 }} > </div>
|
display: "flex", flexFlow: "column nowrap",
|
||||||
<div className={classes.errorMessageBox} style={{ position: "relative" }} >
|
position: "absolute", top: 0, left: 0, right: 0, bottom: 0
|
||||||
<div style={{ fontSize: "30px", position: "absolute", left: 0, top: 3, color: "#A00" }}>
|
}}
|
||||||
<ErrorOutlineIcon color="inherit" fontSize="inherit" style={{ float: "left", marginRight: "12px" }} />
|
>
|
||||||
</div>
|
<div className={classes.loadingMask} />
|
||||||
<div style={{ marginLeft: 40, marginTop: 3 }}>
|
<div style={{ flex: "2 2 3px", height: 20 }} > </div>
|
||||||
<p className={classes.errorText}>
|
<div className={classes.errorMessageBox} style={{ position: "relative" }} >
|
||||||
Error: {this.state.errorMessage}
|
<div style={{ fontSize: "30px", position: "absolute", left: 0, top: 3, color: "#A00" }}>
|
||||||
</p>
|
<ErrorOutlineIcon color="inherit" fontSize="inherit" style={{ float: "left", marginRight: "12px" }} />
|
||||||
</div>
|
</div>
|
||||||
<div style={{ paddingTop: 50, paddingLeft: 36, textAlign: "left" }}>
|
<div style={{ marginLeft: 40, marginTop: 3 }}>
|
||||||
<Button variant='contained' color="primary"
|
<p className={classes.errorText} id="aria-error-text">
|
||||||
onClick={() => this.handleReload()} >
|
Error: {this.state.errorMessage}
|
||||||
Reload
|
</p>
|
||||||
</Button>
|
</div>
|
||||||
|
<div style={{ paddingTop: 50, paddingLeft: 36, textAlign: "left" }}>
|
||||||
|
<Button variant='contained' color="primary"
|
||||||
|
onClick={() => this.handleReload()} >
|
||||||
|
Reload
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div style={{ flex: "5 5 auto", height: 20 }} > </div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style={{ flex: "5 5 auto", height: 20 }} > </div>
|
</Modal >
|
||||||
|
|
||||||
</div>
|
|
||||||
{/* initial load mask*/}
|
|
||||||
<div className={classes.errorContent} style={{ display: this.state.displayState === State.Loading ? "block" : "none",zIndex: 1201 }}>
|
|
||||||
<div className={classes.errorContentMask} />
|
|
||||||
<div className={classes.loadingBox}>
|
|
||||||
<div className={classes.loadingBoxItem}>
|
|
||||||
<CircularProgress color="inherit" className={classes.loadingBoxItem} />
|
|
||||||
</div>
|
|
||||||
<Typography noWrap variant="body2" className={classes.loadingBoxItem}>
|
|
||||||
Loading...
|
|
||||||
</Typography>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/* Reloading mask */}
|
{/* Reloading mask */}
|
||||||
<div className={classes.errorContent} style={{
|
< Modal
|
||||||
zIndex: 1201,
|
open={wantsReloadingScreen(this.state.displayState) || this.state.displayState === State.Loading}
|
||||||
display: (
|
aria-label="loading"
|
||||||
wantsReloadingScreen(this.state.displayState)
|
aria-describedby="reloading-modal-description"
|
||||||
? "block" : "none"
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<div className={classes.errorContentMask} />
|
<div style={{display: "flex",flexFlow: "column nowrap", alignItems: "center"}}>
|
||||||
|
<div className={classes.loadingMask} />
|
||||||
<div className={classes.loadingBox}>
|
<div className={classes.loadingBox}>
|
||||||
<div className={classes.loadingBoxItem}>
|
<div className={classes.loadingBoxItem}>
|
||||||
<CircularProgress color="inherit" className={classes.loadingBoxItem} />
|
<CircularProgress color="inherit" className={classes.loadingBoxItem} />
|
||||||
|
</div>
|
||||||
|
<Typography id="reloading-modal-description" display="block" noWrap variant="body2" className={classes.progressText}>
|
||||||
|
{
|
||||||
|
this.state.displayState === State.Loading ?
|
||||||
|
"Loading..."
|
||||||
|
:this.getReloadingMessage()
|
||||||
|
}
|
||||||
|
</Typography>
|
||||||
</div>
|
</div>
|
||||||
<Typography display="block" noWrap variant="body2" className={classes.progressText}>
|
|
||||||
{this.getReloadingMessage()}
|
|
||||||
</Typography>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Modal >
|
||||||
|
|
||||||
</div >
|
</div >
|
||||||
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -206,6 +206,7 @@ export class PedalboardItem implements Deserializable<PedalboardItem> {
|
|||||||
|
|
||||||
export class SnapshotValue {
|
export class SnapshotValue {
|
||||||
deserialize(input: any): SnapshotValue {
|
deserialize(input: any): SnapshotValue {
|
||||||
|
this.isEnabled = input.isEnabled;
|
||||||
this.instanceId = input.instanceId;
|
this.instanceId = input.instanceId;
|
||||||
this.controlValues = ControlValue.deserializeArray(input.controlValues);
|
this.controlValues = ControlValue.deserializeArray(input.controlValues);
|
||||||
this.lv2State = input.lv2state;
|
this.lv2State = input.lv2state;
|
||||||
|
|||||||
+5
-1
@@ -135,7 +135,7 @@ namespace pipedal
|
|||||||
{
|
{
|
||||||
auto maxInputControl = effect->GetMaxInputControl();
|
auto maxInputControl = effect->GetMaxInputControl();
|
||||||
inputControlValues.resize(maxInputControl);
|
inputControlValues.resize(maxInputControl);
|
||||||
|
this->enabled = true;
|
||||||
for (uint64_t i = 0; i < maxInputControl; ++i)
|
for (uint64_t i = 0; i < maxInputControl; ++i)
|
||||||
{
|
{
|
||||||
bool isInputControl = effect->IsInputControl(i);
|
bool isInputControl = effect->IsInputControl(i);
|
||||||
@@ -150,6 +150,7 @@ namespace pipedal
|
|||||||
}
|
}
|
||||||
if (snapshotValue)
|
if (snapshotValue)
|
||||||
{
|
{
|
||||||
|
this->enabled = snapshotValue->isEnabled_;
|
||||||
for (auto &controlValue : snapshotValue->controlValues_)
|
for (auto &controlValue : snapshotValue->controlValues_)
|
||||||
{
|
{
|
||||||
auto index = effect->GetControlIndex(controlValue.key());
|
auto index = effect->GetControlIndex(controlValue.key());
|
||||||
@@ -202,6 +203,8 @@ namespace pipedal
|
|||||||
}
|
}
|
||||||
void ApplyValues(IEffect *effect)
|
void ApplyValues(IEffect *effect)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
effect->SetBypass(this->enabled);
|
||||||
if (effect != pEffect)
|
if (effect != pEffect)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Wrong effect");
|
throw std::runtime_error("Wrong effect");
|
||||||
@@ -226,6 +229,7 @@ namespace pipedal
|
|||||||
private:
|
private:
|
||||||
IEffect *pEffect;
|
IEffect *pEffect;
|
||||||
Lv2PluginState lv2State;
|
Lv2PluginState lv2State;
|
||||||
|
bool enabled;
|
||||||
std::vector<InputControlEntry> inputControlValues;
|
std::vector<InputControlEntry> inputControlValues;
|
||||||
std::vector<PathPatchProperty> pathPatchProperties;
|
std::vector<PathPatchProperty> pathPatchProperties;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -482,8 +482,8 @@ void AvahiService::Wait()
|
|||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
case ServiceState::Unitialized:
|
case ServiceState::Unitialized:
|
||||||
throw std::runtime_error("Invalid state");
|
done = true;
|
||||||
|
break;
|
||||||
case ServiceState::Initializing:
|
case ServiceState::Initializing:
|
||||||
case ServiceState::Settling:
|
case ServiceState::Settling:
|
||||||
case ServiceState::Requested:
|
case ServiceState::Requested:
|
||||||
@@ -503,6 +503,8 @@ void AvahiService::Wait()
|
|||||||
if (clock::now() > waitTime)
|
if (clock::now() > waitTime)
|
||||||
{
|
{
|
||||||
Lv2Log::error("DNS/SD announcement timed out.");
|
Lv2Log::error("DNS/SD announcement timed out.");
|
||||||
|
done = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
||||||
|
|||||||
+71
-59
@@ -155,6 +155,49 @@ void DisableService()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool disableAvahiConfigLine(SystemConfigFile &avahi, const std::string §ion, const std::string &lineStart)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
// use-ipv6=no
|
||||||
|
int line = avahi.GetLineThatStartsWith(lineStart + "yes");
|
||||||
|
if (line != -1)
|
||||||
|
{
|
||||||
|
avahi.UndoableReplaceLine(line, lineStart + "no");
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (avahi.GetLineThatStartsWith(lineStart + "no") == -1)
|
||||||
|
{
|
||||||
|
line = avahi.GetLineThatStartsWith(section);
|
||||||
|
if (line == -1)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Unable to find [server] section.");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
++line;
|
||||||
|
// increment to end of section.
|
||||||
|
while (line < avahi.GetLineCount())
|
||||||
|
{
|
||||||
|
const auto &txt = avahi.Get(line);
|
||||||
|
if (txt.empty())
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (txt.starts_with("[")) // start of next section.
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
avahi.UndoableAddLine(line,lineStart+"no");
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
static void RestartAvahiService()
|
static void RestartAvahiService()
|
||||||
{
|
{
|
||||||
silentSysExec(SS(SYSTEMCTL_BIN << " restart avahi-daemon.service").c_str());
|
silentSysExec(SS(SYSTEMCTL_BIN << " restart avahi-daemon.service").c_str());
|
||||||
@@ -169,41 +212,10 @@ static void AvahiInstall()
|
|||||||
SystemConfigFile avahi(avahiConfig);
|
SystemConfigFile avahi(avahiConfig);
|
||||||
|
|
||||||
bool changed = avahi.RemoveUndoableActions();
|
bool changed = avahi.RemoveUndoableActions();
|
||||||
int line = avahi.GetLineThatStartsWith("use-ipv6=yes");
|
|
||||||
if (line != -1)
|
changed |= disableAvahiConfigLine(avahi, "[server]", "use-ipv6=");
|
||||||
{
|
changed |= disableAvahiConfigLine(avahi, "[publish]", "publish-aaaa-on-ipv4=");
|
||||||
avahi.UndoableReplaceLine(line, "use-ipv6=no");
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (avahi.GetLineThatStartsWith("use-ipv6=no") == -1)
|
|
||||||
{
|
|
||||||
line = avahi.GetLineThatStartsWith("[server]");
|
|
||||||
if (line == 1)
|
|
||||||
{
|
|
||||||
throw std::runtime_error("Unable to find [server] section.");
|
|
||||||
}
|
|
||||||
{
|
|
||||||
// increment to end of section.
|
|
||||||
while (line < avahi.GetLineCount())
|
|
||||||
{
|
|
||||||
const auto &txt = avahi.Get(line);
|
|
||||||
if (txt.empty())
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (txt.starts_with("[")) // start of next section.
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
++line;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
avahi.UndoableAddLine(avahi.GetLineCount(), "use-ipv6=no");
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (changed)
|
if (changed)
|
||||||
{
|
{
|
||||||
avahi.Save();
|
avahi.Save();
|
||||||
@@ -914,7 +926,7 @@ void Install(const fs::path &programPrefix, const std::string endpointAddress)
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
// apply policy changes we dropped into the polkit configuration files (allows pipedal_d to use NetworkManager dbus apis).
|
// apply policy changes we dropped into the polkit configuration files (allows pipedal_d to use NetworkManager dbus apis).
|
||||||
silentSysExec(SYSTEMCTL_BIN " restart polkit");
|
silentSysExec(SYSTEMCTL_BIN " restart polkit");
|
||||||
|
|
||||||
DeployVarConfig();
|
DeployVarConfig();
|
||||||
|
|
||||||
@@ -995,7 +1007,6 @@ void Install(const fs::path &programPrefix, const std::string endpointAddress)
|
|||||||
// add to netdev group
|
// add to netdev group
|
||||||
sysExec(USERMOD_BIN " -a -G " NETDEV_GROUP_NAME " " SERVICE_ACCOUNT_NAME);
|
sysExec(USERMOD_BIN " -a -G " NETDEV_GROUP_NAME " " SERVICE_ACCOUNT_NAME);
|
||||||
|
|
||||||
|
|
||||||
// create and configure /var directory.
|
// create and configure /var directory.
|
||||||
|
|
||||||
fs::path varDirectory("/var/pipedal");
|
fs::path varDirectory("/var/pipedal");
|
||||||
@@ -1211,11 +1222,11 @@ static void PrintHelp()
|
|||||||
<< "\n\n"
|
<< "\n\n"
|
||||||
<< "One of the following hotspot options can be specifed. If no hotspot option is given, the hotspot will always be enabled. "
|
<< "One of the following hotspot options can be specifed. If no hotspot option is given, the hotspot will always be enabled. "
|
||||||
<< "If one of the hotspot options are given, the PiPedal server will turn the hotspot on or off automatically, as conditions change."
|
<< "If one of the hotspot options are given, the PiPedal server will turn the hotspot on or off automatically, as conditions change."
|
||||||
<< "\n\n"
|
<< "\n\n"
|
||||||
<< "--home-network <wifi-ssid>\n"
|
<< "--home-network <wifi-ssid>\n"
|
||||||
<< AddIndent(4) << "Hotspot is disabled if the specificed Wi-Fi network is detected.\n"
|
<< AddIndent(4) << "Hotspot is disabled if the specificed Wi-Fi network is detected.\n"
|
||||||
<< AddIndent(-4)
|
<< AddIndent(-4)
|
||||||
<< "--no-ethernet\n"
|
<< "--no-ethernet\n"
|
||||||
<< AddIndent(4) << "Hotspot is disabled if an ethernet network is connected.\n"
|
<< AddIndent(4) << "Hotspot is disabled if an ethernet network is connected.\n"
|
||||||
<< AddIndent(-4)
|
<< AddIndent(-4)
|
||||||
<< "--no-wifi\n"
|
<< "--no-wifi\n"
|
||||||
@@ -1336,9 +1347,9 @@ int main(int argc, char **argv)
|
|||||||
parser.AddOption("--port", &portOption);
|
parser.AddOption("--port", &portOption);
|
||||||
parser.AddOption("--enable-hotspot", &enable_hotspot);
|
parser.AddOption("--enable-hotspot", &enable_hotspot);
|
||||||
parser.AddOption("--disable-hotspot", &disable_hotspot);
|
parser.AddOption("--disable-hotspot", &disable_hotspot);
|
||||||
parser.AddOption("--home-network",&homeNetwork);
|
parser.AddOption("--home-network", &homeNetwork);
|
||||||
parser.AddOption("--no-ethernet",&noEthernet);
|
parser.AddOption("--no-ethernet", &noEthernet);
|
||||||
parser.AddOption("--no-wifi",&noWifi);
|
parser.AddOption("--no-wifi", &noWifi);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
parser.Parse(argc, (const char **)argv);
|
parser.Parse(argc, (const char **)argv);
|
||||||
@@ -1367,9 +1378,7 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
int hotspotOptionCount =
|
int hotspotOptionCount =
|
||||||
(homeNetwork.length() != 0 ? 1: 0)
|
(homeNetwork.length() != 0 ? 1 : 0) + noEthernet + noWifi;
|
||||||
+ noEthernet
|
|
||||||
+ noWifi;
|
|
||||||
|
|
||||||
if (enable_hotspot)
|
if (enable_hotspot)
|
||||||
{
|
{
|
||||||
@@ -1377,7 +1386,9 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
throw std::runtime_error("Only one hotspot option at a time can be specified.");
|
throw std::runtime_error("Only one hotspot option at a time can be specified.");
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (hotspotOptionCount > 0)
|
if (hotspotOptionCount > 0)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Hotspot options only only valid when the --enable-hotspot option has been supplied.");
|
throw std::runtime_error("Hotspot options only only valid when the --enable-hotspot option has been supplied.");
|
||||||
@@ -1432,7 +1443,8 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
if (install)
|
if (install)
|
||||||
{
|
{
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
fs::path prefix;
|
fs::path prefix;
|
||||||
if (prefixOption.length() != 0)
|
if (prefixOption.length() != 0)
|
||||||
{
|
{
|
||||||
@@ -1465,8 +1477,8 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
Install(prefix, portOption);
|
Install(prefix, portOption);
|
||||||
FileSystemSync();
|
FileSystemSync();
|
||||||
|
}
|
||||||
} catch (const std::exception&e)
|
catch (const std::exception &e)
|
||||||
{
|
{
|
||||||
cout << "ERROR: " << e.what() << endl;
|
cout << "ERROR: " << e.what() << endl;
|
||||||
FileSystemSync();
|
FileSystemSync();
|
||||||
@@ -1475,10 +1487,12 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
else if (uninstall)
|
else if (uninstall)
|
||||||
{
|
{
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
Uninstall();
|
Uninstall();
|
||||||
FileSystemSync();
|
FileSystemSync();
|
||||||
} catch (const std::exception &e)
|
}
|
||||||
|
catch (const std::exception &e)
|
||||||
{
|
{
|
||||||
cout << "ERROR: " << e.what() << endl;
|
cout << "ERROR: " << e.what() << endl;
|
||||||
FileSystemSync();
|
FileSystemSync();
|
||||||
@@ -1489,7 +1503,6 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
RequireNetworkManager();
|
RequireNetworkManager();
|
||||||
StopService();
|
StopService();
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (start)
|
else if (start)
|
||||||
{
|
{
|
||||||
@@ -1506,14 +1519,12 @@ int main(int argc, char **argv)
|
|||||||
RequireNetworkManager();
|
RequireNetworkManager();
|
||||||
EnableService();
|
EnableService();
|
||||||
FileSystemSync();
|
FileSystemSync();
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (disable)
|
else if (disable)
|
||||||
{
|
{
|
||||||
RequireNetworkManager();
|
RequireNetworkManager();
|
||||||
DisableService();
|
DisableService();
|
||||||
FileSystemSync();
|
FileSystemSync();
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (enable_p2p)
|
else if (enable_p2p)
|
||||||
{
|
{
|
||||||
@@ -1541,8 +1552,7 @@ int main(int argc, char **argv)
|
|||||||
settings.Load();
|
settings.Load();
|
||||||
settings.enable_ = false;
|
settings.enable_ = false;
|
||||||
SetWifiDirectConfig(settings);
|
SetWifiDirectConfig(settings);
|
||||||
|
|
||||||
|
|
||||||
RestartService(true);
|
RestartService(true);
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -1557,15 +1567,17 @@ int main(int argc, char **argv)
|
|||||||
if (homeNetwork.length() != 0)
|
if (homeNetwork.length() != 0)
|
||||||
{
|
{
|
||||||
startMode = HotspotAutoStartMode::NotAtHome;
|
startMode = HotspotAutoStartMode::NotAtHome;
|
||||||
} else if (noEthernet)
|
}
|
||||||
|
else if (noEthernet)
|
||||||
{
|
{
|
||||||
startMode = HotspotAutoStartMode::NoEthernetConnection;
|
startMode = HotspotAutoStartMode::NoEthernetConnection;
|
||||||
} else if (noWifi)
|
}
|
||||||
|
else if (noWifi)
|
||||||
{
|
{
|
||||||
startMode = HotspotAutoStartMode::NoRememberedWifiConections;
|
startMode = HotspotAutoStartMode::NoRememberedWifiConections;
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.ParseArguments(argv,startMode,homeNetwork);
|
settings.ParseArguments(argv, startMode, homeNetwork);
|
||||||
|
|
||||||
if (settings.hasPassword_)
|
if (settings.hasPassword_)
|
||||||
{
|
{
|
||||||
|
|||||||
+4
-1
@@ -293,7 +293,10 @@ namespace pipedal
|
|||||||
|
|
||||||
virtual float GetOutputControlValue(int portIndex) const
|
virtual float GetOutputControlValue(int portIndex) const
|
||||||
{
|
{
|
||||||
return controlValues[portIndex];
|
if (portIndex >= 0 && portIndex < controlValues.size()) {
|
||||||
|
return controlValues[portIndex];
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void SetBypass(bool bypass)
|
virtual void SetBypass(bool bypass)
|
||||||
|
|||||||
+87
-32
@@ -20,6 +20,9 @@
|
|||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "Pedalboard.hpp"
|
#include "Pedalboard.hpp"
|
||||||
#include "AtomConverter.hpp"
|
#include "AtomConverter.hpp"
|
||||||
|
#include "PluginHost.hpp"
|
||||||
|
#include "AtomConverter.hpp"
|
||||||
|
#include "SplitEffect.hpp"
|
||||||
|
|
||||||
|
|
||||||
using namespace pipedal;
|
using namespace pipedal;
|
||||||
@@ -87,6 +90,19 @@ ControlValue* PedalboardItem::GetControlValue(const std::string&symbol)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PedalboardItem::SetControlValue(const std::string&symbol, float value)
|
||||||
|
{
|
||||||
|
ControlValue*controlValue = GetControlValue(symbol);
|
||||||
|
if (controlValue == nullptr) return false;
|
||||||
|
if (controlValue->value() != value)
|
||||||
|
{
|
||||||
|
controlValue->value(value);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const ControlValue* PedalboardItem::GetControlValue(const std::string&symbol) const
|
const ControlValue* PedalboardItem::GetControlValue(const std::string&symbol) const
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < this->controlValues().size(); ++i)
|
for (size_t i = 0; i < this->controlValues().size(); ++i)
|
||||||
@@ -117,14 +133,7 @@ bool Pedalboard::SetControlValue(int64_t pedalItemId, const std::string &symbol,
|
|||||||
{
|
{
|
||||||
PedalboardItem*item = GetItem(pedalItemId);
|
PedalboardItem*item = GetItem(pedalItemId);
|
||||||
if (!item) return false;
|
if (!item) return false;
|
||||||
ControlValue*controlValue = item->GetControlValue(symbol);
|
return item->SetControlValue(symbol,value);
|
||||||
if (controlValue == nullptr) return false;
|
|
||||||
if (controlValue->value() != value)
|
|
||||||
{
|
|
||||||
controlValue->value(value);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -190,12 +199,12 @@ bool IsPedalboardSplitItem(const PedalboardItem*self, const std::vector<Pedalboa
|
|||||||
return self->uri() == SPLIT_PEDALBOARD_ITEM_URI;
|
return self->uri() == SPLIT_PEDALBOARD_ITEM_URI;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Pedalboard::ApplySnapshot(int64_t snapshotIndex)
|
bool Pedalboard::ApplySnapshot(int64_t snapshotIndex, PluginHost&pluginHost)
|
||||||
{
|
{
|
||||||
if (snapshotIndex < 0 ||
|
if (snapshotIndex < 0 ||
|
||||||
snapshotIndex >= this->snapshots_.size() ||
|
snapshotIndex >= this->snapshots_.size() ||
|
||||||
this->snapshots_[snapshotIndex] == nullptr ||
|
this->snapshots_[snapshotIndex] == nullptr
|
||||||
this->selectedSnapshot() == snapshotIndex)
|
)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -210,15 +219,47 @@ bool Pedalboard::ApplySnapshot(int64_t snapshotIndex)
|
|||||||
auto plugins = this->GetAllPlugins();
|
auto plugins = this->GetAllPlugins();
|
||||||
for (PedalboardItem *pedalboardItem: plugins)
|
for (PedalboardItem *pedalboardItem: plugins)
|
||||||
{
|
{
|
||||||
SnapshotValue*snapshotValue = indexedValues[pedalboardItem->instanceId()];
|
if (!pedalboardItem->isEmpty())
|
||||||
if (snapshotValue)
|
|
||||||
{
|
{
|
||||||
pedalboardItem->ApplySnapshotValue(snapshotValue);
|
SnapshotValue*snapshotValue = indexedValues[pedalboardItem->instanceId()];
|
||||||
|
if (snapshotValue)
|
||||||
|
{
|
||||||
|
pedalboardItem->ApplySnapshotValue(snapshotValue);
|
||||||
|
} else {
|
||||||
|
pedalboardItem->ApplyDefaultValues(pluginHost);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PedalboardItem::ApplyDefaultValues(PluginHost&pluginHost)
|
||||||
|
{
|
||||||
|
if (isEmpty()) return;
|
||||||
|
auto pluginInfo = pluginHost.GetPluginInfo(this->uri());
|
||||||
|
if (!pluginInfo)
|
||||||
|
{
|
||||||
|
if (this->isSplit())
|
||||||
|
{
|
||||||
|
pluginInfo = GetSplitterPluginInfo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->isEnabled(true);
|
||||||
|
if (pluginInfo)
|
||||||
|
{
|
||||||
|
for (auto &port: pluginInfo->ports())
|
||||||
|
{
|
||||||
|
this->SetControlValue(port->symbol(),port->default_value());
|
||||||
|
}
|
||||||
|
// a cheat. this isn't actually true, but close enough.
|
||||||
|
for (auto &pathProperty: this->pathProperties_)
|
||||||
|
{
|
||||||
|
pathProperties_[pathProperty.first] = AtomConverter::EmptyPathstring();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void PedalboardItem::ApplySnapshotValue(SnapshotValue*snapshotValue)
|
void PedalboardItem::ApplySnapshotValue(SnapshotValue*snapshotValue)
|
||||||
{
|
{
|
||||||
std::map<std::string,float> cumulativeValues;
|
std::map<std::string,float> cumulativeValues;
|
||||||
@@ -240,6 +281,16 @@ void PedalboardItem::ApplySnapshotValue(SnapshotValue*snapshotValue)
|
|||||||
this->lv2State(snapshotValue->lv2State_);
|
this->lv2State(snapshotValue->lv2State_);
|
||||||
this->stateUpdateCount(this->stateUpdateCount()+1);
|
this->stateUpdateCount(this->stateUpdateCount()+1);
|
||||||
}
|
}
|
||||||
|
for (auto&property: snapshotValue->pathProperties_)
|
||||||
|
{
|
||||||
|
if (property.second == "null")
|
||||||
|
{
|
||||||
|
this->pathProperties_[property.first] = AtomConverter::EmptyPathstring();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
this->pathProperties_[property.first] = property.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
this->isEnabled(snapshotValue->isEnabled_);
|
this->isEnabled(snapshotValue->isEnabled_);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -278,17 +329,19 @@ bool PedalboardItem::IsStructurallyIdentical(const PedalboardItem&other) const
|
|||||||
}
|
}
|
||||||
if (this->isSplit()) // so is the other by virtue of idential uris.
|
if (this->isSplit()) // so is the other by virtue of idential uris.
|
||||||
{
|
{
|
||||||
auto myValue = this->GetControlValue("splitType");
|
// provisionally, it seems ok to change the split type.
|
||||||
auto otherValue = other.GetControlValue("splitType");
|
// auto myValue = this->GetControlValue("splitType");
|
||||||
if (myValue == nullptr || otherValue == nullptr) // actually an error.
|
// auto otherValue = other.GetControlValue("splitType");
|
||||||
{
|
// if (myValue == nullptr || otherValue == nullptr) // actually an error.
|
||||||
return false;
|
// {
|
||||||
}
|
// return false;
|
||||||
// split type changes potentially trigger buffer allocation changes,
|
// }
|
||||||
// so different split types are not structurally identical.
|
|
||||||
if (myValue->value() != otherValue->value()) {
|
// // split type changes potentially trigger buffer allocation changes,
|
||||||
return false;
|
// // so different split types are not structurally identical.
|
||||||
}
|
// if (myValue->value() != otherValue->value()) {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
if (topChain().size() != other.topChain().size())
|
if (topChain().size() != other.topChain().size())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -407,17 +460,19 @@ Snapshot Pedalboard::MakeSnapshotFromCurrentSettings(const Pedalboard &previousP
|
|||||||
{
|
{
|
||||||
Snapshot snapshot;
|
Snapshot snapshot;
|
||||||
// name and color don't matter. this is strictly for loading purposes.
|
// name and color don't matter. this is strictly for loading purposes.
|
||||||
for (auto &item : this->items())
|
auto items = this->GetAllPlugins();
|
||||||
|
for (auto item : items)
|
||||||
{
|
{
|
||||||
item.AddToSnapshotFromCurrentSettings(snapshot);
|
item->AddToSnapshotFromCurrentSettings(snapshot);
|
||||||
}
|
}
|
||||||
// a neccesary precondition: the previous pedalboard must have identical structure,
|
// a neccesary precondition: the previous pedalboard must have identical structure,
|
||||||
// so we can just
|
// so we can just
|
||||||
size_t index = 0;
|
// auto items = this->GetAllPlugins();
|
||||||
for (auto&item: previousPedalboard.items_)
|
|
||||||
{
|
// for (auto&item: previousPedalboard.items_)
|
||||||
item.AddResetsForMissingProperties(snapshot,&index);
|
// {
|
||||||
}
|
// item.AddResetsForMissingProperties(snapshot,&index);
|
||||||
|
// }
|
||||||
return snapshot;
|
return snapshot;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-1
@@ -28,6 +28,7 @@
|
|||||||
namespace pipedal {
|
namespace pipedal {
|
||||||
class SnapshotValue;
|
class SnapshotValue;
|
||||||
class Snapshot;
|
class Snapshot;
|
||||||
|
class PluginHost;
|
||||||
|
|
||||||
#define SPLIT_PEDALBOARD_ITEM_URI "uri://two-play/pipedal/pedalboard#Split"
|
#define SPLIT_PEDALBOARD_ITEM_URI "uri://two-play/pipedal/pedalboard#Split"
|
||||||
#define EMPTY_PEDALBOARD_ITEM_URI "uri://two-play/pipedal/pedalboard#Empty"
|
#define EMPTY_PEDALBOARD_ITEM_URI "uri://two-play/pipedal/pedalboard#Empty"
|
||||||
@@ -102,10 +103,13 @@ public:
|
|||||||
public:
|
public:
|
||||||
ControlValue*GetControlValue(const std::string&symbol);
|
ControlValue*GetControlValue(const std::string&symbol);
|
||||||
const ControlValue*GetControlValue(const std::string&symbol) const;
|
const ControlValue*GetControlValue(const std::string&symbol) const;
|
||||||
|
bool SetControlValue(const std::string&key, float value);
|
||||||
|
|
||||||
|
|
||||||
bool IsStructurallyIdentical(const PedalboardItem&other) const;
|
bool IsStructurallyIdentical(const PedalboardItem&other) const;
|
||||||
|
|
||||||
void ApplySnapshotValue(SnapshotValue*snapshotValue);
|
void ApplySnapshotValue(SnapshotValue*snapshotValue);
|
||||||
|
void ApplyDefaultValues(PluginHost&pluginHost);
|
||||||
bool hasLv2State() const {
|
bool hasLv2State() const {
|
||||||
return lv2State_.isValid_ != 0;
|
return lv2State_.isValid_ != 0;
|
||||||
}
|
}
|
||||||
@@ -203,7 +207,7 @@ public:
|
|||||||
std::vector<PedalboardItem*>GetAllPlugins();
|
std::vector<PedalboardItem*>GetAllPlugins();
|
||||||
|
|
||||||
bool HasItem(int64_t pedalItemid) const { return GetItem(pedalItemid) != nullptr; }
|
bool HasItem(int64_t pedalItemid) const { return GetItem(pedalItemid) != nullptr; }
|
||||||
bool ApplySnapshot(int64_t snapshotIndex);
|
bool ApplySnapshot(int64_t snapshotIndex, PluginHost &pluginHost);
|
||||||
|
|
||||||
GETTER_SETTER_REF(name)
|
GETTER_SETTER_REF(name)
|
||||||
GETTER_SETTER_VEC(items)
|
GETTER_SETTER_VEC(items)
|
||||||
|
|||||||
+16
-15
@@ -535,23 +535,17 @@ void PiPedalModel::SetPedalboard(int64_t clientId, Pedalboard &pedalboard)
|
|||||||
void PiPedalModel::SetSnapshot(int64_t selectedSnapshot)
|
void PiPedalModel::SetSnapshot(int64_t selectedSnapshot)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::recursive_mutex> lock(mutex);
|
std::lock_guard<std::recursive_mutex> lock(mutex);
|
||||||
if (this->pedalboard.ApplySnapshot(selectedSnapshot))
|
if (this->pedalboard.ApplySnapshot(selectedSnapshot, pluginHost))
|
||||||
{
|
{
|
||||||
this->pedalboard.SetCurrentSnapshotModified(false);
|
|
||||||
this->FireSnapshotModified(selectedSnapshot,false);
|
|
||||||
if (this->audioHost)
|
|
||||||
{
|
|
||||||
if (this->previousPedalboardLoaded && this->pedalboard.IsStructureIdentical(this->previousPedalboard))
|
|
||||||
{
|
|
||||||
this->audioHost->LoadSnapshot(*(this->pedalboard.snapshots()[selectedSnapshot]), this->pluginHost); // no longer own it.
|
|
||||||
} else {
|
|
||||||
LoadCurrentPedalboard();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
SetPresetChanged(-1, true, false);
|
|
||||||
this->pedalboard.selectedSnapshot(selectedSnapshot);
|
this->pedalboard.selectedSnapshot(selectedSnapshot);
|
||||||
FirePedalboardChanged(-1, false);
|
for (auto snapshot: this->pedalboard.snapshots())
|
||||||
|
{
|
||||||
|
if (snapshot)
|
||||||
|
{
|
||||||
|
snapshot->isModified_ = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FirePedalboardChanged(-1, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -567,6 +561,13 @@ void PiPedalModel::SetSnapshots(std::vector<std::shared_ptr<Snapshot>> &snapshot
|
|||||||
if (selectedSnapshot != -1)
|
if (selectedSnapshot != -1)
|
||||||
{
|
{
|
||||||
this->pedalboard.selectedSnapshot(selectedSnapshot);
|
this->pedalboard.selectedSnapshot(selectedSnapshot);
|
||||||
|
for (auto &snapshot: pedalboard.snapshots())
|
||||||
|
{
|
||||||
|
if (snapshot)
|
||||||
|
{
|
||||||
|
snapshot->isModified_ = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this->FirePedalboardChanged(-1, false); // notify clients (but don't change the running pedalboard, because it's still the same)
|
this->FirePedalboardChanged(-1, false); // notify clients (but don't change the running pedalboard, because it's still the same)
|
||||||
|
|||||||
@@ -182,6 +182,7 @@ SplitEffect::SplitEffect(
|
|||||||
|
|
||||||
Lv2PluginInfo::ptr puginInfo = g_splitterPluginInfo;
|
Lv2PluginInfo::ptr puginInfo = g_splitterPluginInfo;
|
||||||
|
|
||||||
|
defaultInputControlValues.resize(MAX_INPUT_CONTROL);
|
||||||
for (auto&port: puginInfo->ports())
|
for (auto&port: puginInfo->ports())
|
||||||
{
|
{
|
||||||
if (port->is_control_port() && port->is_input())
|
if (port->is_control_port() && port->is_input())
|
||||||
|
|||||||
@@ -358,7 +358,6 @@ namespace pipedal
|
|||||||
|
|
||||||
virtual void SetBypass(bool enabled)
|
virtual void SetBypass(bool enabled)
|
||||||
{
|
{
|
||||||
throw PiPedalArgumentException("Not implmented. Should not have been called.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual float GetOutputControlValue(int index) const {
|
virtual float GetOutputControlValue(int index) const {
|
||||||
|
|||||||
@@ -1,3 +1,21 @@
|
|||||||
|
Loading shields need to be of Modal type.
|
||||||
|
|
||||||
|
MOD fileTypes
|
||||||
|
|
||||||
|
- audioloop: Audio Loops, meant to be used for looper-style plugins
|
||||||
|
- audiorecording: Audio Recordings, triggered by plugins and stored in the unit
|
||||||
|
- audiosample: One-shot Audio Samples, meant to be used for sampler-style plugins
|
||||||
|
- audiotrack: Audio Tracks, meant to be used as full-performance/song or backtrack
|
||||||
|
- cabsim: Speaker Cabinets, meant as small IR audio files
|
||||||
|
- h2drumkit: Hydrogen Drumkits, must use h2drumkit file extension
|
||||||
|
- ir: Impulse Responses
|
||||||
|
- midiclip: MIDI Clips, to be used in sync with host tempo, must have mid or midi file extension
|
||||||
|
- midisong: MIDI Songs, meant to be used as full-performance/song or backtrack
|
||||||
|
- sf2: SF2 Instruments, must have sf2 or sf3 file extension
|
||||||
|
- sfz: SFZ Instruments, must have sfz file extension
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Main menu on Pixel 5 client.
|
Main menu on Pixel 5 client.
|
||||||
x1 bank menu (landscape pixel 5) should show current bank.
|
x1 bank menu (landscape pixel 5) should show current bank.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user