Initial VST3 Support (disabled)

Disabled until Steinberg licensing compliance  can be sorted out.
This commit is contained in:
Robin Davies
2022-08-15 18:14:49 -04:00
parent 351d1542e1
commit 553ae2a3f7
56 changed files with 4840 additions and 637 deletions
+18 -2
View File
@@ -228,6 +228,7 @@ export const LoadPluginDialog =
let gridWidth = width - this.margin_reserve;
let columns = Math.floor((gridWidth) / this.nominal_column_width);
if (columns < 1) columns = 1;
if (columns > 3) columns = 3;
return columns;
}
@@ -388,6 +389,14 @@ export const LoadPluginDialog =
// let selectedUri = this.state.selected_uri;
}
vst3_indicator(uiPlugin? : UiPlugin)
{
if (uiPlugin?.is_vst3)
{
return (<img alt="vst" src="/img/vst.svg" style={{marginLeft: 8,height: 22, opacity: 0.6,position: "relative",top: -1}} />)
}
return null;
}
stereo_indicator(uiPlugin?: UiPlugin): string {
if (!uiPlugin) return "";
if (uiPlugin.audio_inputs === 2 || uiPlugin.audio_outputs === 2) {
@@ -436,7 +445,13 @@ export const LoadPluginDialog =
for (let i = 0; i < plugins.length; ++i) {
let plugin = plugins[i];
if (filterType === PluginType.Plugin || rootClass.is_type_of(filterType, plugin.plugin_type)) {
let score = searchFilter.score(plugin.name, plugin.plugin_display_type, plugin.author_name);
let score:number = 0;
if (plugin.is_vst3)
{
score = searchFilter.score(plugin.name, plugin.plugin_display_type, plugin.author_name,"vst3");
} else {
score = searchFilter.score(plugin.name, plugin.plugin_display_type, plugin.author_name);
}
if (score !== 0) {
if (this.state.favoritesList[plugin.uri]) {
@@ -668,8 +683,9 @@ export const LoadPluginDialog =
<div style={{ display: "flex", justifyContent: "start", alignItems: "center", flex: "1 1 auto", height: "100%", overflow: "hidden" }} >
<PluginInfoDialog plugin_uri={this.state.selected_uri ?? ""} />
<Typography display='block' variant='body2' color="textPrimary" noWrap >
{this.info_string(selectedPlugin)}
{this.info_string(selectedPlugin)}
</Typography>
{this.vst3_indicator(selectedPlugin)}
<div style={{
color: isFavorite ? "#F80" : "#CCC", display: (this.state.selected_uri !== "" ? "block" : "none"),
position: "relative", top: -2
+26 -2
View File
@@ -45,6 +45,8 @@ export class Port implements Deserializable<Port> {
this.supports_time_position = input.supports_time_position;
this.port_group = input.port_group;
this.comment = input.comment;
this.is_bypass = input.is_bypass;
this.is_program_controller = input.is_program_controller;
return this;
}
@@ -75,12 +77,17 @@ export class Port implements Deserializable<Port> {
supports_time_position: boolean = false;
port_group: string = "";
comment: string = "";
is_bypass: boolean = false;
is_program_controller: boolean = false;
}
export class PortGroup {
deserialize(input: any): PortGroup {
this.symbol = input.symbol;
this.name = input.name;
this.parent_group = input.parent_group;
this.program_list_id = input.program_list_id ?? -1;
return this;
}
static deserialize_array(input: any) : PortGroup[] {
@@ -94,6 +101,8 @@ export class PortGroup {
symbol: string = "";
name: string = "";
parent_group: string = "";
program_list_id: number = -1;
};
export class Lv2Plugin implements Deserializable<Lv2Plugin> {
@@ -223,10 +232,19 @@ export class UiControl implements Deserializable<UiControl> {
this.scale_points = ScalePoint.deserialize_array(input.scale_points);
this.port_group = input.port_group;
this.units = input.units as Units;
this.comment = input.comment;
this.comment = input.comment ?? "";
this.is_bypass = input.is_bypass ? true: false;
this.is_program_controller = input.is_program_controller? true: false;
this.custom_units = input.custom_units ?? "";
this.controlType = ControlType.Dial;
if (this.is_bypass)
{
this.not_on_gui = true;
}
if (this.enumeration_property && this.scale_points.length === 2)
{
@@ -234,7 +252,7 @@ export class UiControl implements Deserializable<UiControl> {
} else {
if (this.min_value === 0 && this.max_value === 1)
{
if (this.toggled_property || this.integer_property)
if (this.toggled_property || this.integer_property || this.range_steps === 2)
{
this.controlType = ControlType.OnOffSwitch;
}
@@ -276,6 +294,10 @@ export class UiControl implements Deserializable<UiControl> {
port_group: string = "";
units: Units = Units.none;
comment: string = "";
is_bypass: boolean = true;
is_program_controller: boolean = true;
custom_units: string = "";
// Return the value of the closest scale_point.
clampSelectValue(value: number): number{
@@ -452,6 +474,7 @@ export class UiPlugin implements Deserializable<UiPlugin> {
this.description = input.description;
this.controls = UiControl.deserialize_array(input.controls);
this.port_groups = PortGroup.deserialize_array(input.port_groups);
this.is_vst3 = input.is_vst3;
return this;
}
@@ -501,5 +524,6 @@ export class UiPlugin implements Deserializable<UiPlugin> {
description: string = "";
controls: UiControl[] = [];
port_groups: PortGroup[] = [];
is_vst3 : boolean = false;
}
+2
View File
@@ -67,6 +67,7 @@ export class PedalBoardItem implements Deserializable<PedalBoardItem> {
this.midiBindings = MidiBinding.deserialize_array(input.midiBindings);
this.controlValues = ControlValue.deserializeArray(input.controlValues);
this.vstState = input.vstState ?? "";
return this;
}
deserialize(input: any): PedalBoardItem {
@@ -183,6 +184,7 @@ export class PedalBoardItem implements Deserializable<PedalBoardItem> {
pluginName?: string;
controlValues: ControlValue[] = ControlValue.EmptyArray;
midiBindings: MidiBinding[] = [];
vstState: string = "";
};
+115 -97
View File
@@ -62,6 +62,12 @@ const EMPTY_ICON_URL = "img/fx_empty.svg";
const ERROR_ICON_URL = "img/fx_error.svg";
const TERMINAL_ICON_URL = "img/fx_terminal.svg";
function CalculateConnection(numberOfInputs: number, numberOfOutputs: number)
{
let result = Math.min(numberOfInputs, numberOfOutputs);
if (result > 2) result = 2;
return result;
}
const pedalBoardStyles = (theme: Theme) => createStyles({
scrollContainer: {
@@ -210,10 +216,9 @@ class PedalLayout {
bounds: Rect = new Rect();
inputs: number = 0;
outputs: number = 0;
stereoInput: boolean = false;
stereoOutput: boolean = false;
numberOfInputs: number = 2;
numberOfOutputs: number = 2;
pedalItem?: PedalBoardItem;
// Split Layout only.
@@ -227,8 +232,8 @@ class PedalLayout {
let t: PedalLayout = new PedalLayout();
t.uri = START_PEDALBOARD_ITEM_URI;
t.iconUrl = TERMINAL_ICON_URL;
t.inputs = 0;
t.outputs = 1;
t.numberOfInputs = 0;
t.numberOfOutputs = 2;
return t;
}
static End(): PedalLayout {
@@ -236,8 +241,8 @@ class PedalLayout {
t.pluginType = PluginType.UtilityPlugin;
t.uri = END_PEDALBOARD_ITEM_URI;
t.iconUrl = TERMINAL_ICON_URL;
t.inputs = 2;
t.outputs = 0;
t.numberOfInputs = 2;
t.numberOfOutputs = 0;
return t;
}
constructor(model?: PiPedalModel, pedalItem?: PedalBoardItem) {
@@ -256,27 +261,27 @@ class PedalLayout {
this.topChildren = makeChain(model, splitter.topChain);
this.bottomChildren = makeChain(model, splitter.bottomChain);
this.inputs = 2;
this.outputs = 2;
this.numberOfInputs = 2;
this.numberOfOutputs = 2;
} else if (pedalItem.isEmpty()) {
this.pluginType = PluginType.UtilityPlugin;
this.iconUrl = EMPTY_ICON_URL;
this.inputs = 2;
this.outputs = 2;
this.numberOfInputs = 2;
this.numberOfOutputs = 2;
} else if (pedalItem.uri === START_PEDALBOARD_ITEM_URI) {
this.pluginType = PluginType.UtilityPlugin;
this.iconUrl = TERMINAL_ICON_URL;
this.inputs = 0;
this.outputs = PiPedalModelFactory.getInstance().jackSettings.get().inputAudioPorts.length;
this.numberOfInputs = 0;
this.numberOfOutputs = PiPedalModelFactory.getInstance().jackSettings.get().inputAudioPorts.length;
} else if (pedalItem.uri === END_PEDALBOARD_ITEM_URI) {
this.pluginType = PluginType.UtilityPlugin;
this.iconUrl = TERMINAL_ICON_URL;
this.inputs = PiPedalModelFactory.getInstance().jackSettings.get().outputAudioPorts.length;
this.outputs = 0;
this.numberOfInputs = PiPedalModelFactory.getInstance().jackSettings.get().outputAudioPorts.length;
this.numberOfOutputs = 0;
}
else {
let uiPlugin = model.getUiPlugin(pedalItem.uri);
@@ -284,15 +289,15 @@ class PedalLayout {
this.pluginType = uiPlugin.plugin_type;
this.iconUrl = SelectIcon(uiPlugin.plugin_type,uiPlugin.uri);
this.name = uiPlugin.name;
this.inputs = uiPlugin.audio_inputs;
this.outputs = uiPlugin.audio_outputs;
this.numberOfInputs = Math.max(uiPlugin.audio_inputs,2);
this.numberOfOutputs = Math.max(uiPlugin.audio_outputs,2);
} else {
// default to empty plugin.
this.pluginType = PluginType.UtilityPlugin;
this.name = pedalItem.pluginName??"#error";
this.iconUrl = ERROR_ICON_URL;
this.inputs = 2;
this.outputs = 2;
this.numberOfInputs = 2;
this.numberOfOutputs = 2;
}
}
}
@@ -677,18 +682,18 @@ const PedalBoardView =
// let classes = this.props.classes;
let x_ = item.bounds.x + CELL_WIDTH / 2;
let y_ = item.bounds.y + CELL_HEIGHT / 2;
let isStereo = item.stereoOutput;
let numberOfOutputs = item.numberOfOutputs;
let color = enabled ? ENABLED_CONNECTOR_COLOR : DISABLED_CONNECTOR_COLOR;
let svgPath = new SvgPathBuilder().moveTo(x_, y_).lineTo(x_ + CELL_WIDTH, y_).toString();
if (isStereo) {
if (numberOfOutputs === 2) {
output.push((
<path d={svgPath} stroke={color} strokeWidth={SVG_STEREO_STROKE_WIDTH} />
));
output.push((
<path d={svgPath} stroke="white" strokeWidth={SVG_STROKE_WIDTH} />
));
} else {
} else if (numberOfOutputs === 1) {
output.push((
<path d={svgPath} stroke={color} strokeWidth={SVG_STROKE_WIDTH} />
));
@@ -712,18 +717,18 @@ const PedalBoardView =
let topStartPath = new SvgPathBuilder().moveTo(x_, y_).lineTo(x_, yTop).lineTo(x_ + CELL_WIDTH, yTop).toString();
let bottomStartPath = new SvgPathBuilder().moveTo(x_, y_).lineTo(x_, yBottom).lineTo(x_ + CELL_WIDTH, yBottom).toString();
if (item.stereoInput && item.topChildren[0].stereoInput) {
if (item.numberOfInputs === 2 && item.topChildren[0].numberOfInputs === 2) {
output.push((<path d={topStartPath} stroke={topColor} strokeWidth={SVG_STEREO_STROKE_WIDTH} />));
output.push((<path d={topStartPath} stroke="white" strokeWidth={SVG_STROKE_WIDTH} />));
} else {
} else if (item.numberOfInputs !== 0 && item.topChildren[0].numberOfInputs !== 0) {
output.push((<path d={topStartPath} stroke={topColor} strokeWidth={SVG_STROKE_WIDTH} />));
}
if (item.stereoInput && item.bottomChildren[0].stereoInput) {
if (item.numberOfInputs === 2 && item.bottomChildren[0].numberOfInputs === 2) {
output.push((<path d={bottomStartPath} stroke={bottomColor} strokeWidth={SVG_STEREO_STROKE_WIDTH} />));
output.push((<path d={bottomStartPath} stroke="white" strokeWidth={SVG_STROKE_WIDTH} />));
} else {
} else if (item.numberOfInputs !== 0 && item.bottomChildren[0].numberOfInputs !== 0) {
output.push((<path d={bottomStartPath} stroke={bottomColor} strokeWidth={SVG_STROKE_WIDTH} />));
}
@@ -741,6 +746,8 @@ const PedalBoardView =
let firstPathStereo: boolean;
let secondPathStereo: boolean;
let firstPathAbsent: boolean;
let secondPathAbsent: boolean;
let firstPathEnabled: boolean;
let secondPathEnabled: boolean;
let xTee: number;
@@ -753,11 +760,13 @@ const PedalBoardView =
// Third case: L/R stereo output, when both outputs are mono, requires a third stroke.
let thirdPath: string | null = null; // for L/R stereo output (which can be stereo even if both outputs are mono)
let hasThirdPath = item.stereoOutput && (!lastTop.stereoOutput) && (!lastBottom.stereoOutput);
let hasThirdPath = item.numberOfOutputs === 2 && (lastTop.numberOfOutputs !== 2) && (lastBottom.numberOfOutputs !== 2);
if (hasThirdPath) {
firstPathStereo = false;
secondPathStereo = false;
firstPathAbsent = lastTop.numberOfOutputs === 0 || item.numberOfOutputs === 0;
secondPathAbsent = lastBottom.numberOfOutputs === 0 || item.numberOfOutputs === 0;
xTee = xTee0 - monoAdjustment;
firstPath = new SvgPathBuilder().moveTo(xBottom, yBottom).lineTo(xTee, yBottom).lineTo(xTee, y_).toString();
@@ -767,10 +776,13 @@ const PedalBoardView =
thirdPath= new SvgPathBuilder().moveTo(xTee0,y_).lineTo(xEnd,y_).toString();
firstPathEnabled = bottomEnabled;
secondPathEnabled = topEnabled;
} else if (bottomPathFirst || (topEnabled && lastTop.stereoOutput)) {
} else if (bottomPathFirst || (topEnabled && lastTop.numberOfOutputs === 2)) {
// draw the bottom path first.
firstPathStereo = item.stereoOutput && lastBottom.stereoOutput;
secondPathStereo = item.stereoOutput && lastTop.stereoOutput;
firstPathStereo = item.numberOfOutputs === 2 && lastBottom.numberOfOutputs === 2;
secondPathStereo = item.numberOfOutputs === 2 && lastTop.numberOfOutputs === 2;
firstPathAbsent = item.numberOfOutputs === 0 || lastBottom.numberOfOutputs === 0;
secondPathAbsent = item.numberOfOutputs === 0 || lastTop.numberOfOutputs === 0;
xTee = firstPathStereo ? xTee0 : xTee0 - monoAdjustment;
firstPath = new SvgPathBuilder().moveTo(xBottom, yBottom).lineTo(xTee, yBottom).lineTo(xTee, y_).toString();
xTee = secondPathStereo ? xTee0 : xTee0 - monoAdjustment;
@@ -780,8 +792,10 @@ const PedalBoardView =
secondPathEnabled = topEnabled;
} else {
// draw the top path first.
firstPathStereo = item.stereoOutput && lastTop.stereoOutput;
secondPathStereo = item.stereoOutput && lastBottom.stereoOutput;
firstPathStereo = item.numberOfOutputs === 2 && lastTop.numberOfOutputs === 2;
secondPathStereo = item.numberOfOutputs === 2 && lastBottom.numberOfOutputs === 2;
firstPathAbsent = item.numberOfOutputs === 0 || lastTop.numberOfOutputs === 0;
secondPathAbsent = item.numberOfOutputs === 0 || lastBottom.numberOfOutputs === 0;
xTee = firstPathStereo ? xTee0 : xTee0 - monoAdjustment;
firstPath = new SvgPathBuilder().moveTo(xTop, yTop).lineTo(xTee, yTop).lineTo(xTee, y_).toString();
@@ -804,7 +818,7 @@ const PedalBoardView =
output.push((
<path d={firstPath} stroke="white" strokeWidth={SVG_STROKE_WIDTH} />
));
} else {
} else if (!firstPathAbsent) {
output.push((
<path d={firstPath} stroke={firstPathColor} strokeWidth={SVG_STROKE_WIDTH} />
));
@@ -816,7 +830,7 @@ const PedalBoardView =
output.push((
<path d={secondPath} stroke="white" strokeWidth={SVG_STROKE_WIDTH} />
));
} else {
} else if (!secondPathAbsent) {
output.push((
<path d={secondPath} stroke={secondPathColor} strokeWidth={SVG_STROKE_WIDTH} />
));
@@ -828,7 +842,7 @@ const PedalBoardView =
output.push((
<path d={firstPath} stroke={firstPathColor} strokeWidth={SVG_STEREO_STROKE_WIDTH} />
));
} else {
} else if (!firstPathAbsent) {
output.push((
<path d={firstPath} stroke={firstPathColor} strokeWidth={SVG_STROKE_WIDTH} />
));
@@ -837,7 +851,7 @@ const PedalBoardView =
output.push((
<path d={secondPath} stroke={secondPathColor} strokeWidth={SVG_STEREO_STROKE_WIDTH} />
));
} else {
} else if (!secondPathAbsent) {
output.push((
<path d={secondPath} stroke={secondPathColor} strokeWidth={SVG_STROKE_WIDTH} />
));
@@ -1011,126 +1025,130 @@ const PedalBoardView =
}
return true;
}
canOutputStereo(item: PedalLayout): boolean {
getNumberOfInputs(item: PedalLayout): number {
if (item.pedalItem) {
let plugin = this.model.getUiPlugin(item.pedalItem.uri);
if (plugin) {
return plugin.audio_outputs === 2;
return plugin.audio_inputs;
}
}
return true;
return 1;
}
getNumberOfOutputs(item: PedalLayout): number {
if (item.pedalItem) {
let plugin = this.model.getUiPlugin(item.pedalItem.uri);
if (plugin) {
return plugin.audio_outputs;
}
}
return 1;
}
markStereoOutputs(layoutChain: PedalLayout[], stereoInput: boolean, stereoOutput: boolean) {
markStereoOutputs(layoutChain: PedalLayout[], numberOfInputs: number, numberOfOutputs: number) {
// analyze forward flow.
this.markStereoForward(layoutChain, stereoInput);
this.markStereoForward(layoutChain, numberOfInputs);
// mark items that feed a mono effect as mono.
this.markStereoBackward(layoutChain, stereoOutput);
this.markStereoBackward(layoutChain, numberOfOutputs);
}
markStereoBackward(layoutChain: PedalLayout[], stereoOutput: boolean) : boolean
markStereoBackward(layoutChain: PedalLayout[], numberOfOutputs: number) : number
{
for (let i = layoutChain.length-1; i >= 0; --i)
{
let item = layoutChain[i];
if (item.isSplitter())
{
if (!stereoOutput)
{
item.stereoOutput = false;
}
this.markStereoBackward(item.topChildren,stereoOutput);
this.markStereoBackward(item.bottomChildren,stereoOutput);
let topStereoInput = item.topChildren[0].stereoInput;
let bottomStereoInput = item.bottomChildren[0].stereoInput;
item.numberOfOutputs = CalculateConnection(item.numberOfOutputs, numberOfOutputs)
if (! (topStereoInput || bottomStereoInput))
this.markStereoBackward(item.topChildren,numberOfOutputs);
this.markStereoBackward(item.bottomChildren,numberOfOutputs);
let topInputs = item.topChildren[0].numberOfInputs;
let bottomInputs = item.bottomChildren[0].numberOfInputs;
let splitItem = item.pedalItem as PedalBoardSplitItem;
if (splitItem.getSplitType() !== SplitType.Lr)
{
let splitItem = item.pedalItem as PedalBoardSplitItem;
if (splitItem.getSplitType() !== SplitType.Lr)
{
item.stereoInput = false;
}
item.numberOfInputs = CalculateConnection(item.numberOfInputs, Math.max(topInputs,bottomInputs));
}
} else if (item.isEnd())
{
} else if (item.isStart())
{
if (!stereoOutput)
{
item.stereoOutput = false;
}
return item.stereoOutput;
item.numberOfOutputs = CalculateConnection(item.numberOfOutputs,numberOfOutputs);
return item.numberOfOutputs;
} else if (item.isEmpty()) {
if (!stereoOutput)
if (numberOfOutputs === 0)
{
item.stereoOutput = false;
item.stereoInput = false;
item.numberOfOutputs = 0;
item.numberOfInputs = CalculateConnection(item.numberOfInputs,2);
} else {
item.numberOfOutputs = CalculateConnection(item.numberOfOutputs,numberOfOutputs);
item.numberOfInputs = CalculateConnection(item.numberOfInputs,numberOfOutputs);
}
} else {
if (!stereoOutput)
{
item.stereoOutput = false;
}
item.numberOfOutputs = CalculateConnection(item.numberOfOutputs,numberOfOutputs);
}
stereoOutput = item.stereoInput;
numberOfOutputs = item.numberOfInputs;
}
return stereoOutput;
return numberOfOutputs;
}
markStereoForward(layoutChain: PedalLayout[],stereoInput: boolean): boolean
markStereoForward(layoutChain: PedalLayout[],numberOfInputs: number): number
{
if (layoutChain.length === 0) {
return stereoInput;
return numberOfInputs;
}
for (let i = 0; i < layoutChain.length; ++i) {
let item = layoutChain[i];
if (item.isSplitter()) {
let splitter = item.pedalItem as PedalBoardSplitItem;
item.stereoInput = stereoInput;
item.numberOfInputs = numberOfInputs;
let isChainInputStereo = stereoInput;
let chainInputs = numberOfInputs;
if (splitter.getSplitType() === SplitType.Lr)
{
isChainInputStereo = false;
chainInputs = CalculateConnection(numberOfInputs,1);
}
let topStereo = this.markStereoForward(item.topChildren, isChainInputStereo);
let bottomStereo = this.markStereoForward(item.bottomChildren, isChainInputStereo);
let topOutputs = this.markStereoForward(item.topChildren, chainInputs);
let bottomOutputs = this.markStereoForward(item.bottomChildren, chainInputs);
if (splitter.getSplitType() === SplitType.Ab) {
if (splitter.isASelected()) {
item.stereoOutput = topStereo;
item.numberOfOutputs = topOutputs;
} else {
item.stereoOutput = bottomStereo;
item.numberOfOutputs = bottomOutputs;
}
} else if (splitter.getSplitType() === SplitType.Lr) {
item.stereoOutput = true;
item.numberOfOutputs = (topOutputs !== 0 && bottomOutputs !== 0) ? 2: 0;
} else {
item.stereoOutput = topStereo || bottomStereo;
item.numberOfOutputs = CalculateConnection(topOutputs,bottomOutputs);
}
} else if (item.isStart())
{
item.stereoOutput = (PiPedalModelFactory.getInstance().jackSettings.get().inputAudioPorts.length > 1);
item.numberOfOutputs = Math.min(PiPedalModelFactory.getInstance().jackSettings.get().inputAudioPorts.length,2);
} else if (item.isEnd()) {
item.stereoInput = (PiPedalModelFactory.getInstance().jackSettings.get().outputAudioPorts.length > 1) && stereoInput;
return item.stereoInput;
item.numberOfInputs =
CalculateConnection(
Math.min(PiPedalModelFactory.getInstance().jackSettings.get().outputAudioPorts.length,2),
numberOfInputs);
return item.numberOfInputs;
} else if (item.isEmpty()) {
item.stereoInput = stereoInput;
item.stereoOutput = stereoInput;
} else {
if (stereoInput && this.canOutputStereo(item)) {
item.stereoInput = true;
item.numberOfInputs = numberOfInputs;
if (numberOfInputs === 0)
{
item.numberOfOutputs = 2;
} else {
item.stereoInput = false;
item.numberOfOutputs = item.numberOfInputs;
}
item.stereoOutput = this.canOutputStereo(item);
} else {
item.numberOfInputs = CalculateConnection(numberOfInputs,this.getNumberOfInputs(item));
item.numberOfOutputs = this.getNumberOfOutputs(item);
}
stereoInput = item.stereoOutput;
numberOfInputs = item.numberOfOutputs;
}
return stereoInput;
return numberOfInputs;
}
currentLayout?: PedalLayout[];
@@ -1145,7 +1163,7 @@ const PedalBoardView =
{
layoutChain.splice(0, 0, start);
layoutChain.splice(layoutChain.length, 0, end);
this.markStereoOutputs(layoutChain, true, true);
this.markStereoOutputs(layoutChain, 2,2);
}
let layoutSize = this.doLayout(layoutChain);
+80 -2
View File
@@ -22,7 +22,7 @@ import { UiPlugin, UiControl, PluginType } from './Lv2Plugin';
import { PiPedalArgumentError, PiPedalStateError } from './PiPedalError';
import { ObservableProperty } from './ObservableProperty';
import { PedalBoard, ControlValue } from './PedalBoard'
import { PedalBoard, PedalBoardItem, ControlValue } from './PedalBoard'
import PluginClass from './PluginClass';
import PiPedalSocket, { PiPedalMessageHeader } from './PiPedalSocket';
import { nullCast } from './Utility'
@@ -303,6 +303,13 @@ interface ControlChangedBody {
symbol: string;
value: number;
};
interface Vst3ControlChangedBody {
clientId: number;
instanceId: number;
symbol: string;
value: number;
state: string;
};
export interface FavoritesList {
[url: string]: boolean;
@@ -634,6 +641,16 @@ class PiPedalModelImpl implements PiPedalModel {
controlChangedBody.value,
false // do NOT notify the server of the change.
);
} else if (message === "onVst3ControlChanged") {
let controlChangedBody = body as Vst3ControlChangedBody;
this._setVst3PedalBoardControlValue(
controlChangedBody.instanceId,
controlChangedBody.symbol,
controlChangedBody.value,
controlChangedBody.state,
false // do NOT notify the server of the change.
);
} else if (message === "onJackServerSettingsChanged") {
let jackServerSettings = new JackServerSettings().deserialize(body);
this.jackServerSettings.set(jackServerSettings);
@@ -1195,6 +1212,29 @@ class PiPedalModelImpl implements PiPedalModel {
}
}
}
_setVst3PedalBoardControlValue(instanceId: number, key: string, value: number, state: string, notifyServer: boolean ): void {
let pedalBoard = this.pedalBoard.get();
if (pedalBoard === undefined) throw new PiPedalStateError("Pedalboard not ready.");
let newPedalBoard = pedalBoard.clone();
let item: PedalBoardItem = newPedalBoard.getItem(instanceId);
let changed = item.setControlValue(key, value);
item.vstState = state;
if (changed) {
this.pedalBoard.set(newPedalBoard);
if (notifyServer) {
this._setServerControl("setControl", instanceId, key, value);
}
for (let i = 0; i < this._controlValueChangeItems.length; ++i) {
let item = this._controlValueChangeItems[i];
if (instanceId === item.instanceId) {
item.onValueChanged(key, value);
}
}
}
}
setPedalBoardControlValue(instanceId: number, key: string, value: number): void {
@@ -1232,7 +1272,7 @@ class PiPedalModelImpl implements PiPedalModel {
clientId: this.clientId,
pedalBoard: this.pedalBoard.get()
};
this.webSocket?.send("setCurrentPedalBoard", body);
this.webSocket?.send("updateCurrentPedalBoard", body);
}
@@ -1288,6 +1328,8 @@ class PiPedalModelImpl implements PiPedalModel {
deletePedalBoardPedal(instanceId: number): number | null {
let pedalBoard = this.pedalBoard.get();
let newPedalBoard = pedalBoard.clone();
this.updateVst3State(newPedalBoard);
let result = newPedalBoard.deleteItem(instanceId);
if (result != null) {
this.pedalBoard.set(newPedalBoard);
@@ -1301,6 +1343,9 @@ class PiPedalModelImpl implements PiPedalModel {
if (fromInstanceId === toInstanceId) return;
let pedalBoard = this.pedalBoard.get();
let newPedalBoard = pedalBoard.clone();
this.updateVst3State(newPedalBoard);
let fromItem = newPedalBoard.getItem(fromInstanceId);
if (fromItem === null) {
throw new PiPedalArgumentError("fromInstanceId not found.");
@@ -1317,6 +1362,9 @@ class PiPedalModelImpl implements PiPedalModel {
if (fromInstanceId === toInstanceId) return;
let pedalBoard = this.pedalBoard.get();
let newPedalBoard = pedalBoard.clone();
this.updateVst3State(newPedalBoard);
let fromItem = newPedalBoard.getItem(fromInstanceId);
if (fromItem === null) {
throw new PiPedalArgumentError("fromInstanceId not found.");
@@ -1334,6 +1382,10 @@ class PiPedalModelImpl implements PiPedalModel {
let pedalBoard = this.pedalBoard.get();
let newPedalBoard = pedalBoard.clone();
this.updateVst3State(newPedalBoard);
let fromItem = newPedalBoard.getItem(instanceId);
if (fromItem === null) {
throw new PiPedalArgumentError("fromInstanceId not found.");
@@ -1350,6 +1402,9 @@ class PiPedalModelImpl implements PiPedalModel {
let pedalBoard = this.pedalBoard.get();
let newPedalBoard = pedalBoard.clone();
this.updateVst3State(newPedalBoard);
let fromItem = newPedalBoard.getItem(instanceId);
if (fromItem === null) {
throw new PiPedalArgumentError("fromInstanceId not found.");
@@ -1371,6 +1426,9 @@ class PiPedalModelImpl implements PiPedalModel {
let pedalBoard = this.pedalBoard.get();
let newPedalBoard = pedalBoard.clone();
this.updateVst3State(newPedalBoard);
let fromItem = newPedalBoard.getItem(fromInstanceId);
let toItem = newPedalBoard.getItem(toInstanceId);
if (fromItem === null) {
@@ -1389,6 +1447,9 @@ class PiPedalModelImpl implements PiPedalModel {
addPedalBoardItem(instanceId: number, append: boolean): number {
let pedalBoard = this.pedalBoard.get();
let newPedalBoard = pedalBoard.clone();
this.updateVst3State(newPedalBoard);
let item = newPedalBoard.getItem(instanceId);
if (item === null) {
throw new PiPedalArgumentError("instanceId not found.");
@@ -1402,6 +1463,8 @@ class PiPedalModelImpl implements PiPedalModel {
addPedalBoardSplitItem(instanceId: number, append: boolean): number {
let pedalBoard = this.pedalBoard.get();
let newPedalBoard = pedalBoard.clone();
this.updateVst3State(newPedalBoard);
let item = newPedalBoard.getItem(instanceId);
if (item === null) {
throw new PiPedalArgumentError("instanceId not found.");
@@ -1416,6 +1479,9 @@ class PiPedalModelImpl implements PiPedalModel {
setPedalBoardItemEmpty(instanceId: number): number {
let pedalBoard = this.pedalBoard.get();
let newPedalBoard = pedalBoard.clone();
this.updateVst3State(newPedalBoard);
let item = newPedalBoard.getItem(instanceId);
if (item === null) {
throw new PiPedalArgumentError("instanceId not found.");
@@ -1768,12 +1834,24 @@ class PiPedalModelImpl implements PiPedalModel {
this.showAlert(error);
});
}
updateVst3State(pedalBoard: PedalBoard)
{
// let it = pedalBoard.itemsGenerator();
// while (true) {
// let v = it.next();
// if (v.done) break;
// let item = v.value;
// }
}
setMidiBinding(instanceId: number, midiBinding: MidiBinding): void {
let pedalBoard = this.pedalBoard.get();
if (!pedalBoard) {
throw new PiPedalStateError("Pedalboard not loaded.");
}
let newPedalBoard = pedalBoard.clone();
this.updateVst3State(newPedalBoard);
if (newPedalBoard.setMidiBinding(instanceId, midiBinding)) {
this.pedalBoard.set(newPedalBoard);
// notify the server.
+14 -8
View File
@@ -603,17 +603,23 @@ const PluginControl =
let uiControl = this.props.uiControl;
if (uiControl) {
if (uiControl.range_steps > 1) {
range = Math.round(range * uiControl.range_steps-1) / (uiControl.range_steps-1);
range = Math.round(range * (uiControl.range_steps-1)) / (uiControl.range_steps-1);
}
let value: number;
if (uiControl.is_logarithmic)
if (uiControl.min_value === uiControl.max_value)
{
value = uiControl.min_value*Math.pow(uiControl.max_value/uiControl.min_value,range);
} else {
value = range * (uiControl.max_value - uiControl.min_value) + uiControl.min_value;
}
if (uiControl.integer_property) {
value = Math.round(value);
value = uiControl.min_value;
} else
{
if (uiControl.is_logarithmic)
{
value = uiControl.min_value*Math.pow(uiControl.max_value/uiControl.min_value,range);
} else {
value = range * (uiControl.max_value - uiControl.min_value) + uiControl.min_value;
}
if (uiControl.integer_property) {
value = Math.round(value);
}
}
return value;
}