+2
-2
@@ -1,10 +1,10 @@
|
||||
cmake_minimum_required(VERSION 3.16.0)
|
||||
project(pipedal
|
||||
VERSION 1.3.54
|
||||
VERSION 1.3.55
|
||||
DESCRIPTION "PiPedal Guitar Effect Pedal For Raspberry Pi"
|
||||
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 (CMAKE_INSTALL_PREFIX "/usr/")
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ static int ToOsSignalType(SignalHandler::SignalType signalType)
|
||||
case SignalHandler::Hangup: result = SIGHUP; break;
|
||||
|
||||
default:
|
||||
throw std::runtime_error("INvalid signal type");
|
||||
throw std::runtime_error("Invalid signal type");
|
||||
}
|
||||
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://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).
|
||||
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:
|
||||
|
||||
- [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)
|
||||
|
||||
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
|
||||
|
||||
```
|
||||
sudo apt update
|
||||
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.
|
||||
|
||||
|
||||
+11
-1
@@ -1,4 +1,14 @@
|
||||
# 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
|
||||
|
||||
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)
|
||||
|
||||
Bug fixes.
|
||||
Bug fixes:
|
||||
- Various crashes related to snapshots.
|
||||
|
||||
- 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:
|
||||
|
||||
- <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
|
||||
@@ -12,7 +12,7 @@ Install the package by running
|
||||
```
|
||||
sudo apt update
|
||||
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.
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
|
||||
|
||||
<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).
|
||||
|
||||
|
||||
#### 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
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
import { SyntheticEvent } from 'react';
|
||||
import { WithStyles } from '@mui/styles';
|
||||
|
||||
import './AppThemed.css';
|
||||
|
||||
//import {alpha} from '@mui/material/styles';
|
||||
import AppBar from '@mui/material/AppBar';
|
||||
import Modal from '@mui/material/Modal';
|
||||
import Toolbar from '@mui/material/Toolbar';
|
||||
import CssBaseline from '@mui/material/CssBaseline';
|
||||
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 List from '@mui/material/List';
|
||||
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 ListItemText from '@mui/material/ListItemText';
|
||||
import CircularProgress from '@mui/material/CircularProgress';
|
||||
@@ -92,6 +94,17 @@ const appStyles = (theme: Theme) => createStyles({
|
||||
listSubheader: {
|
||||
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: {
|
||||
display: "block",
|
||||
position: "absolute",
|
||||
@@ -100,7 +113,6 @@ const appStyles = (theme: Theme) => createStyles({
|
||||
top: "0px",
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
background: isDarkMode() ? "#222" : "#DDD",
|
||||
opacity: "0.95",
|
||||
justifyContent: "center",
|
||||
textAlign: "center",
|
||||
@@ -166,22 +178,22 @@ const appStyles = (theme: Theme) => createStyles({
|
||||
|
||||
},
|
||||
loadingBox: {
|
||||
position: "relative",
|
||||
display: "flex",
|
||||
flexFlow: "column nowrap",
|
||||
position: "absolute",
|
||||
top: "20%",
|
||||
left: 0, right: 0,
|
||||
color: isDarkMode() ? theme.palette.text.secondary : "#888",
|
||||
// border: "3px solid #888",
|
||||
borderRadius: "12px",
|
||||
padding: "12px",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
textAlign: "center",
|
||||
opacity: 0.8,
|
||||
zIndex: 2010
|
||||
|
||||
},
|
||||
loadingBoxItem: {
|
||||
justifyContent: "center",
|
||||
display: "flex", flexFlow: "row nowrap",
|
||||
alignItems: "center",
|
||||
textAlign: "center",
|
||||
zIndex: 2010
|
||||
|
||||
},
|
||||
|
||||
@@ -247,9 +259,8 @@ function setFullScreen(value: boolean) {
|
||||
|
||||
if (docEl.requestFullscren) // the latest offical api.
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
window.document.documentElement.requestFullscreen({navigationUI: "show"});
|
||||
if (value) {
|
||||
window.document.documentElement.requestFullscreen({ navigationUI: "show" });
|
||||
} else {
|
||||
window.document.exitFullscreen();
|
||||
}
|
||||
@@ -267,10 +278,10 @@ function setFullScreen(value: boolean) {
|
||||
}
|
||||
|
||||
|
||||
function preventDefault(e: SyntheticEvent): void {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
}
|
||||
// function preventDefault(e: SyntheticEvent): void {
|
||||
// e.stopPropagation();
|
||||
// e.preventDefault();
|
||||
// }
|
||||
|
||||
type AppState = {
|
||||
zoomedControlInfo: ZoomedControlInfo | undefined;
|
||||
@@ -403,7 +414,8 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
||||
return false;
|
||||
}
|
||||
|
||||
onOpenBank(bankId: number) {
|
||||
handleSpecificBank(bankId: number) {
|
||||
|
||||
this.model_.openBank(bankId)
|
||||
.catch((error) => this.model_.showAlert(error.toString()));
|
||||
|
||||
@@ -491,17 +503,15 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
||||
|
||||
}
|
||||
handleDrawerSelectBank() {
|
||||
|
||||
this.setState({
|
||||
isDrawerOpen: false,
|
||||
bankDialogOpen: true,
|
||||
editBankDialogOpen: false
|
||||
});
|
||||
|
||||
}
|
||||
handleDrawerDonationClick() {
|
||||
this.setState({
|
||||
isDrawerOpen: false,
|
||||
});
|
||||
this.hideDrawer(false);
|
||||
if (this.model_.isAndroidHosted()) {
|
||||
this.model_.showAndroidDonationActivity();
|
||||
} else {
|
||||
@@ -514,14 +524,12 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
||||
|
||||
handleDrawerAboutClick() {
|
||||
this.setState({
|
||||
isDrawerOpen: false,
|
||||
aboutDialogOpen: true
|
||||
});
|
||||
|
||||
}
|
||||
handleDrawerRenameBank() {
|
||||
this.setState({
|
||||
isDrawerOpen: false,
|
||||
renameBankDialogOpen: true,
|
||||
saveBankAsDialogOpen: false
|
||||
});
|
||||
@@ -529,7 +537,6 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
||||
}
|
||||
handleDrawerSaveBankAs() {
|
||||
this.setState({
|
||||
isDrawerOpen: false,
|
||||
renameBankDialogOpen: false,
|
||||
saveBankAsDialogOpen: true
|
||||
});
|
||||
@@ -657,6 +664,8 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
||||
let bankEntries = Math.floor((height - K) / ENTRY_HEIGHT);
|
||||
if (bankEntries < 1) bankEntries = 1;
|
||||
if (bankEntries > 7) bankEntries = 7;
|
||||
if (bankEntries === 2) bankEntries = 1;
|
||||
|
||||
this.setState({ bankDisplayItems: bankEntries });
|
||||
|
||||
}
|
||||
@@ -686,27 +695,33 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
||||
}
|
||||
|
||||
shortBankList(banks: BankIndex): BankIndexEntry[] {
|
||||
let n = this.state.bankDisplayItems;
|
||||
let nDisplayEntries = this.state.bankDisplayItems;
|
||||
let entries = banks.entries;
|
||||
if (entries.length < n + 1) { // +1 for the .... entry.
|
||||
return entries;
|
||||
}
|
||||
let nListEntries = entries.length;
|
||||
|
||||
let result: BankIndexEntry[] = [];
|
||||
let selectedIndex = -1;
|
||||
for (let i = 0; i < entries.length; ++i) {
|
||||
if (entries[i].instanceId === banks.selectedBank) {
|
||||
selectedIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (n > entries.length) n = entries.length;
|
||||
if (selectedIndex > n) {
|
||||
for (let i = 0; i < n - 1; ++i) {
|
||||
|
||||
if (nListEntries <= nDisplayEntries) {
|
||||
for (let i = 0; i < nListEntries; ++i) {
|
||||
result.push(entries[i]);
|
||||
}
|
||||
result.push(entries[selectedIndex]);
|
||||
} 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]);
|
||||
}
|
||||
}
|
||||
@@ -747,7 +762,7 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
||||
<div style={{
|
||||
colorScheme: isDarkMode() ? "dark" : "light", // affects scrollbar color
|
||||
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"
|
||||
}}
|
||||
onContextMenu={(e) => {
|
||||
@@ -831,11 +846,11 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
||||
</div>
|
||||
)}
|
||||
<TemporaryDrawer position='left' title="PiPedal"
|
||||
is_open={this.state.isDrawerOpen} onClose={() => { this.hideDrawer(); }} >
|
||||
is_open={this.state.isDrawerOpen} onClose={() => { this.hideDrawer(false); }} >
|
||||
|
||||
<List>
|
||||
<ListItem button key='PerformanceView'
|
||||
onClick={(ev) => {
|
||||
<ListItemButton key='PerformanceView'
|
||||
onClick={(ev: any) => {
|
||||
ev.stopPropagation();
|
||||
this.hideDrawer(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 }} />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary='Performance View' />
|
||||
</ListItem>
|
||||
</ListItemButton>
|
||||
</List>
|
||||
<Divider />
|
||||
<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) => {
|
||||
return (
|
||||
<ListItem button key={'bank' + bank.instanceId} selected={bank.instanceId === this.state.banks.selectedBank}
|
||||
onClick={() => this.onOpenBank(bank.instanceId)}
|
||||
<ListItemButton key={'bank' + bank.instanceId} selected={bank.instanceId === this.state.banks.selectedBank}
|
||||
onClick={(ev: any) => {
|
||||
ev.stopPropagation();
|
||||
this.hideDrawer(false);
|
||||
this.handleSpecificBank(bank.instanceId);
|
||||
}}
|
||||
>
|
||||
|
||||
<ListItemText primary={bank.name} />
|
||||
</ListItem>
|
||||
</ListItemButton>
|
||||
|
||||
);
|
||||
})
|
||||
}
|
||||
{
|
||||
showBankSelectDialog && (
|
||||
<ListItem button key={'bankDOTDOTDOT'} selected={false}
|
||||
onClick={(ev) => {
|
||||
<ListItemButton key={'bankDOTDOTDOT'} selected={false}
|
||||
onClick={(ev: any) => {
|
||||
ev.stopPropagation();
|
||||
this.hideDrawer(true);
|
||||
this.handleDrawerSelectBank();
|
||||
@@ -877,7 +896,7 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
||||
>
|
||||
|
||||
<ListItemText primary={"..."} />
|
||||
</ListItem>
|
||||
</ListItemButton>
|
||||
|
||||
|
||||
)
|
||||
@@ -885,8 +904,8 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
||||
</List>
|
||||
<Divider />
|
||||
<List>
|
||||
<ListItem button key='RenameBank'
|
||||
onClick={(ev) => {
|
||||
<ListItemButton key='RenameBank'
|
||||
onClick={(ev: any) => {
|
||||
ev.stopPropagation();
|
||||
this.hideDrawer(true);
|
||||
this.handleDrawerRenameBank()
|
||||
@@ -895,9 +914,9 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
||||
<RenameOutlineIcon color='inherit' className={classes.menuIcon} />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary='Rename bank' />
|
||||
</ListItem>
|
||||
<ListItem button key='SaveBank'
|
||||
onClick={(ev) => {
|
||||
</ListItemButton>
|
||||
<ListItemButton key='SaveBank'
|
||||
onClick={(ev: any) => {
|
||||
ev.stopPropagation();
|
||||
this.hideDrawer(true);
|
||||
this.handleDrawerSaveBankAs();
|
||||
@@ -906,9 +925,9 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
||||
<SaveBankAsIcon color="inherit" className={classes.menuIcon} />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary='Save as new bank' />
|
||||
</ListItem>
|
||||
<ListItem button key='EditBanks'
|
||||
onClick={(ev) => {
|
||||
</ListItemButton>
|
||||
<ListItemButton key='EditBanks'
|
||||
onClick={(ev: any) => {
|
||||
ev.stopPropagation();
|
||||
this.hideDrawer(true);
|
||||
this.handleDrawerManageBanks();
|
||||
@@ -917,12 +936,12 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
||||
<EditBanksIcon color="inherit" className={classes.menuIcon} />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary='Manage banks...' />
|
||||
</ListItem>
|
||||
</ListItemButton>
|
||||
</List>
|
||||
<Divider />
|
||||
<List>
|
||||
<ListItem button key='Settings'
|
||||
onClick={(ev) => {
|
||||
<ListItemButton key='Settings'
|
||||
onClick={(ev: any) => {
|
||||
ev.stopPropagation();
|
||||
this.hideDrawer(true);
|
||||
this.handleDrawerSettingsClick()
|
||||
@@ -931,9 +950,9 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
||||
<SettingsIcon color="inherit" className={classes.menuIcon} />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary='Settings' />
|
||||
</ListItem>
|
||||
<ListItem button key='About'
|
||||
onClick={(ev) => {
|
||||
</ListItemButton>
|
||||
<ListItemButton key='About'
|
||||
onClick={(ev: any) => {
|
||||
ev.stopPropagation();
|
||||
this.hideDrawer(true);
|
||||
this.handleDrawerAboutClick();
|
||||
@@ -942,18 +961,17 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
||||
<HelpOutlineIcon color="inherit" className={classes.menuIcon} />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary='About' />
|
||||
</ListItem>
|
||||
<ListItem button key='Donations'
|
||||
onClick={(ev) => {
|
||||
</ListItemButton>
|
||||
<ListItemButton key='Donations'
|
||||
onClick={(ev: any) => {
|
||||
ev.stopPropagation();
|
||||
this.hideDrawer(true);
|
||||
this.handleDrawerDonationClick();
|
||||
}}>
|
||||
<ListItemIcon >
|
||||
<VolunteerActivismIcon className={classes.menuIcon} color="inherit" />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary='Donations' />
|
||||
</ListItem>
|
||||
</ListItemButton>
|
||||
</List>
|
||||
|
||||
</TemporaryDrawer>
|
||||
@@ -1040,67 +1058,62 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
||||
</DialogEx>
|
||||
|
||||
|
||||
<div className={classes.errorContent} style={{ zIndex: 1200, display: this.state.displayState === State.Error ? "flex" : "none" }}
|
||||
onMouseDown={preventDefault} onKeyDown={preventDefault}
|
||||
<Modal open={this.state.displayState === State.Error}
|
||||
aria-label="fatal-error"
|
||||
aria-describedby="aria-error-text"
|
||||
>
|
||||
<div className={classes.errorContentMask} />
|
||||
<div style={{ flex: "2 2 3px", height: 20 }} > </div>
|
||||
<div className={classes.errorMessageBox} style={{ position: "relative" }} >
|
||||
<div style={{ fontSize: "30px", position: "absolute", left: 0, top: 3, color: "#A00" }}>
|
||||
<ErrorOutlineIcon color="inherit" fontSize="inherit" style={{ float: "left", marginRight: "12px" }} />
|
||||
</div>
|
||||
<div style={{ marginLeft: 40, marginTop: 3 }}>
|
||||
<p className={classes.errorText}>
|
||||
Error: {this.state.errorMessage}
|
||||
</p>
|
||||
</div>
|
||||
<div style={{ paddingTop: 50, paddingLeft: 36, textAlign: "left" }}>
|
||||
<Button variant='contained' color="primary"
|
||||
onClick={() => this.handleReload()} >
|
||||
Reload
|
||||
</Button>
|
||||
<div style={{
|
||||
display: "flex", flexFlow: "column nowrap",
|
||||
position: "absolute", top: 0, left: 0, right: 0, bottom: 0
|
||||
}}
|
||||
>
|
||||
<div className={classes.loadingMask} />
|
||||
<div style={{ flex: "2 2 3px", height: 20 }} > </div>
|
||||
<div className={classes.errorMessageBox} style={{ position: "relative" }} >
|
||||
<div style={{ fontSize: "30px", position: "absolute", left: 0, top: 3, color: "#A00" }}>
|
||||
<ErrorOutlineIcon color="inherit" fontSize="inherit" style={{ float: "left", marginRight: "12px" }} />
|
||||
</div>
|
||||
<div style={{ marginLeft: 40, marginTop: 3 }}>
|
||||
<p className={classes.errorText} id="aria-error-text">
|
||||
Error: {this.state.errorMessage}
|
||||
</p>
|
||||
</div>
|
||||
<div style={{ paddingTop: 50, paddingLeft: 36, textAlign: "left" }}>
|
||||
<Button variant='contained' color="primary"
|
||||
onClick={() => this.handleReload()} >
|
||||
Reload
|
||||
</Button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{ flex: "5 5 auto", height: 20 }} > </div>
|
||||
</div>
|
||||
|
||||
<div style={{ flex: "5 5 auto", height: 20 }} > </div>
|
||||
|
||||
</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>
|
||||
</Modal >
|
||||
{/* Reloading mask */}
|
||||
<div className={classes.errorContent} style={{
|
||||
zIndex: 1201,
|
||||
display: (
|
||||
wantsReloadingScreen(this.state.displayState)
|
||||
? "block" : "none"
|
||||
)
|
||||
}}
|
||||
< Modal
|
||||
open={wantsReloadingScreen(this.state.displayState) || this.state.displayState === State.Loading}
|
||||
aria-label="loading"
|
||||
aria-describedby="reloading-modal-description"
|
||||
>
|
||||
<div className={classes.errorContentMask} />
|
||||
|
||||
<div className={classes.loadingBox}>
|
||||
<div className={classes.loadingBoxItem}>
|
||||
<CircularProgress color="inherit" className={classes.loadingBoxItem} />
|
||||
<div style={{display: "flex",flexFlow: "column nowrap", alignItems: "center"}}>
|
||||
<div className={classes.loadingMask} />
|
||||
<div className={classes.loadingBox}>
|
||||
<div 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>
|
||||
<Typography display="block" noWrap variant="body2" className={classes.progressText}>
|
||||
{this.getReloadingMessage()}
|
||||
</Typography>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</Modal >
|
||||
</div >
|
||||
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -206,6 +206,7 @@ export class PedalboardItem implements Deserializable<PedalboardItem> {
|
||||
|
||||
export class SnapshotValue {
|
||||
deserialize(input: any): SnapshotValue {
|
||||
this.isEnabled = input.isEnabled;
|
||||
this.instanceId = input.instanceId;
|
||||
this.controlValues = ControlValue.deserializeArray(input.controlValues);
|
||||
this.lv2State = input.lv2state;
|
||||
|
||||
+5
-1
@@ -135,7 +135,7 @@ namespace pipedal
|
||||
{
|
||||
auto maxInputControl = effect->GetMaxInputControl();
|
||||
inputControlValues.resize(maxInputControl);
|
||||
|
||||
this->enabled = true;
|
||||
for (uint64_t i = 0; i < maxInputControl; ++i)
|
||||
{
|
||||
bool isInputControl = effect->IsInputControl(i);
|
||||
@@ -150,6 +150,7 @@ namespace pipedal
|
||||
}
|
||||
if (snapshotValue)
|
||||
{
|
||||
this->enabled = snapshotValue->isEnabled_;
|
||||
for (auto &controlValue : snapshotValue->controlValues_)
|
||||
{
|
||||
auto index = effect->GetControlIndex(controlValue.key());
|
||||
@@ -202,6 +203,8 @@ namespace pipedal
|
||||
}
|
||||
void ApplyValues(IEffect *effect)
|
||||
{
|
||||
|
||||
effect->SetBypass(this->enabled);
|
||||
if (effect != pEffect)
|
||||
{
|
||||
throw std::runtime_error("Wrong effect");
|
||||
@@ -226,6 +229,7 @@ namespace pipedal
|
||||
private:
|
||||
IEffect *pEffect;
|
||||
Lv2PluginState lv2State;
|
||||
bool enabled;
|
||||
std::vector<InputControlEntry> inputControlValues;
|
||||
std::vector<PathPatchProperty> pathPatchProperties;
|
||||
};
|
||||
|
||||
@@ -482,8 +482,8 @@ void AvahiService::Wait()
|
||||
{
|
||||
default:
|
||||
case ServiceState::Unitialized:
|
||||
throw std::runtime_error("Invalid state");
|
||||
|
||||
done = true;
|
||||
break;
|
||||
case ServiceState::Initializing:
|
||||
case ServiceState::Settling:
|
||||
case ServiceState::Requested:
|
||||
@@ -503,6 +503,8 @@ void AvahiService::Wait()
|
||||
if (clock::now() > waitTime)
|
||||
{
|
||||
Lv2Log::error("DNS/SD announcement timed out.");
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
||||
|
||||
+71
-59
@@ -155,6 +155,49 @@ void DisableService()
|
||||
#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()
|
||||
{
|
||||
silentSysExec(SS(SYSTEMCTL_BIN << " restart avahi-daemon.service").c_str());
|
||||
@@ -169,41 +212,10 @@ static void AvahiInstall()
|
||||
SystemConfigFile avahi(avahiConfig);
|
||||
|
||||
bool changed = avahi.RemoveUndoableActions();
|
||||
int line = avahi.GetLineThatStartsWith("use-ipv6=yes");
|
||||
if (line != -1)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
changed |= disableAvahiConfigLine(avahi, "[server]", "use-ipv6=");
|
||||
changed |= disableAvahiConfigLine(avahi, "[publish]", "publish-aaaa-on-ipv4=");
|
||||
|
||||
if (changed)
|
||||
{
|
||||
avahi.Save();
|
||||
@@ -914,7 +926,7 @@ void Install(const fs::path &programPrefix, const std::string endpointAddress)
|
||||
try
|
||||
{
|
||||
// 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();
|
||||
|
||||
@@ -995,7 +1007,6 @@ void Install(const fs::path &programPrefix, const std::string endpointAddress)
|
||||
// add to netdev group
|
||||
sysExec(USERMOD_BIN " -a -G " NETDEV_GROUP_NAME " " SERVICE_ACCOUNT_NAME);
|
||||
|
||||
|
||||
// create and configure /var directory.
|
||||
|
||||
fs::path varDirectory("/var/pipedal");
|
||||
@@ -1211,11 +1222,11 @@ static void PrintHelp()
|
||||
<< "\n\n"
|
||||
<< "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."
|
||||
<< "\n\n"
|
||||
<< "\n\n"
|
||||
<< "--home-network <wifi-ssid>\n"
|
||||
<< AddIndent(4) << "Hotspot is disabled if the specificed Wi-Fi network is detected.\n"
|
||||
<< AddIndent(-4)
|
||||
<< "--no-ethernet\n"
|
||||
<< "--no-ethernet\n"
|
||||
<< AddIndent(4) << "Hotspot is disabled if an ethernet network is connected.\n"
|
||||
<< AddIndent(-4)
|
||||
<< "--no-wifi\n"
|
||||
@@ -1336,9 +1347,9 @@ int main(int argc, char **argv)
|
||||
parser.AddOption("--port", &portOption);
|
||||
parser.AddOption("--enable-hotspot", &enable_hotspot);
|
||||
parser.AddOption("--disable-hotspot", &disable_hotspot);
|
||||
parser.AddOption("--home-network",&homeNetwork);
|
||||
parser.AddOption("--no-ethernet",&noEthernet);
|
||||
parser.AddOption("--no-wifi",&noWifi);
|
||||
parser.AddOption("--home-network", &homeNetwork);
|
||||
parser.AddOption("--no-ethernet", &noEthernet);
|
||||
parser.AddOption("--no-wifi", &noWifi);
|
||||
try
|
||||
{
|
||||
parser.Parse(argc, (const char **)argv);
|
||||
@@ -1367,9 +1378,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
int hotspotOptionCount =
|
||||
(homeNetwork.length() != 0 ? 1: 0)
|
||||
+ noEthernet
|
||||
+ noWifi;
|
||||
(homeNetwork.length() != 0 ? 1 : 0) + noEthernet + noWifi;
|
||||
|
||||
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.");
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hotspotOptionCount > 0)
|
||||
{
|
||||
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)
|
||||
{
|
||||
try {
|
||||
try
|
||||
{
|
||||
fs::path prefix;
|
||||
if (prefixOption.length() != 0)
|
||||
{
|
||||
@@ -1465,8 +1477,8 @@ int main(int argc, char **argv)
|
||||
}
|
||||
Install(prefix, portOption);
|
||||
FileSystemSync();
|
||||
|
||||
} catch (const std::exception&e)
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
cout << "ERROR: " << e.what() << endl;
|
||||
FileSystemSync();
|
||||
@@ -1475,10 +1487,12 @@ int main(int argc, char **argv)
|
||||
}
|
||||
else if (uninstall)
|
||||
{
|
||||
try {
|
||||
try
|
||||
{
|
||||
Uninstall();
|
||||
FileSystemSync();
|
||||
} catch (const std::exception &e)
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
cout << "ERROR: " << e.what() << endl;
|
||||
FileSystemSync();
|
||||
@@ -1489,7 +1503,6 @@ int main(int argc, char **argv)
|
||||
{
|
||||
RequireNetworkManager();
|
||||
StopService();
|
||||
|
||||
}
|
||||
else if (start)
|
||||
{
|
||||
@@ -1506,14 +1519,12 @@ int main(int argc, char **argv)
|
||||
RequireNetworkManager();
|
||||
EnableService();
|
||||
FileSystemSync();
|
||||
|
||||
}
|
||||
else if (disable)
|
||||
{
|
||||
RequireNetworkManager();
|
||||
DisableService();
|
||||
FileSystemSync();
|
||||
|
||||
}
|
||||
else if (enable_p2p)
|
||||
{
|
||||
@@ -1541,8 +1552,7 @@ int main(int argc, char **argv)
|
||||
settings.Load();
|
||||
settings.enable_ = false;
|
||||
SetWifiDirectConfig(settings);
|
||||
|
||||
|
||||
|
||||
RestartService(true);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -1557,15 +1567,17 @@ int main(int argc, char **argv)
|
||||
if (homeNetwork.length() != 0)
|
||||
{
|
||||
startMode = HotspotAutoStartMode::NotAtHome;
|
||||
} else if (noEthernet)
|
||||
}
|
||||
else if (noEthernet)
|
||||
{
|
||||
startMode = HotspotAutoStartMode::NoEthernetConnection;
|
||||
} else if (noWifi)
|
||||
}
|
||||
else if (noWifi)
|
||||
{
|
||||
startMode = HotspotAutoStartMode::NoRememberedWifiConections;
|
||||
}
|
||||
|
||||
settings.ParseArguments(argv,startMode,homeNetwork);
|
||||
settings.ParseArguments(argv, startMode, homeNetwork);
|
||||
|
||||
if (settings.hasPassword_)
|
||||
{
|
||||
|
||||
+4
-1
@@ -293,7 +293,10 @@ namespace pipedal
|
||||
|
||||
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)
|
||||
|
||||
+87
-32
@@ -20,6 +20,9 @@
|
||||
#include "pch.h"
|
||||
#include "Pedalboard.hpp"
|
||||
#include "AtomConverter.hpp"
|
||||
#include "PluginHost.hpp"
|
||||
#include "AtomConverter.hpp"
|
||||
#include "SplitEffect.hpp"
|
||||
|
||||
|
||||
using namespace pipedal;
|
||||
@@ -87,6 +90,19 @@ ControlValue* PedalboardItem::GetControlValue(const std::string&symbol)
|
||||
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
|
||||
{
|
||||
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);
|
||||
if (!item) return false;
|
||||
ControlValue*controlValue = item->GetControlValue(symbol);
|
||||
if (controlValue == nullptr) return false;
|
||||
if (controlValue->value() != value)
|
||||
{
|
||||
controlValue->value(value);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return item->SetControlValue(symbol,value);
|
||||
}
|
||||
|
||||
|
||||
@@ -190,12 +199,12 @@ bool IsPedalboardSplitItem(const PedalboardItem*self, const std::vector<Pedalboa
|
||||
return self->uri() == SPLIT_PEDALBOARD_ITEM_URI;
|
||||
}
|
||||
|
||||
bool Pedalboard::ApplySnapshot(int64_t snapshotIndex)
|
||||
bool Pedalboard::ApplySnapshot(int64_t snapshotIndex, PluginHost&pluginHost)
|
||||
{
|
||||
if (snapshotIndex < 0 ||
|
||||
snapshotIndex >= this->snapshots_.size() ||
|
||||
this->snapshots_[snapshotIndex] == nullptr ||
|
||||
this->selectedSnapshot() == snapshotIndex)
|
||||
this->snapshots_[snapshotIndex] == nullptr
|
||||
)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -210,15 +219,47 @@ bool Pedalboard::ApplySnapshot(int64_t snapshotIndex)
|
||||
auto plugins = this->GetAllPlugins();
|
||||
for (PedalboardItem *pedalboardItem: plugins)
|
||||
{
|
||||
SnapshotValue*snapshotValue = indexedValues[pedalboardItem->instanceId()];
|
||||
if (snapshotValue)
|
||||
if (!pedalboardItem->isEmpty())
|
||||
{
|
||||
pedalboardItem->ApplySnapshotValue(snapshotValue);
|
||||
SnapshotValue*snapshotValue = indexedValues[pedalboardItem->instanceId()];
|
||||
if (snapshotValue)
|
||||
{
|
||||
pedalboardItem->ApplySnapshotValue(snapshotValue);
|
||||
} else {
|
||||
pedalboardItem->ApplyDefaultValues(pluginHost);
|
||||
}
|
||||
}
|
||||
}
|
||||
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)
|
||||
{
|
||||
std::map<std::string,float> cumulativeValues;
|
||||
@@ -240,6 +281,16 @@ void PedalboardItem::ApplySnapshotValue(SnapshotValue*snapshotValue)
|
||||
this->lv2State(snapshotValue->lv2State_);
|
||||
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_);
|
||||
|
||||
}
|
||||
@@ -278,17 +329,19 @@ bool PedalboardItem::IsStructurallyIdentical(const PedalboardItem&other) const
|
||||
}
|
||||
if (this->isSplit()) // so is the other by virtue of idential uris.
|
||||
{
|
||||
auto myValue = this->GetControlValue("splitType");
|
||||
auto otherValue = other.GetControlValue("splitType");
|
||||
if (myValue == nullptr || otherValue == nullptr) // actually an error.
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// split type changes potentially trigger buffer allocation changes,
|
||||
// so different split types are not structurally identical.
|
||||
if (myValue->value() != otherValue->value()) {
|
||||
return false;
|
||||
}
|
||||
// provisionally, it seems ok to change the split type.
|
||||
// auto myValue = this->GetControlValue("splitType");
|
||||
// auto otherValue = other.GetControlValue("splitType");
|
||||
// if (myValue == nullptr || otherValue == nullptr) // actually an error.
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// // split type changes potentially trigger buffer allocation changes,
|
||||
// // so different split types are not structurally identical.
|
||||
// if (myValue->value() != otherValue->value()) {
|
||||
// return false;
|
||||
// }
|
||||
if (topChain().size() != other.topChain().size())
|
||||
{
|
||||
return false;
|
||||
@@ -407,17 +460,19 @@ Snapshot Pedalboard::MakeSnapshotFromCurrentSettings(const Pedalboard &previousP
|
||||
{
|
||||
Snapshot snapshot;
|
||||
// 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,
|
||||
// so we can just
|
||||
size_t index = 0;
|
||||
for (auto&item: previousPedalboard.items_)
|
||||
{
|
||||
item.AddResetsForMissingProperties(snapshot,&index);
|
||||
}
|
||||
// auto items = this->GetAllPlugins();
|
||||
|
||||
// for (auto&item: previousPedalboard.items_)
|
||||
// {
|
||||
// item.AddResetsForMissingProperties(snapshot,&index);
|
||||
// }
|
||||
return snapshot;
|
||||
|
||||
}
|
||||
|
||||
+5
-1
@@ -28,6 +28,7 @@
|
||||
namespace pipedal {
|
||||
class SnapshotValue;
|
||||
class Snapshot;
|
||||
class PluginHost;
|
||||
|
||||
#define SPLIT_PEDALBOARD_ITEM_URI "uri://two-play/pipedal/pedalboard#Split"
|
||||
#define EMPTY_PEDALBOARD_ITEM_URI "uri://two-play/pipedal/pedalboard#Empty"
|
||||
@@ -102,10 +103,13 @@ public:
|
||||
public:
|
||||
ControlValue*GetControlValue(const std::string&symbol);
|
||||
const ControlValue*GetControlValue(const std::string&symbol) const;
|
||||
bool SetControlValue(const std::string&key, float value);
|
||||
|
||||
|
||||
bool IsStructurallyIdentical(const PedalboardItem&other) const;
|
||||
|
||||
void ApplySnapshotValue(SnapshotValue*snapshotValue);
|
||||
void ApplyDefaultValues(PluginHost&pluginHost);
|
||||
bool hasLv2State() const {
|
||||
return lv2State_.isValid_ != 0;
|
||||
}
|
||||
@@ -203,7 +207,7 @@ public:
|
||||
std::vector<PedalboardItem*>GetAllPlugins();
|
||||
|
||||
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_VEC(items)
|
||||
|
||||
+16
-15
@@ -535,23 +535,17 @@ void PiPedalModel::SetPedalboard(int64_t clientId, Pedalboard &pedalboard)
|
||||
void PiPedalModel::SetSnapshot(int64_t selectedSnapshot)
|
||||
{
|
||||
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);
|
||||
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)
|
||||
{
|
||||
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)
|
||||
|
||||
@@ -182,6 +182,7 @@ SplitEffect::SplitEffect(
|
||||
|
||||
Lv2PluginInfo::ptr puginInfo = g_splitterPluginInfo;
|
||||
|
||||
defaultInputControlValues.resize(MAX_INPUT_CONTROL);
|
||||
for (auto&port: puginInfo->ports())
|
||||
{
|
||||
if (port->is_control_port() && port->is_input())
|
||||
|
||||
@@ -358,7 +358,6 @@ namespace pipedal
|
||||
|
||||
virtual void SetBypass(bool enabled)
|
||||
{
|
||||
throw PiPedalArgumentException("Not implmented. Should not have been called.");
|
||||
}
|
||||
|
||||
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.
|
||||
x1 bank menu (landscape pixel 5) should show current bank.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user