Merge branch 'main'

This commit is contained in:
Robin Davies
2022-07-01 21:22:28 -04:00
21 changed files with 348 additions and 108 deletions
-1
View File
@@ -4,7 +4,6 @@ project(pipedal
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 "v0.9.11-rc-2") set (DISPLAY_VERSION "v0.9.11-rc-2")
set (CMAKE_INSTALL_PREFIX "/usr/") set (CMAKE_INSTALL_PREFIX "/usr/")
+2 -2
View File
@@ -3,12 +3,12 @@ Depends: libstdc++6 (>= 9), libasound2 (>= 1.0.16), libc6 (>= 2.34), libgcc-s1 (
Description: IoT guitar effect for Raspberry Pi Description: IoT guitar effect for Raspberry Pi
IoT guitar effect pedal for Raspberry Pi, with phone-friendly web interface. IoT guitar effect pedal for Raspberry Pi, with phone-friendly web interface.
Homepage: https://github.com/rerdavies/pipedal Homepage: https://github.com/rerdavies/pipedal
Maintainer: Robin Davies<rerdavies@gmail.com Maintainer: Robin E. R. Davies<rerdavies@gmail.com>
Source: pipedal Source: pipedal
Package: pipedal Package: pipedal
Pre-Depends: hostapd;authbind Pre-Depends: hostapd;authbind
Priority: optional Priority: optional
Section: sound Section: sound
Version: 0.1.4 Version: 0.9.11
Installed-Size: 15147 Installed-Size: 15147
+1 -1
View File
@@ -1,2 +1,2 @@
#!/usr/bin/bash #!/usr/bin/bash
/usr/local/pipedalconfig --install /usr/bin/pipedalconfig --install
+1 -1
View File
@@ -1,2 +1,2 @@
#!/usr/bin/bash #!/usr/bin/bash
/usr/local/pipedalconfig --uninstall /usr/bin/pipedalconfig --uninstall
+11 -5
View File
@@ -4,7 +4,7 @@ Run the following commands to install build tools required by the PiPedal build.
# install CMake # install CMake
sudo apt update sudo apt update
sudo apt install cmake ninja-build sudo apt install -y cmake ninja-build
The PiPedal build process also requires version 12 or later of `node.js`. Type `node --version` to see if you have a version The PiPedal build process also requires version 12 or later of `node.js`. Type `node --version` to see if you have a version
of `node.js` installed already. Otherwise run the following commands as root to install the v14.x lts version of `node.js`: of `node.js` installed already. Otherwise run the following commands as root to install the v14.x lts version of `node.js`:
@@ -22,10 +22,10 @@ with
Run the following commands to install dependent libraries required by the PiPedal build. Run the following commands to install dependent libraries required by the PiPedal build.
sudo apt update sudo apt update
sudo apt install liblilv-dev libboost-dev jackd2 libjack-jackd2-dev libnl-3-dev libnl-genl-3-dev libsystemd-dev catch sudo apt install -y liblilv-dev libboost-dev jackd2 libjack-jackd2-dev libnl-3-dev libnl-genl-3-dev libsystemd-dev catch
sudo apt install libasound2-dev jackd2 uuid-dev sudo apt install -y libasound2-dev jackd2 uuid-dev
sudo apt install libwebsocketpp-dev authbind sudo apt install -y libwebsocketpp-dev authbind
sudo apt install libavahi-client-dev sudo apt install -y libavahi-client-dev
### Installing Sources ### Installing Sources
@@ -36,6 +36,12 @@ Clone the rerdavies/pipdal package from github. Use the source control tools fro
cd ~/src # or whereever you keep your source repositories. cd ~/src # or whereever you keep your source repositories.
git clone https://github.com/rerdavies/pipedal.git git clone https://github.com/rerdavies/pipedal.git
In the project root, run the following commands to initialze and update pipedal submodules
cd ~/src/pipedal
git submodule init
git submodule update
Run the following command to install and configure React dependencies. Run the following command to install and configure React dependencies.
cd ~/src/pipedal cd ~/src/pipedal
+2 -2
View File
@@ -231,9 +231,9 @@ GEM
jekyll-seo-tag (~> 2.1) jekyll-seo-tag (~> 2.1)
minitest (5.15.0) minitest (5.15.0)
multipart-post (2.1.1) multipart-post (2.1.1)
nokogiri (1.13.4-aarch64-linux) nokogiri (1.13.6-aarch64-linux)
racc (~> 1.4) racc (~> 1.4)
nokogiri (1.13.4-x86_64-linux) nokogiri (1.13.6-x86_64-linux)
racc (~> 1.4) racc (~> 1.4)
octokit (4.22.0) octokit (4.22.0)
faraday (>= 0.9) faraday (>= 0.9)
+3 -1
View File
@@ -11,8 +11,10 @@ Install the package by running
``` ```
sudo apt update sudo apt update
cd ~/Downloads cd ~/Downloads
sudo apt-get install ./pipedal_0.9.11_arm64.deb sudo dpkg --install pipedal_0.9.11_arm64.deb
``` ```
On Raspberry Pi OS, if you have a graphical desktop installed, you can also install package by double-clicking on the downloaded package in the File Manager.
After installing, follow the instructions in [Configuring PiPedal after Installation](Configuring.md). After installing, follow the instructions in [Configuring PiPedal after Installation](Configuring.md).
-------- --------
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24"><path d="M14 18.2 7.8 12 14 5.8 15.6 7.4 11 12 15.6 16.6Z"/></svg>

After

Width:  |  Height:  |  Size: 129 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24"><path d="M9.4 18.2 7.8 16.6 12.4 12 7.8 7.4 9.4 5.8 15.6 12Z"/></svg>

After

Width:  |  Height:  |  Size: 132 B

+1 -1
View File
@@ -1,5 +1,5 @@
{ {
"socket_server_port": 8080, "socket_server_port": 80,
"socket_server_address": "*", "socket_server_address": "*",
"debug": true, "debug": true,
"max_upload_size": 1048576, "max_upload_size": 1048576,
+89 -1
View File
@@ -63,6 +63,7 @@ export interface PluginPresetsChangedHandle {
export interface ZoomedControlInfo { export interface ZoomedControlInfo {
source: HTMLElement; source: HTMLElement;
name: string;
instanceId: number; instanceId: number;
uiControl: UiControl; uiControl: UiControl;
} }
@@ -432,6 +433,9 @@ export interface PiPedalModel {
getAlsaDevices(): Promise<AlsaDeviceInfo[]>; getAlsaDevices(): Promise<AlsaDeviceInfo[]>;
zoomUiControl(sourceElement: HTMLElement, instanceId: number, uiControl: UiControl): void; zoomUiControl(sourceElement: HTMLElement, instanceId: number, uiControl: UiControl): void;
onPreviousZoomedControl() : void;
onNextZoomedControl() : void;
clearZoomedControl(): void; clearZoomedControl(): void;
setFavorite(pluginUrl: string, isFavorite: boolean): void; setFavorite(pluginUrl: string, isFavorite: boolean): void;
@@ -2094,8 +2098,92 @@ class PiPedalModelImpl implements PiPedalModel {
} }
zoomUiControl(sourceElement: HTMLElement, instanceId: number, uiControl: UiControl): void { zoomUiControl(sourceElement: HTMLElement, instanceId: number, uiControl: UiControl): void {
this.zoomedUiControl.set({ source: sourceElement, instanceId: instanceId, uiControl: uiControl }); let name = uiControl.name;
if (uiControl.port_group !== "")
{
let pedalboard = this.pedalBoard.get();
if (pedalboard)
{
let plugin = pedalboard.getItem(instanceId);
let uiPlugin = this.getUiPlugin(plugin.uri);
if (uiPlugin)
{
for (let i = 0; i < uiPlugin.port_groups.length; ++i)
{
if (uiPlugin.port_groups[i].symbol === uiControl.port_group)
{
name = uiPlugin.port_groups[i].name + " / " + name;
break;
} }
}
}
}
}
this.zoomedUiControl.set({ source: sourceElement, name: name, instanceId: instanceId, uiControl: uiControl });
}
onPreviousZoomedControl() : void
{
let currentUiControl = this.zoomedUiControl.get();
if (!currentUiControl) return;
let currentSymbol = currentUiControl.uiControl.symbol;
let pedalboard = this.pedalBoard.get();
if (!pedalboard) return;
let pedalboardItem = pedalboard.getItem(currentUiControl.instanceId);
let uiPlugin = this.getUiPlugin(pedalboardItem.uri);
if (!uiPlugin) return;
let i = 0;
let ix = -1;
for (i = 0; i < uiPlugin.controls.length; ++i)
{
if (uiPlugin.controls[i].symbol === currentSymbol) {
ix = i;
break;
}
}
if (ix === -1) return;
++ix;
if (ix >= uiPlugin.controls.length) return;
this.zoomUiControl(currentUiControl.source,currentUiControl.instanceId,uiPlugin.controls[ix]);
}
onNextZoomedControl() : void
{
let currentUiControl = this.zoomedUiControl.get();
if (!currentUiControl) return;
let currentSymbol = currentUiControl.uiControl.symbol;
let pedalboard = this.pedalBoard.get();
if (!pedalboard) return;
let pedalboardItem = pedalboard.getItem(currentUiControl.instanceId);
let uiPlugin = this.getUiPlugin(pedalboardItem.uri);
if (!uiPlugin) return;
let i = 0;
let ix = -1;
for (i = 0; i < uiPlugin.controls.length; ++i)
{
if (uiPlugin.controls[i].symbol === currentSymbol) {
ix = i;
break;
}
}
if (ix === -1) return;
--ix;
if (ix < 0) return;
this.zoomUiControl(currentUiControl.source,currentUiControl.instanceId,uiPlugin.controls[ix]);
}
clearZoomedControl(): void { clearZoomedControl(): void {
this.zoomedUiControl.set(undefined); this.zoomedUiControl.set(undefined);
} }
+1 -1
View File
@@ -1,4 +1,4 @@
// Copyright (c) 2022 Robin Davies // Copyright (c) 2022 Robin Davies
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy of // Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in // this software and associated documentation files (the "Software"), to deal in
+153 -34
View File
@@ -17,22 +17,42 @@
// 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 React, {SyntheticEvent} from 'react'; import React, {ReactNode, SyntheticEvent } from 'react';
import MenuItem from '@mui/material/MenuItem';
import Select from '@mui/material/Select';
import Switch from '@mui/material/Switch';
import { UiControl, ScalePoint } from './Lv2Plugin';
import { Theme } from '@mui/material/styles'; import { Theme } from '@mui/material/styles';
import { WithStyles,withStyles } from '@mui/styles'; import { WithStyles, withStyles } from '@mui/styles';
import createStyles from '@mui/styles/createStyles'; import createStyles from '@mui/styles/createStyles';
import { ZoomedControlInfo } from './PiPedalModel'; import { ZoomedControlInfo } from './PiPedalModel';
import DialogEx from './DialogEx'; import DialogEx from './DialogEx';
import Typography from '@mui/material/Typography'; import Typography from '@mui/material/Typography';
import { PiPedalModelFactory,PiPedalModel } from './PiPedalModel'; import { PiPedalModelFactory, PiPedalModel } from './PiPedalModel';
import ZoomedDial from './ZoomedDial'; import ZoomedDial from './ZoomedDial';
import IconButton from '@mui/material/IconButton';
import NavigateBeforeIcon from '@mui/icons-material/NavigateBefore';
import NavigateNextIcon from '@mui/icons-material/NavigateNext';
const styles = (theme: Theme) => createStyles({ const styles = (theme: Theme) => createStyles({
switchTrack: {
height: '100%',
width: '100%',
borderRadius: 14 / 2,
zIndex: -1,
transition: theme.transitions.create(['opacity', 'background-color'], {
duration: theme.transitions.duration.shortest
}),
backgroundColor: theme.palette.secondary.main,
opacity: theme.palette.mode === 'light' ? 0.38 : 0.3
}
}); });
interface ZoomedUiControlProps extends WithStyles<typeof styles> { interface ZoomedUiControlProps extends WithStyles<typeof styles> {
theme: Theme;
dialogOpen: boolean; dialogOpen: boolean;
onDialogClose: () => void; onDialogClose: () => void;
onDialogClosed: () => void; onDialogClosed: () => void;
@@ -59,8 +79,7 @@ const ZoomedUiControl = withStyles(styles, { withTheme: true })(
model: PiPedalModel; model: PiPedalModel;
constructor(props: ZoomedUiControlProps) constructor(props: ZoomedUiControlProps) {
{
super(props); super(props);
this.model = PiPedalModelFactory.getInstance(); this.model = PiPedalModelFactory.getInstance();
this.state = { this.state = {
@@ -69,25 +88,45 @@ const ZoomedUiControl = withStyles(styles, { withTheme: true })(
} }
getCurrentValue(): number { getCurrentValue(): number {
if (!this.props.controlInfo) if (!this.props.controlInfo) {
{
return 0; return 0;
} else { } else {
let uiControl = this.props.controlInfo.uiControl; let uiControl = this.props.controlInfo.uiControl;
let instanceId = this.props.controlInfo.instanceId; let instanceId = this.props.controlInfo.instanceId;
if (instanceId === -1) return 0; if (instanceId === -1) return 0;
let pedalBoardItem = this.model.pedalBoard.get()?.getItem(instanceId); let pedalBoardItem = this.model.pedalBoard.get()?.getItem(instanceId);
let value: number = pedalBoardItem?.getControlValue(uiControl.symbol)??0; let value: number = pedalBoardItem?.getControlValue(uiControl.symbol) ?? 0;
return value; return value;
} }
} }
hasControlChanged(oldProps: ZoomedUiControlProps, newProps: ZoomedUiControlProps)
{
if (oldProps.controlInfo === null) onSelectChanged(val: string | number) {
{ let v = Number.parseFloat(val.toString());
this.setState({ value: v });
if (this.props.controlInfo) {
this.model.setPedalBoardControlValue(
this.props.controlInfo.instanceId,
this.props.controlInfo.uiControl.symbol,
v);
}
}
onCheckChanged(checked: boolean): void {
let v = checked ? 1: 0;
this.setState({ value: v });
if (this.props.controlInfo) {
this.model.setPedalBoardControlValue(
this.props.controlInfo.instanceId,
this.props.controlInfo.uiControl.symbol,
v);
}
}
hasControlChanged(oldProps: ZoomedUiControlProps, newProps: ZoomedUiControlProps) {
if (oldProps.controlInfo === null) {
return newProps.controlInfo !== null; return newProps.controlInfo !== null;
} else if (newProps.controlInfo === null) } else if (newProps.controlInfo === null) {
{
return oldProps.controlInfo !== null; return oldProps.controlInfo !== null;
} else { } else {
if (newProps.controlInfo?.instanceId !== oldProps.controlInfo?.instanceId) return true; if (newProps.controlInfo?.instanceId !== oldProps.controlInfo?.instanceId) return true;
@@ -97,14 +136,11 @@ const ZoomedUiControl = withStyles(styles, { withTheme: true })(
} }
componentDidUpdate(oldProps: ZoomedUiControlProps, oldState: ZoomedUiControlState) componentDidUpdate(oldProps: ZoomedUiControlProps, oldState: ZoomedUiControlState) {
{ if (this.hasControlChanged(oldProps, this.props)) {
if (this.hasControlChanged(oldProps,this.props))
{
let currentValue = this.getCurrentValue(); let currentValue = this.getCurrentValue();
if (this.state.value !== currentValue) if (this.state.value !== currentValue) {
{ this.setState({ value: this.getCurrentValue() });
this.setState({value: this.getCurrentValue()});
} }
} }
} }
@@ -115,33 +151,102 @@ const ZoomedUiControl = withStyles(styles, { withTheme: true })(
return false; return false;
} }
makeSelect(control: UiControl, value: number): ReactNode {
if (control.isOnOffSwitch()) {
// normal gray unchecked state.
return (
<Switch checked={value !== 0} color="secondary"
onChange={(event) => {
this.onCheckChanged(event.target.checked);
}}
/>
);
}
if (control.isAbToggle()) {
// unchecked color is not gray.
return (
<Switch checked={value !== 0} color="secondary"
onChange={(event) => {
this.onCheckChanged(event.target.checked);
}}
classes={{
track: this.props.classes.switchTrack
}}
style={{ color: this.props.theme.palette.secondary.main }}
/>
);
} else {
return (
<Select variant="standard"
value={control.clampSelectValue(value)}
onChange={(e)=> this.onSelectChanged(e.target.value)}
inputProps={{
name: control.name,
id: 'id' + control.symbol,
style: { fontSize: "1.0em" }
}}
style={{ marginLeft: 4, marginRight: 4, width: 140 }}
>
{control.scale_points.map((scale_point: ScalePoint) => (
<MenuItem key={scale_point.value} value={scale_point.value}>{scale_point.label}</MenuItem>
))}
</Select>
);
}
}
render() { render() {
let displayValue = this.props.controlInfo?.uiControl.formatDisplayValue(this.state.value)??""; if (!this.props.controlInfo) {
return false;
}
let uiControl = this.props.controlInfo.uiControl;
let displayValue = uiControl.formatDisplayValue(this.state.value) ?? "";
if (uiControl.isOnOffSwitch())
{
displayValue = this.state.value !== 0 ? "On": "Off";
} else if (uiControl.isSelect())
{
displayValue = "\u00A0";
}
return ( return (
<DialogEx tag="zoomedControlDlg" open={this.props.dialogOpen} <DialogEx tag="zoomedControlDlg" open={this.props.dialogOpen}
onClose={()=> { this.props.onDialogClose()}} onClose={() => { this.props.onDialogClose() }}
onAbort={()=> { this.props.onDialogClose()}} onAbort={() => { this.props.onDialogClose() }}
> >
<div style={{ width: 300, height: 300, background: "#FFF", <div style={{
width: 380, height: 300, background: "FFFF",
display: "flex", flexFlow: "row", alignItems: "center", alignContent: " center", justifyContent: "center"
}}>
<IconButton sx={{ height: "100%", width: 48, borderRadius: "0% 50% 50% 0%" }} onClick={
() => {
this.model.onNextZoomedControl();
}
} >
<NavigateBeforeIcon />
</IconButton>
<div style={{
width: 200, flexGrow: 1, height: 300, background: "#FFF",
display: "flex", flexFlow: "column", alignItems: "center", alignContent: "center", justifyContent: "center" display: "flex", flexFlow: "column", alignItems: "center", alignContent: "center", justifyContent: "center"
}} }}
onDrag={this.onDrag} onDrag={this.onDrag}
> >
<Typography <Typography
display="block" variant="h6" color="textPrimary" style={{textAlign: "center"}} display="block" variant="h6" color="textPrimary" style={{ textAlign: "center" }}
> >
{this.props.controlInfo?.uiControl.name??""} {this.props.controlInfo.name}
</Typography> </Typography>
{uiControl.isDial() ? (
<ZoomedDial size={200} controlInfo={this.props.controlInfo} <ZoomedDial size={200} controlInfo={this.props.controlInfo}
onPreviewValue={(v)=> { onPreviewValue={(v) => {
this.setState({value: v}); this.setState({ value: v });
}} }}
onSetValue={(v)=> { onSetValue={(v) => {
this.setState({value: v}); this.setState({ value: v });
if (this.props.controlInfo) if (this.props.controlInfo) {
{
this.model.setPedalBoardControlValue( this.model.setPedalBoardControlValue(
this.props.controlInfo.instanceId, this.props.controlInfo.instanceId,
this.props.controlInfo.uiControl.symbol, this.props.controlInfo.uiControl.symbol,
@@ -149,13 +254,27 @@ const ZoomedUiControl = withStyles(styles, { withTheme: true })(
} }
}} }}
/> />
) :
<div style={{height: 200, paddingTop: 80}}>
{this.makeSelect(uiControl,this.state.value)}
</div>
}
<Typography <Typography
display="block" variant="h6" color="textPrimary" style={{textAlign: "center"}} display="block" variant="h6" color="textPrimary" style={{ textAlign: "center" }}
> >
{displayValue} {displayValue}
</Typography> </Typography>
</div> </div>
<IconButton sx={{ height: "100%", width: 48, borderRadius: "50% 0% 0% 50%" }}
onClick={() => {
this.model.onPreviousZoomedControl();
}
}
>
<NavigateNextIcon />
</IconButton>
</div>
</DialogEx> </DialogEx>
); );
+4 -7
View File
@@ -64,7 +64,8 @@ bool AdminClient::WriteMessage(const char *message)
} }
catch (const std::exception &e) catch (const std::exception &e)
{ {
Lv2Log::error(SS("Failed to connect to PiPedal Admin service.")); // Socket permissions require membership in pipedal_d group.
Lv2Log::error(SS("Failed to connect to PiPedal Admin service. " << e.what()));
return false; return false;
} }
} }
@@ -168,7 +169,7 @@ void AdminClient::MonitorGovernor(const std::string &governor)
bool result = WriteMessage(cmd.str().c_str()); bool result = WriteMessage(cmd.str().c_str());
if (!result) if (!result)
{ // unexpected. Should throw exception on failure. { // unexpected. Should throw exception on failure.
throw PiPedalException("Operation failed."); Lv2Log::warning("Not monitoring CPU governor status.");
} }
} }
void AdminClient::UnmonitorGovernor() void AdminClient::UnmonitorGovernor()
@@ -180,9 +181,5 @@ void AdminClient::UnmonitorGovernor()
std::stringstream cmd; std::stringstream cmd;
cmd << "UnmonitorGovernor"; cmd << "UnmonitorGovernor";
cmd << '\n'; cmd << '\n';
bool result = WriteMessage(cmd.str().c_str()); bool ignored = WriteMessage(cmd.str().c_str());
if (!result)
{ // unexpected. Should throw exception on failure.
throw PiPedalException("Operation failed.");
}
} }
-8
View File
@@ -8,14 +8,6 @@ set (USE_PCH 1)
include(FindPkgConfig) include(FindPkgConfig)
# apt install libsdbus-c++-dev
# apt install libsdbus-c++-bin
find_package(sdbus-c++ REQUIRED)
# Can't get the pkg_check to work. # Can't get the pkg_check to work.
# pkg_check_modules(LIBNL3 "nl-genl-3") # pkg_check_modules(LIBNL3 "nl-genl-3")
+30 -11
View File
@@ -75,7 +75,7 @@ using namespace pipedal;
#define PIPEDAL_P2PD_SERVICE "pipedal_p2pd" #define PIPEDAL_P2PD_SERVICE "pipedal_p2pd"
#define JACK_SERVICE "jack" #define JACK_SERVICE "jack"
#define REMOVE_OLD_SERVICE 1 // Grandfathering: whether to remove the old shutdown service (now pipedaladmind) #define REMOVE_OLD_SERVICE 0 // Grandfathering: whether to remove the old shutdown service (now pipedaladmind)
#define OLD_SHUTDOWN_SERVICE "pipedalshutdownd" #define OLD_SHUTDOWN_SERVICE "pipedalshutdownd"
std::filesystem::path GetServiceFileName(const std::string &serviceName) std::filesystem::path GetServiceFileName(const std::string &serviceName)
@@ -112,11 +112,11 @@ void EnableService()
{ {
if (sysExec(SYSTEMCTL_BIN " enable " NATIVE_SERVICE ".service") != EXIT_SUCCESS) if (sysExec(SYSTEMCTL_BIN " enable " NATIVE_SERVICE ".service") != EXIT_SUCCESS)
{ {
cout << "Error: Failed to enable the " NATIVE_SERVICE " service."; cout << "Error: Failed to enable the " NATIVE_SERVICE " service.\n";
} }
if (sysExec(SYSTEMCTL_BIN " enable " ADMIN_SERVICE ".service") != EXIT_SUCCESS) if (sysExec(SYSTEMCTL_BIN " enable " ADMIN_SERVICE ".service") != EXIT_SUCCESS)
{ {
cout << "Error: Failed to enable the " ADMIN_SERVICE " service."; cout << "Error: Failed to enable the " ADMIN_SERVICE " service.\n";
} }
} }
void DisableService() void DisableService()
@@ -131,16 +131,16 @@ void DisableService()
#endif #endif
if (sysExec(SYSTEMCTL_BIN " disable " NATIVE_SERVICE ".service") != EXIT_SUCCESS) if (sysExec(SYSTEMCTL_BIN " disable " NATIVE_SERVICE ".service") != EXIT_SUCCESS)
{ {
cout << "Error: Failed to disable the " NATIVE_SERVICE " service."; cout << "Error: Failed to disable the " NATIVE_SERVICE " service.\n";
} }
if (sysExec(SYSTEMCTL_BIN " disable " ADMIN_SERVICE ".service") != EXIT_SUCCESS) if (sysExec(SYSTEMCTL_BIN " disable " ADMIN_SERVICE ".service") != EXIT_SUCCESS)
{ {
cout << "Error: Failed to disable the " ADMIN_SERVICE " service."; cout << "Error: Failed to disable the " ADMIN_SERVICE " service.\n";
} }
#if REMOVE_OLD_SERVICE #if REMOVE_OLD_SERVICE
if (sysExec(SYSTEMCTL_BIN " disable " OLD_SHUTDOWN_SERVICE ".service") != EXIT_SUCCESS) if (sysExec(SYSTEMCTL_BIN " disable " OLD_SHUTDOWN_SERVICE ".service") != EXIT_SUCCESS)
{ {
cout << "Error: Failed to disable the " OLD_SHUTDOWN_SERVICE " service."; cout << "Error: Failed to disable the " OLD_SHUTDOWN_SERVICE " service.\n";
} }
#endif #endif
} }
@@ -149,18 +149,18 @@ void StopService(bool excludeShutdownService = false)
{ {
if (sysExec(SYSTEMCTL_BIN " stop " NATIVE_SERVICE ".service") != EXIT_SUCCESS) if (sysExec(SYSTEMCTL_BIN " stop " NATIVE_SERVICE ".service") != EXIT_SUCCESS)
{ {
cout << "Error: Failed to stop the " NATIVE_SERVICE " service."; cout << "Error: Failed to stop the " NATIVE_SERVICE " service.\n";
} }
if (!excludeShutdownService) if (!excludeShutdownService)
{ {
if (sysExec(SYSTEMCTL_BIN " stop " ADMIN_SERVICE ".service") != EXIT_SUCCESS) if (sysExec(SYSTEMCTL_BIN " stop " ADMIN_SERVICE ".service") != EXIT_SUCCESS)
{ {
cout << "Error: Failed to stop the " ADMIN_SERVICE " service."; cout << "Error: Failed to stop the " ADMIN_SERVICE " service.\n";
} }
#if REMOVE_OLD_SERVICE #if REMOVE_OLD_SERVICE
if (sysExec(SYSTEMCTL_BIN " stop " OLD_SHUTDOWN_SERVICE ".service") != EXIT_SUCCESS) if (sysExec(SYSTEMCTL_BIN " stop " OLD_SHUTDOWN_SERVICE ".service") != EXIT_SUCCESS)
{ {
cout << "Error: Failed to stop the " OLD_SHUTDOWN_SERVICE " service."; cout << "Error: Failed to stop the " OLD_SHUTDOWN_SERVICE " service.\n";
} }
#endif #endif
} }
@@ -168,7 +168,7 @@ void StopService(bool excludeShutdownService = false)
if (sysExec(SYSTEMCTL_BIN " stop " JACK_SERVICE ".service") != EXIT_SUCCESS) if (sysExec(SYSTEMCTL_BIN " stop " JACK_SERVICE ".service") != EXIT_SUCCESS)
{ {
#if INSTALL_JACK_SERVICE #if INSTALL_JACK_SERVICE
throw PiPedalException("Failed to stop the " JACK_SERVICE " service."); cout << PiPedalException("Failed to stop the " JACK_SERVICE " service.");
#endif #endif
} }
#endif #endif
@@ -551,9 +551,24 @@ static void PrepareDeviceidFile()
{ {
DeviceIdFile deviceIdFile; DeviceIdFile deviceIdFile;
deviceIdFile.deviceName = "PiPedal-" + RandomChars(2); deviceIdFile.deviceName = "PiPedal";
deviceIdFile.uuid = MakeUuid(); deviceIdFile.uuid = MakeUuid();
deviceIdFile.Save(); deviceIdFile.Save();
} else {
DeviceIdFile deviceIdFile;
if (deviceIdFile.deviceName == "" || deviceIdFile.uuid == "")
{
if (deviceIdFile.deviceName == "")
{
deviceIdFile.deviceName = "PiPedal";
}
if (deviceIdFile.uuid == "")
{
deviceIdFile.uuid = MakeUuid();
}
deviceIdFile.Save();
}
} }
} }
@@ -563,6 +578,10 @@ void Install(const std::filesystem::path &programPrefix, const std::string endpo
{ {
throw PiPedalException("Failed to create audio service group."); throw PiPedalException("Failed to create audio service group.");
} }
if (sysExec(GROUPADD_BIN " -f " SERVICE_GROUP_NAME) != EXIT_SUCCESS)
{
throw PiPedalException("Failed to create pipedald service group.");
}
PrepareDeviceidFile(); PrepareDeviceidFile();
InstallJackService(); InstallJackService();
+5 -6
View File
@@ -39,16 +39,16 @@ const char DeviceIdFile::DEVICEID_FILE_NAME[] = "/etc/pipedal/config/device_uuid
void DeviceIdFile::Load() void DeviceIdFile::Load()
{ {
{
ifstream f; ifstream f;
f.open(DEVICEID_FILE_NAME); f.open(DEVICEID_FILE_NAME);
if (!f.is_open()) if (f.is_open())
{ {
throw invalid_argument("Can't open file " + std::string(DEVICEID_FILE_NAME));
}
std::getline(f, uuid); std::getline(f, uuid);
std::getline(f, deviceName); std::getline(f, deviceName);
}
}
} }
void DeviceIdFile::Save() void DeviceIdFile::Save()
{ {
@@ -67,10 +67,9 @@ void DeviceIdFile::Save()
{ {
throw logic_error("Group not found: pipedal_d"); throw logic_error("Group not found: pipedal_d");
} }
std::ignore = chown(path.c_str(),-1,group_->gr_gid); std::ignore = chown(path.c_str(), -1, group_->gr_gid);
std::ignore = chmod(path.c_str(), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH); std::ignore = chmod(path.c_str(), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
f << uuid << endl; f << uuid << endl;
f << deviceName << endl; f << deviceName << endl;
} }
+3 -1
View File
@@ -176,7 +176,9 @@ void JackConfiguration::JackInitialize()
AddPorts(client, &this->inputAudioPorts_, "system", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput); AddPorts(client, &this->inputAudioPorts_, "system", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput);
AddPorts(client, &this->outputAudioPorts_, "system", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput); AddPorts(client, &this->outputAudioPorts_, "system", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput);
isValid_ = true; AddPorts(client, &this->inputMidiPorts_, "system", JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput);
AddPorts(client, &this->outputMidiPorts_, "system", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput);
isValid_ = (this->inputAudioPorts_.size() > 0 && this->outputAudioPorts_.size() > 0);
this->errorStatus_ = ""; this->errorStatus_ = "";
jack_client_close(client); jack_client_close(client);
} }
+8
View File
@@ -704,7 +704,15 @@ void PiPedalModel::UpdateDnsSd()
DeviceIdFile deviceIdFile; DeviceIdFile deviceIdFile;
deviceIdFile.Load(); deviceIdFile.Load();
if (deviceIdFile.deviceName != "" && deviceIdFile.uuid != "")
{
avahiService.Announce(webPort,deviceIdFile.deviceName,deviceIdFile.uuid,"pipedal"); avahiService.Announce(webPort,deviceIdFile.deviceName,deviceIdFile.uuid,"pipedal");
} else {
// device_uuid file is written at install time. This warning is harmless if you're debugging.
// Without it, we can't pulblish the website via dnsDS.
// Run "pipedalconfig --install" to create the file.
Lv2Log::warning("Cant read device_uuid file. dnsSD announcement skipped.");
}
} }
void PiPedalModel::SetWifiDirectConfigSettings(const WifiDirectConfigSettings &wifiDirectConfigSettings) void PiPedalModel::SetWifiDirectConfigSettings(const WifiDirectConfigSettings &wifiDirectConfigSettings)
+2 -1
View File
@@ -488,7 +488,8 @@ void pipedal::SetWifiDirectConfig(const WifiDirectConfigSettings &settings)
dhcpcd.InsertLine(line++, "interface p2p-wlan0-0"); dhcpcd.InsertLine(line++, "interface p2p-wlan0-0");
dhcpcd.InsertLine(line++, " static ip_address=" P2P_INTERFACE_ADDR); dhcpcd.InsertLine(line++, " static ip_address=" P2P_INTERFACE_ADDR);
dhcpcd.InsertLine(line++, " domain_name_servers=" P2P_IP_ADDRESS); dhcpcd.InsertLine(line++, " nohook wpa_supplicant");
//dhcpcd.InsertLine(line++, " domain_name_servers=" P2P_IP_ADDRESS);
dhcpcd.Save(dhcpcdConfig); dhcpcd.Save(dhcpcdConfig);
} }
+8 -2
View File
@@ -425,12 +425,18 @@ public:
} }
std::string GetConfig(const std::string &fromAddress) std::string GetConfig(const std::string &fromAddress)
{ {
std::string linkLocalAddress = GetLinkLocalAddress(fromAddress); #define LINK_LOCAL_WEB_SOCKET 1
#if LINK_LOCAL_WEB_SOCKET
std::string webSocketAddress = GetLinkLocalAddress(fromAddress);
Lv2Log::info(SS("Web Socket Adddress: " << webSocketAddress << ":" << portNumber));
#else
std::string webSocketAddress = "*";
#endif
std::stringstream s; std::stringstream s;
s << "{ \"socket_server_port\": " << portNumber s << "{ \"socket_server_port\": " << portNumber
<< ", \"socket_server_address\": \"" << linkLocalAddress << "\", \"ui_plugins\": [ ], \"max_upload_size\": " << maxUploadSize << " }"; << ", \"socket_server_address\": \"" << webSocketAddress << "\", \"ui_plugins\": [ ], \"max_upload_size\": " << maxUploadSize << " }";
return s.str(); return s.str();
} }