WIP Sync
This commit is contained in:
@@ -1,23 +1,61 @@
|
||||
|
||||
import { Pedalboard, ControlValue } from "./Pedalboard.tsx";
|
||||
import JackServerSettings from "./JackServerSettings.tsx";
|
||||
import JackConfiguration from "./Jack.tsx";
|
||||
|
||||
|
||||
function isActiveChannel(channels: number[]): boolean {
|
||||
if (channels.length < 2) return false;
|
||||
return channels[1] >= 0 || channels[0] >= 0;
|
||||
}
|
||||
|
||||
function chName(ch: number): string {
|
||||
if (ch === -1) {
|
||||
return "None";
|
||||
}
|
||||
return "Ch " + (ch + 1);
|
||||
}
|
||||
function channelPairName(channels: number[], maxChannels: number): string {
|
||||
if (channels.length !== 2) {
|
||||
return "Invalid";
|
||||
}
|
||||
if (channels[0] === -1 && channels[1] === -1) {
|
||||
return "None";
|
||||
}
|
||||
|
||||
if (maxChannels === 2) {
|
||||
if (channels[0] === 0 && channels[1] === 1) {
|
||||
return "Stereo";
|
||||
}
|
||||
if (channels[0] === 0 && (channels[0] === channels[1] || channels[1] === -1)) {
|
||||
return "Left";
|
||||
}
|
||||
if (channels[1] === 1 && (channels[0] === channels[1])) {
|
||||
return "Right";
|
||||
}
|
||||
if (channels[0] === 1 && channels[1] === 0) {
|
||||
return "Right,Left";
|
||||
}
|
||||
}
|
||||
return chName(channels[0]) + "," + chName(channels[1]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
export default class ChannelRouterSettings {
|
||||
configured: boolean = false;
|
||||
channelRouterPresetId: number = -1;
|
||||
|
||||
mainInputChannels: number[] = [1,1];
|
||||
mainOutputChannels: number[] = [0,1];
|
||||
mainInputChannels: number[] = [1, 1];
|
||||
mainOutputChannels: number[] = [0, 1];
|
||||
mainInserts: Pedalboard = new Pedalboard();
|
||||
|
||||
auxInputChannels: number[] = [0,0];
|
||||
auxOutputChannels: number[] = [-1,-1];
|
||||
auxInputChannels: number[] = [0, 0];
|
||||
auxOutputChannels: number[] = [-1, -1];
|
||||
auxInserts: Pedalboard = new Pedalboard();
|
||||
|
||||
sendInputChannels: number[] = [-1,-1];
|
||||
sendOutputChannels: number[] = [-1,-1];
|
||||
sendInputChannels: number[] = [-1, -1];
|
||||
sendOutputChannels: number[] = [-1, -1];
|
||||
|
||||
controlValues: ControlValue[] = [];
|
||||
// Inserts...
|
||||
@@ -55,10 +93,89 @@ export default class ChannelRouterSettings {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
let newValue = new ControlValue(symbol,value);
|
||||
let newValue = new ControlValue(symbol, value);
|
||||
this.controlValues.push(newValue);
|
||||
this.controlValues = this.controlValues.slice(); // trigger observers.
|
||||
return true;
|
||||
}
|
||||
|
||||
getDescription(jackConfiguration: JackConfiguration): string {
|
||||
if (!this.configured) {
|
||||
return "Not configured";
|
||||
}
|
||||
if (!jackConfiguration.isValid)
|
||||
{
|
||||
return "Not configured"
|
||||
}
|
||||
if (!this.isValid(jackConfiguration)) {
|
||||
return "Invalid configuration";
|
||||
}
|
||||
let nInputs = jackConfiguration.inputAudioPorts.length;
|
||||
let nOutputs = jackConfiguration.outputAudioPorts.length;
|
||||
let description = channelPairName(this.mainInputChannels, nInputs) + " -> " +
|
||||
channelPairName(this.mainOutputChannels, nOutputs);
|
||||
if (isActiveChannel(this.auxInputChannels) && isActiveChannel(this.auxOutputChannels))
|
||||
{
|
||||
description += " " + "+ re-amp: " + channelPairName(this.auxInputChannels, nInputs) + " -> " +
|
||||
channelPairName(this.auxOutputChannels, nOutputs);
|
||||
}
|
||||
if (isActiveChannel(this.sendInputChannels) && isActiveChannel(this.sendOutputChannels)) {
|
||||
description += " " + "+ send: " +channelPairName(this.sendOutputChannels, nOutputs)
|
||||
+ " -> " + channelPairName(this.sendInputChannels, nInputs);
|
||||
}
|
||||
return description;
|
||||
}
|
||||
canEdit(jackConfiguration: JackConfiguration): boolean {
|
||||
return jackConfiguration.isValid;
|
||||
}
|
||||
|
||||
isValid(jackConfiguration: JackConfiguration): boolean {
|
||||
if (!this.configured) {
|
||||
return false;
|
||||
}
|
||||
let maxInputChannels = jackConfiguration.inputAudioPorts.length;
|
||||
let maxOutputChannels = jackConfiguration.outputAudioPorts.length;
|
||||
|
||||
let hasInput = false;
|
||||
let hasOutput = false;
|
||||
for (let ch of this.mainInputChannels) {
|
||||
if (ch >= 0) {
|
||||
hasInput = true;
|
||||
if (ch >= maxInputChannels) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!hasInput) {
|
||||
return false;
|
||||
}
|
||||
for (let ch of this.mainOutputChannels) {
|
||||
if (ch >= 0) {
|
||||
hasOutput = true;
|
||||
if (ch >= maxOutputChannels) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!hasOutput) {
|
||||
return false;
|
||||
}
|
||||
for (let ch of this.auxInputChannels) {
|
||||
if (ch >= maxInputChannels) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (let ch of this.auxOutputChannels) {
|
||||
if (ch >= maxOutputChannels) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (let ch of this.sendInputChannels) {
|
||||
if (ch >= maxInputChannels) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -42,6 +42,11 @@ import DialogEx from './DialogEx';
|
||||
|
||||
import { PiPedalModelFactory } from './PiPedalModel';
|
||||
|
||||
|
||||
let debugInputChannels: number | null = 2;
|
||||
let debugOutputChannels: number | null = 4;
|
||||
|
||||
|
||||
export interface ChannelRouterSettingsDialogProps {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
@@ -309,6 +314,12 @@ function ChannelRouterSettingsDialog(props: ChannelRouterSettingsDialogProps) {
|
||||
|
||||
let ChannelSelect = (routeType: RouteType, channelIndex: number, input: boolean, icon: boolean = true) => {
|
||||
let channelCount = input ? config.inputAudioPorts.length : config.outputAudioPorts.length;
|
||||
if (input && debugInputChannels != null) {
|
||||
channelCount = debugInputChannels;
|
||||
}
|
||||
if (!input && debugOutputChannels != null) {
|
||||
channelCount = debugOutputChannels;
|
||||
}
|
||||
|
||||
let value: number;
|
||||
|
||||
@@ -336,7 +347,7 @@ function ChannelRouterSettingsDialog(props: ChannelRouterSettingsDialogProps) {
|
||||
}
|
||||
onChange={(event) => {
|
||||
let newValue = event.target.value as number;
|
||||
let newSettings = Object.assign(new ChannelRouterSettings(), settings);
|
||||
let newSettings = new ChannelRouterSettings().deserialize(settings);
|
||||
switch (routeType) {
|
||||
case RouteType.Main:
|
||||
if (input) {
|
||||
@@ -385,7 +396,11 @@ function ChannelRouterSettingsDialog(props: ChannelRouterSettingsDialogProps) {
|
||||
}
|
||||
for (let preset of channelRouterPresets) {
|
||||
if (preset.id === presetId) {
|
||||
model.setChannelRouterSettings(preset.settings);
|
||||
let newPreset = Object.assign(new ChannelRouterSettings(), preset.settings);
|
||||
// mark the presets as inserts.
|
||||
newPreset.mainInserts.nextInstanceId = Pedalboard.MAIN_INSERT_INSTANCE_BASE;
|
||||
newPreset.auxInserts.nextInstanceId = Pedalboard.AUX_INSERT_INSTANCE_BASE;
|
||||
model.setChannelRouterSettings(newPreset);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -759,7 +774,7 @@ function ChannelRouterSettingsDialog(props: ChannelRouterSettingsDialogProps) {
|
||||
{ChannelSelect(RouteType.Send, 0, true, false)}
|
||||
</td>
|
||||
<td style={cellLeft}>
|
||||
{ChannelSelect(RouteType.Send, 1, false, false)}
|
||||
{ChannelSelect(RouteType.Send, 1, true, false)}
|
||||
</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
@@ -381,10 +381,10 @@ export class Pedalboard implements Deserializable<Pedalboard> {
|
||||
|
||||
static readonly START_CONTROL = -2; // synthetic PedalboardItem for input volume.
|
||||
static readonly END_CONTROL = -3; // synthetic PedalboardItem for output volume.
|
||||
static readonly MAIN_INSERT_START_CONTROL_ID = Pedalboard.MAIN_INSERT_INSTANCE_BASE + MAX_INSTANCE_ID -2;
|
||||
static readonly MAIN_INSERT_END_CONTROL_ID = Pedalboard.MAIN_INSERT_INSTANCE_BASE + MAX_INSTANCE_ID -3;
|
||||
static readonly AUX_INSERT_START_CONTROL_ID = Pedalboard.AUX_INSERT_INSTANCE_BASE + MAX_INSTANCE_ID -2;
|
||||
static readonly AUX_INSERT_END_CONTROL_ID = Pedalboard.AUX_INSERT_INSTANCE_BASE + MAX_INSTANCE_ID -3;
|
||||
static readonly MAIN_INSERT_START_CONTROL_ID = Pedalboard.MAIN_INSERT_INSTANCE_BASE + -2 + MAX_INSTANCE_ID;
|
||||
static readonly MAIN_INSERT_END_CONTROL_ID = Pedalboard.MAIN_INSERT_INSTANCE_BASE + -3 + MAX_INSTANCE_ID;
|
||||
static readonly AUX_INSERT_START_CONTROL_ID = Pedalboard.AUX_INSERT_INSTANCE_BASE + -2 + MAX_INSTANCE_ID
|
||||
static readonly AUX_INSERT_END_CONTROL_ID = Pedalboard.AUX_INSERT_INSTANCE_BASE + -3 + MAX_INSTANCE_ID;
|
||||
|
||||
|
||||
static readonly START_PEDALBOARD_ITEM_URI = "uri://two-play/pipedal/pedalboard#Start";
|
||||
|
||||
@@ -431,9 +431,9 @@ interface MonitorPortOutputBody {
|
||||
}
|
||||
|
||||
|
||||
interface ChannelSelectionChangedBody {
|
||||
interface ChannelRouterSettingsChangedBody {
|
||||
clientId: number;
|
||||
jackChannelSelection: JackChannelSelection;
|
||||
channelRouterSettings: ChannelRouterSettings;
|
||||
}
|
||||
interface RenamePresetBody {
|
||||
clientId: number;
|
||||
@@ -730,10 +730,11 @@ export class PiPedalModel //implements PiPedalModel
|
||||
} else if (message === "onShowStatusMonitorChanged") {
|
||||
let value = body as boolean;
|
||||
this.showStatusMonitor.set(value);
|
||||
} else if (message === "onChannelSelectionChanged") {
|
||||
let channelSelectionBody = body as ChannelSelectionChangedBody;
|
||||
let channelSelection = new JackChannelSelection().deserialize(channelSelectionBody.jackChannelSelection);
|
||||
this.jackSettings.set(channelSelection);
|
||||
} else if (message === "onChannelRouterSettingsChanged") {
|
||||
let channelRouterSettingChangedBody = body as ChannelRouterSettingsChangedBody;
|
||||
let channelRouterSettings = new ChannelRouterSettings().deserialize(
|
||||
channelRouterSettingChangedBody.channelRouterSettings);
|
||||
this.channelRouterSettings.set(channelRouterSettings);
|
||||
} else if (message === "onSnapshotModified") {
|
||||
let { snapshotIndex, modified } = (body as { snapshotIndex: number, modified: boolean });
|
||||
let snapshots = this.pedalboard.get().snapshots;
|
||||
|
||||
@@ -519,29 +519,10 @@ const SettingsDialog = withStyles(
|
||||
}
|
||||
|
||||
handleSelectChannelsDialogResult(channels: string[] | null): void {
|
||||
if (this.state.jackSettings === null) { return; }
|
||||
if (channels) {
|
||||
let newSelection = this.state.jackSettings.clone();
|
||||
if (this.state.showInputSelectDialog) {
|
||||
newSelection.inputAudioPorts = channels;
|
||||
} else {
|
||||
newSelection.outputAudioPorts = channels;
|
||||
}
|
||||
this.setState({
|
||||
jackSettings: newSelection,
|
||||
showInputSelectDialog: false,
|
||||
showOutputSelectDialog: false
|
||||
|
||||
});
|
||||
this.model.setJackSettings(newSelection);
|
||||
} else {
|
||||
this.setState({
|
||||
showInputSelectDialog: false,
|
||||
showOutputSelectDialog: false
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
this.setState({
|
||||
showInputSelectDialog: false,
|
||||
showOutputSelectDialog: false
|
||||
});
|
||||
}
|
||||
|
||||
midiSummary(): string {
|
||||
@@ -618,8 +599,10 @@ const SettingsDialog = withStyles(
|
||||
let disableShutdown = this.state.shuttingDown || this.state.restarting;
|
||||
|
||||
let canKeepScreenOn = this.model.canKeepScreenOn;
|
||||
let hasAudioConfig = isConfigValid && this.state.jackConfiguration.outputAudioPorts.length >= 1
|
||||
let hasAudioConfig = isConfigValid
|
||||
&& this.state.jackConfiguration.inputAudioPorts.length >= 1
|
||||
&& this.state.jackConfiguration.outputAudioPorts.length >= 1;
|
||||
|
||||
|
||||
return (
|
||||
<DialogEx tag="settings" fullScreen open={this.props.open}
|
||||
@@ -753,40 +736,43 @@ const SettingsDialog = withStyles(
|
||||
<SelectHoverBackground selected={false} showHover={true} />
|
||||
<div style={{ width: "100%" }}>
|
||||
<Typography display="block" variant="body2" noWrap>Channel Routing</Typography>
|
||||
<Typography display="block" variant="caption" color="textSecondary" noWrap>{
|
||||
this.state.jackSettings == null ? "" :
|
||||
this.state.jackSettings.getAudioInputDisplayValue(this.state.jackConfiguration)}</Typography>
|
||||
<Typography display="block" variant="caption"
|
||||
color={
|
||||
this.state.channelRouterSettings?.isValid(this.state.jackConfiguration) ?? false
|
||||
? "textSecondary": "error"} noWrap>{
|
||||
this.state.channelRouterSettings?.getDescription(this.state.jackConfiguration)??""}</Typography>
|
||||
</div>
|
||||
</ButtonBase>
|
||||
|
||||
|
||||
{/* Old Input and Output selection
|
||||
|
||||
<ButtonBase className={classes.setting} onClick={() => this.handleInputSelection()}
|
||||
disabled={!isConfigValid || this.state.jackConfiguration.outputAudioPorts.length <= 1}
|
||||
style={{ opacity: !isConfigValid ? 0.6 : 1.0 }}
|
||||
|
||||
<ButtonBase className={classes.setting} onClick={() => this.handleInputSelection()}
|
||||
disabled={!isConfigValid || this.state.jackConfiguration.outputAudioPorts.length <= 1}
|
||||
style={{ opacity: !isConfigValid ? 0.6 : 1.0 }}
|
||||
|
||||
>
|
||||
<SelectHoverBackground selected={false} showHover={true} />
|
||||
<div style={{ width: "100%" }}>
|
||||
<Typography display="block" variant="body2" noWrap>Input channels</Typography>
|
||||
<Typography display="block" variant="caption" color="textSecondary" noWrap>{
|
||||
this.state.jackSettings == null ? "" :
|
||||
this.state.jackSettings.getAudioInputDisplayValue(this.state.jackConfiguration)}</Typography>
|
||||
</div>
|
||||
</ButtonBase>
|
||||
<ButtonBase className={classes.setting} onClick={() => this.handleOutputSelection()}
|
||||
disabled={!isConfigValid || this.state.jackConfiguration.outputAudioPorts.length <= 1}
|
||||
style={{ opacity: !isConfigValid ? 0.6 : 1.0 }}
|
||||
>
|
||||
<SelectHoverBackground selected={false} showHover={true} />
|
||||
<div style={{ width: "100%" }}>
|
||||
<Typography display="block" variant="body2" noWrap>Output channels</Typography>
|
||||
<Typography display="block" variant="caption" color="textSecondary" noWrap>{
|
||||
this.state.jackSettings == null ? "" :
|
||||
this.state.jackSettings.getAudioOutputDisplayValue(this.state.jackConfiguration)}</Typography>
|
||||
</div>
|
||||
</ButtonBase>
|
||||
>
|
||||
<SelectHoverBackground selected={false} showHover={true} />
|
||||
<div style={{ width: "100%" }}>
|
||||
<Typography display="block" variant="body2" noWrap>Input channels</Typography>
|
||||
<Typography display="block" variant="caption" color="textSecondary" noWrap>{
|
||||
this.state.jackSettings == null ? "" :
|
||||
this.state.jackSettings.getAudioInputDisplayValue(this.state.jackConfiguration)}</Typography>
|
||||
</div>
|
||||
</ButtonBase>
|
||||
<ButtonBase className={classes.setting} onClick={() => this.handleOutputSelection()}
|
||||
disabled={!isConfigValid || this.state.jackConfiguration.outputAudioPorts.length <= 1}
|
||||
style={{ opacity: !isConfigValid ? 0.6 : 1.0 }}
|
||||
>
|
||||
<SelectHoverBackground selected={false} showHover={true} />
|
||||
<div style={{ width: "100%" }}>
|
||||
<Typography display="block" variant="body2" noWrap>Output channels</Typography>
|
||||
<Typography display="block" variant="caption" color="textSecondary" noWrap>{
|
||||
this.state.jackSettings == null ? "" :
|
||||
this.state.jackSettings.getAudioOutputDisplayValue(this.state.jackConfiguration)}</Typography>
|
||||
</div>
|
||||
</ButtonBase>
|
||||
*/}
|
||||
<Divider />
|
||||
<div >
|
||||
<Typography className={classes.sectionHead} display="block" variant="caption" color="secondary">MIDI</Typography>
|
||||
|
||||
Reference in New Issue
Block a user