TooB Spectum Analyzer
This commit is contained in:
+80
-64
@@ -21,73 +21,89 @@ add_custom_command(
|
|||||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/react
|
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/react
|
||||||
|
|
||||||
DEPENDS
|
DEPENDS
|
||||||
src/SearchControl.tsx
|
src/NumericInput.tsx
|
||||||
src/WifiChannel.tsx
|
|
||||||
src/JackServerSettingsDialog.tsx
|
|
||||||
src/JackServerSettings.tsx
|
|
||||||
src/DialogEx.tsx
|
|
||||||
src/AlsaDeviceInfo.tsx
|
|
||||||
|
|
||||||
src/AboutDialog.tsx
|
|
||||||
src/App.test.tsx
|
|
||||||
src/App.tsx
|
|
||||||
src/Banks.tsx
|
|
||||||
src/ControlViewFactory.tsx
|
|
||||||
src/DraggableGrid.tsx
|
|
||||||
src/Draggable.tsx
|
|
||||||
src/FullScreenIME.tsx
|
|
||||||
src/GxTunerControl.tsx
|
|
||||||
src/IControlViewFactory.tsx
|
|
||||||
src/index.tsx
|
|
||||||
src/JackHostStatus.tsx
|
|
||||||
src/JackStatusView.tsx
|
|
||||||
src/Jack.tsx
|
|
||||||
src/LoadPluginDialogBackup.tsx
|
|
||||||
src/LoadPluginDialog.tsx
|
|
||||||
src/Lv2Plugin.tsx
|
|
||||||
src/MainPage.tsx
|
|
||||||
src/ObservableProperty.tsx
|
|
||||||
src/PedalBoard.tsx
|
|
||||||
src/PedalBoardView.tsx
|
|
||||||
src/Pedal.tsx
|
|
||||||
src/PiPedalError.tsx
|
|
||||||
src/PiPedalModel.tsx
|
|
||||||
src/PiPedalSocket.tsx
|
|
||||||
src/PluginClass.tsx
|
|
||||||
src/PluginControl.tsx
|
|
||||||
src/PluginControlView.tsx
|
|
||||||
src/PluginIcon.tsx
|
|
||||||
src/PluginInfoDialog.tsx
|
|
||||||
src/PresetDialog.tsx
|
|
||||||
src/PresetSelector.tsx
|
|
||||||
src/Rect.tsx
|
|
||||||
src/RenameDialog.tsx
|
src/RenameDialog.tsx
|
||||||
src/ResizeResponsiveComponent.tsx
|
|
||||||
src/SelectChannelsDialog.tsx
|
|
||||||
src/SelectHoverBackground.tsx
|
|
||||||
src/SelectMidiChannelsDialog.tsx
|
|
||||||
src/SettingsDialog.tsx
|
|
||||||
src/SplitControlView.tsx
|
|
||||||
src/SplitUiControls.tsx
|
|
||||||
src/StringBuilder.tsx
|
|
||||||
src/SvgPathBuilder.tsx
|
|
||||||
src/TemporaryDrawer.tsx
|
|
||||||
src/ToobCabSimView.tsx
|
|
||||||
src/ToobFrequencyResponseView.tsx
|
|
||||||
src/ToobPowerStage2View.tsx
|
|
||||||
src/ToobInputStageView.tsx
|
src/ToobInputStageView.tsx
|
||||||
src/ToobToneStackView.tsx
|
src/ToobCabSimView.tsx
|
||||||
src/Units.tsx
|
src/SearchFilter.tsx
|
||||||
src/Utility.tsx
|
src/Draggable.tsx
|
||||||
src/VuMeter.tsx
|
src/SelectHoverBackground.tsx
|
||||||
src/PluginPreset.tsx
|
src/JackStatusView.tsx
|
||||||
src/XxxSnippet.tsx
|
src/SplitControlView.tsx
|
||||||
src/WifiConfigSettings.tsx
|
src/MidiBindingsDialog.tsx
|
||||||
src/WifiConfigDialog.tsx
|
src/WifiChannel.tsx
|
||||||
src/NoChangePassword.tsx
|
src/PluginControlView.tsx
|
||||||
src/XxxSnippet.tsx
|
src/TemporaryDrawer.tsx
|
||||||
|
src/LoadPluginDialogBackup.tsx
|
||||||
|
src/logo.svg
|
||||||
|
src/AlsaDeviceInfo.tsx
|
||||||
|
src/JackServerSettingsDialog.tsx
|
||||||
src/ZoomedUiControl.tsx
|
src/ZoomedUiControl.tsx
|
||||||
|
src/PedalBoardView.tsx
|
||||||
|
src/MainPage.tsx
|
||||||
|
src/App.tsx
|
||||||
|
src/PresetDialog.tsx
|
||||||
|
src/PluginPreset.tsx
|
||||||
|
src/react-app-env.d.ts
|
||||||
|
src/ToobSpectrumResponseView.tsx
|
||||||
|
src/SettingsDialog.tsx
|
||||||
|
src/SelectChannelsDialog.tsx
|
||||||
|
src/StringBuilder.tsx
|
||||||
|
src/ToobPowerStage2View.tsx
|
||||||
|
src/SearchControl.tsx
|
||||||
|
src/XxxSnippet.tsx
|
||||||
|
src/Units.tsx
|
||||||
|
src/Jack.tsx
|
||||||
|
src/PluginControl.tsx
|
||||||
|
src/ResizeResponsiveComponent.tsx
|
||||||
|
src/Lv2Plugin.tsx
|
||||||
|
src/index.tsx
|
||||||
|
src/NoChangePassword.tsx
|
||||||
|
src/VuMeter.tsx
|
||||||
|
src/ControlViewFactory.tsx
|
||||||
|
src/JackServerSettings.tsx
|
||||||
|
src/MidiBinding.tsx
|
||||||
|
src/UploadDialog.tsx
|
||||||
|
src/PiPedalSocket.tsx
|
||||||
|
src/PedalBoard.tsx
|
||||||
|
src/JackHostStatus.tsx
|
||||||
|
src/ZoomedDial.tsx
|
||||||
|
src/Rect.tsx
|
||||||
|
src/SvgPathBuilder.tsx
|
||||||
|
src/IControlViewFactory.tsx
|
||||||
|
src/PiPedalModel.tsx
|
||||||
|
src/PluginInfoDialog.tsx
|
||||||
|
src/reportWebVitals.ts
|
||||||
|
src/PiPedalError.tsx
|
||||||
|
src/BankDialog.tsx
|
||||||
|
src/PluginIcon.tsx
|
||||||
|
src/WifiConfigDialog.tsx
|
||||||
|
src/PresetSelector.tsx
|
||||||
|
src/LoadPluginDialog.tsx
|
||||||
|
src/ToobFrequencyResponseView.tsx
|
||||||
|
src/WifiConfigSettings.tsx
|
||||||
|
src/setupTests.ts
|
||||||
|
src/AboutDialog.tsx
|
||||||
|
src/index.css
|
||||||
|
src/Banks.tsx
|
||||||
|
src/DialogEx.tsx
|
||||||
|
src/ToobWaveShapeView.tsx
|
||||||
|
src/FullScreenIME.tsx
|
||||||
|
src/App.css
|
||||||
|
src/PluginPresetSelector.tsx
|
||||||
|
src/Utility.tsx
|
||||||
|
src/SelectMidiChannelsDialog.tsx
|
||||||
|
src/App.test.tsx
|
||||||
|
src/MidiBindingView.tsx
|
||||||
|
src/SplitUiControls.tsx
|
||||||
|
src/PluginClass.tsx
|
||||||
|
src/ObservableProperty.tsx
|
||||||
|
src/Pedal.tsx
|
||||||
|
src/GxTunerControl.tsx
|
||||||
|
src/DraggableGrid.tsx
|
||||||
|
src/ToobToneStackView.tsx
|
||||||
|
src/ToobSpectrumAnalyzerView.tsx
|
||||||
|
|
||||||
public/css/roboto.css
|
public/css/roboto.css
|
||||||
public/fonts/Roboto-BlackItalic.woff2
|
public/fonts/Roboto-BlackItalic.woff2
|
||||||
public/fonts/Roboto-Black.woff2
|
public/fonts/Roboto-Black.woff2
|
||||||
|
|||||||
@@ -30,13 +30,15 @@ import ToobInputStageViewFactory from './ToobInputStageView';
|
|||||||
import ToobToneStackViewFactory from './ToobToneStackView';
|
import ToobToneStackViewFactory from './ToobToneStackView';
|
||||||
import ToobCabSimViewFactory from './ToobCabSimView';
|
import ToobCabSimViewFactory from './ToobCabSimView';
|
||||||
import ToobPowerStage2Factory from './ToobPowerStage2View';
|
import ToobPowerStage2Factory from './ToobPowerStage2View';
|
||||||
|
import ToobSpectrumAnalyzerViewFactory from './ToobSpectrumAnalyzerView';
|
||||||
|
|
||||||
|
|
||||||
let pluginFactories: IControlViewFactory[] = [
|
let pluginFactories: IControlViewFactory[] = [
|
||||||
new ToobInputStageViewFactory(),
|
new ToobInputStageViewFactory(),
|
||||||
new ToobToneStackViewFactory(),
|
new ToobToneStackViewFactory(),
|
||||||
new ToobCabSimViewFactory(),
|
new ToobCabSimViewFactory(),
|
||||||
new ToobPowerStage2Factory()
|
new ToobPowerStage2Factory(),
|
||||||
|
new ToobSpectrumAnalyzerViewFactory()
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -288,7 +288,7 @@ const JackServerSettingsDialog = withStyles(styles)(
|
|||||||
{((!noDevices) && !waitingForDevices) && (
|
{((!noDevices) && !waitingForDevices) && (
|
||||||
this.state.alsaDevices!.map((device) =>
|
this.state.alsaDevices!.map((device) =>
|
||||||
(
|
(
|
||||||
<MenuItem value={device.id}>{device.name}</MenuItem>
|
<MenuItem key={device.id} value={device.id}>{device.name}</MenuItem>
|
||||||
)
|
)
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ const MidiBindingView =
|
|||||||
generateControlSelects(): React.ReactNode[] {
|
generateControlSelects(): React.ReactNode[] {
|
||||||
|
|
||||||
return Utility.validMidiControllers.map((control) => (
|
return Utility.validMidiControllers.map((control) => (
|
||||||
<MenuItem value={control.value}>{control.displayName}</MenuItem>
|
<MenuItem key={control.value} value={control.value}>{control.displayName}</MenuItem>
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -556,7 +556,7 @@ const PluginControl =
|
|||||||
style={{ marginLeft: 4, marginRight: 4, width: 140 }}
|
style={{ marginLeft: 4, marginRight: 4, width: 140 }}
|
||||||
>
|
>
|
||||||
{control.scale_points.map((scale_point: ScalePoint) => (
|
{control.scale_points.map((scale_point: ScalePoint) => (
|
||||||
<MenuItem value={scale_point.value}>{scale_point.label}</MenuItem>
|
<MenuItem key={scale_point.value} value={scale_point.value}>{scale_point.label}</MenuItem>
|
||||||
|
|
||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
|
|||||||
@@ -365,6 +365,7 @@ const PluginControlView =
|
|||||||
|
|
||||||
for (let i = 0; i < controls.length; ++i)
|
for (let i = 0; i < controls.length; ++i)
|
||||||
{
|
{
|
||||||
|
controls[i].key = 'k'+i;
|
||||||
result.push(controls[i]);
|
result.push(controls[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -298,7 +298,7 @@ const PresetSelector =
|
|||||||
{
|
{
|
||||||
presets.presets.map((preset) => {
|
presets.presets.map((preset) => {
|
||||||
return (
|
return (
|
||||||
<MenuItem value={preset.instanceId} >
|
<MenuItem key={preset.instanceId} value={preset.instanceId} >
|
||||||
{(presets.presetChanged && preset.instanceId === presets.selectedInstanceId)
|
{(presets.presetChanged && preset.instanceId === presets.selectedInstanceId)
|
||||||
? (preset.name + "*")
|
? (preset.name + "*")
|
||||||
: (preset.name)
|
: (preset.name)
|
||||||
|
|||||||
@@ -0,0 +1,89 @@
|
|||||||
|
// Copyright (c) 2021 Robin Davies
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
// the Software without restriction, including without limitation the rights to
|
||||||
|
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
// subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
// 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 React from 'react';
|
||||||
|
import { createStyles, withStyles, WithStyles, Theme } from '@material-ui/core/styles';
|
||||||
|
|
||||||
|
import IControlViewFactory from './IControlViewFactory';
|
||||||
|
import { PiPedalModelFactory, PiPedalModel } from "./PiPedalModel";
|
||||||
|
import { PedalBoardItem } from './PedalBoard';
|
||||||
|
import PluginControlView, { ControlGroup,ControlViewCustomization } from './PluginControlView';
|
||||||
|
import ToobSpectrumResponseView from './ToobSpectrumResponseView';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const styles = (theme: Theme) => createStyles({
|
||||||
|
});
|
||||||
|
|
||||||
|
interface ToobSpectrumAnalyzerProps extends WithStyles<typeof styles> {
|
||||||
|
instanceId: number;
|
||||||
|
item: PedalBoardItem;
|
||||||
|
|
||||||
|
};
|
||||||
|
interface ToobSpectrumAnalyzerState {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const ToobSpectrumAnalyzerView =
|
||||||
|
withStyles(styles, { withTheme: true })(
|
||||||
|
class extends React.Component<ToobSpectrumAnalyzerProps, ToobSpectrumAnalyzerState>
|
||||||
|
implements ControlViewCustomization
|
||||||
|
{
|
||||||
|
model: PiPedalModel;
|
||||||
|
|
||||||
|
customizationId: number = 1;
|
||||||
|
|
||||||
|
constructor(props: ToobSpectrumAnalyzerProps) {
|
||||||
|
super(props);
|
||||||
|
this.model = PiPedalModelFactory.getInstance();
|
||||||
|
this.state = {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ModifyControls(controls: (React.ReactNode| ControlGroup)[]): (React.ReactNode| ControlGroup)[]
|
||||||
|
{
|
||||||
|
controls.splice(0,0,
|
||||||
|
( <ToobSpectrumResponseView instanceId={this.props.instanceId} />)
|
||||||
|
);
|
||||||
|
return controls;
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
return (<PluginControlView
|
||||||
|
instanceId={this.props.instanceId}
|
||||||
|
item={this.props.item}
|
||||||
|
customization={this}
|
||||||
|
customizationId={this.customizationId}
|
||||||
|
/>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class ToobSpectrumAnalyzerViewFactory implements IControlViewFactory {
|
||||||
|
uri: string = "http://two-play.com/plugins/toob-spectrum";
|
||||||
|
|
||||||
|
Create(model: PiPedalModel, pedalBoardItem: PedalBoardItem): React.ReactNode {
|
||||||
|
return (<ToobSpectrumAnalyzerView instanceId={pedalBoardItem.instanceId} item={pedalBoardItem} />);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
export default ToobSpectrumAnalyzerViewFactory;
|
||||||
@@ -0,0 +1,307 @@
|
|||||||
|
// Copyright (c) 2021 Robin Davies
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
// the Software without restriction, including without limitation the rights to
|
||||||
|
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
// subject to the following conditions:
|
||||||
|
//
|
||||||
|
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
// 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 React from 'react';
|
||||||
|
import { createStyles, withStyles, WithStyles, Theme } from '@material-ui/core/styles';
|
||||||
|
|
||||||
|
import { PiPedalModelFactory, PiPedalModel, State,ListenHandle } from "./PiPedalModel";
|
||||||
|
import { StandardItemSize } from './PluginControlView';
|
||||||
|
import Utility from './Utility';
|
||||||
|
import { setInterval,clearInterval } from 'timers';
|
||||||
|
|
||||||
|
|
||||||
|
const SPECTRUM_RESPONSE_VECTOR_URI = "http://two-play.com/plugins/toob#spectrumResponse";
|
||||||
|
|
||||||
|
const PLOT_WIDTH = StandardItemSize.width*3-16;
|
||||||
|
const PLOT_HEIGHT = StandardItemSize.height-12;
|
||||||
|
|
||||||
|
const styles = (theme: Theme) => createStyles({
|
||||||
|
frame: {
|
||||||
|
width: PLOT_WIDTH, height: PLOT_HEIGHT, background: "#444",
|
||||||
|
borderRadius: 6,
|
||||||
|
marginTop: 12, marginLeft: 8, marginRight: 8,
|
||||||
|
boxShadow: "1px 4px 8px #000 inset"
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
interface ToobSpectrumResponseProps extends WithStyles<typeof styles> {
|
||||||
|
instanceId: number;
|
||||||
|
|
||||||
|
};
|
||||||
|
interface ToobSpectrumResponseState {
|
||||||
|
path: string;
|
||||||
|
minF: number;
|
||||||
|
maxF: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
const ToobSpectrumResponseView =
|
||||||
|
withStyles(styles, { withTheme: true })(
|
||||||
|
class extends React.Component<ToobSpectrumResponseProps, ToobSpectrumResponseState>
|
||||||
|
{
|
||||||
|
model: PiPedalModel;
|
||||||
|
|
||||||
|
customizationId: number = 1;
|
||||||
|
|
||||||
|
constructor(props: ToobSpectrumResponseProps) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
|
||||||
|
this.model = PiPedalModelFactory.getInstance();
|
||||||
|
|
||||||
|
let minF = 60;
|
||||||
|
let maxF = 18000;
|
||||||
|
|
||||||
|
let plugin = this.model.pedalBoard.get()?.maybeGetItem(this.props.instanceId);
|
||||||
|
if (plugin)
|
||||||
|
{
|
||||||
|
minF = plugin.getControlValue("minF");
|
||||||
|
maxF = plugin.getControlValue("maxF");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
path: "",
|
||||||
|
minF: minF,
|
||||||
|
maxF: maxF
|
||||||
|
};
|
||||||
|
|
||||||
|
this.onPedalBoardChanged = this.onPedalBoardChanged.bind(this);
|
||||||
|
this.onStateChanged = this.onStateChanged.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
onStateChanged()
|
||||||
|
{
|
||||||
|
if (this.model.state.get() === State.Ready)
|
||||||
|
{
|
||||||
|
this.requestDeferred = false;
|
||||||
|
this.requestOutstanding = false;
|
||||||
|
|
||||||
|
let plugin = this.model.pedalBoard.get()?.maybeGetItem(this.props.instanceId);
|
||||||
|
if (plugin)
|
||||||
|
{
|
||||||
|
let minF = plugin.getControlValue("minF");
|
||||||
|
let maxF = plugin.getControlValue("maxF");
|
||||||
|
this.setState({minF: minF, maxF: maxF});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
this.isReady = this.model.state.get() === State.Ready;
|
||||||
|
|
||||||
|
this.maybeStartClock(); // after a reconnect.
|
||||||
|
}
|
||||||
|
onPedalBoardChanged()
|
||||||
|
{
|
||||||
|
this.maybeStartClock();
|
||||||
|
let plugin = this.model.pedalBoard.get()?.maybeGetItem(this.props.instanceId);
|
||||||
|
if (plugin)
|
||||||
|
{
|
||||||
|
let minF = plugin.getControlValue("minF");
|
||||||
|
let maxF = plugin.getControlValue("maxF");
|
||||||
|
this.setState({minF: minF, maxF: maxF});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mounted: boolean = false;
|
||||||
|
isReady: boolean = false;
|
||||||
|
componentDidMount()
|
||||||
|
{
|
||||||
|
this.model.state.addOnChangedHandler(this.onStateChanged);
|
||||||
|
this.model.pedalBoard.addOnChangedHandler(this.onPedalBoardChanged);
|
||||||
|
this.mounted = true;
|
||||||
|
this.isReady = this.model.state.get() === State.Ready;
|
||||||
|
this.maybeStartClock();
|
||||||
|
}
|
||||||
|
componentWillUnmount()
|
||||||
|
{
|
||||||
|
this.mounted = false;
|
||||||
|
this.maybeStartClock();
|
||||||
|
this.model.state.removeOnChangedHandler(this.onStateChanged);
|
||||||
|
this.model.pedalBoard.removeOnChangedHandler(this.onPedalBoardChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidUpdate() {
|
||||||
|
}
|
||||||
|
requestOutstanding: boolean = false;
|
||||||
|
requestDeferred: boolean = false;
|
||||||
|
|
||||||
|
// Size of the SVG element.
|
||||||
|
xMin: number = 0;
|
||||||
|
xMax: number = PLOT_WIDTH+4;
|
||||||
|
yMin: number = 0;
|
||||||
|
yMax: number = PLOT_HEIGHT;
|
||||||
|
|
||||||
|
onSpectrumResponseUpdated(svgPath: string) {
|
||||||
|
this.setState({path: svgPath});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
isTicking : boolean = false;
|
||||||
|
hClock?: NodeJS.Timeout;
|
||||||
|
hAtomOutput?: ListenHandle;
|
||||||
|
|
||||||
|
maybeStartClock() {
|
||||||
|
let shouldTick = this.isReady && this.mounted;
|
||||||
|
|
||||||
|
if (shouldTick !== this.isTicking)
|
||||||
|
{
|
||||||
|
this.isTicking = shouldTick;
|
||||||
|
if (shouldTick)
|
||||||
|
{
|
||||||
|
this.hAtomOutput = this.model.listenForAtomOutput(this.props.instanceId,
|
||||||
|
(instanceId,atomOutput)=> {
|
||||||
|
this.onSpectrumResponseUpdated(atomOutput.value as string);
|
||||||
|
if (this.requestDeferred) {
|
||||||
|
Utility.delay(30) // take breath
|
||||||
|
.then(
|
||||||
|
() => {
|
||||||
|
this.requestOutstanding = false;
|
||||||
|
this.requestDeferred = false;
|
||||||
|
this.requestSpectrum();
|
||||||
|
}
|
||||||
|
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
this.requestOutstanding = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
this.hClock = setInterval(()=> {
|
||||||
|
this.requestSpectrum();
|
||||||
|
},
|
||||||
|
1000/15);
|
||||||
|
} else {
|
||||||
|
if (this.hAtomOutput)
|
||||||
|
{
|
||||||
|
this.model.cancelListenForAtomOutput(this.hAtomOutput);
|
||||||
|
this.hAtomOutput = undefined;
|
||||||
|
}
|
||||||
|
if (this.hClock)
|
||||||
|
{
|
||||||
|
clearInterval(this.hClock);
|
||||||
|
this.hClock = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
requestSpectrum() {
|
||||||
|
if (this.requestOutstanding) { // throttling.
|
||||||
|
this.requestDeferred = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.requestOutstanding = true;
|
||||||
|
this.model.getLv2Parameter<string>(this.props.instanceId, SPECTRUM_RESPONSE_VECTOR_URI)
|
||||||
|
.then((data) => {
|
||||||
|
}).catch(error => {
|
||||||
|
// assume the connection was lost. We'll get saved by a reconnect.
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
numPoints = 200;
|
||||||
|
|
||||||
|
minF = 60;
|
||||||
|
maxF = 18000;
|
||||||
|
logMinF = Math.log(this.minF);
|
||||||
|
logMaxF = Math.log(this.maxF);
|
||||||
|
|
||||||
|
toX(f: number): number {
|
||||||
|
let width = PLOT_WIDTH-8;
|
||||||
|
return (Math.log(f)-this.logMinF)*width/(this.logMaxF-this.logMinF);
|
||||||
|
}
|
||||||
|
grid(): React.ReactNode[] {
|
||||||
|
let result: React.ReactNode[] = [];
|
||||||
|
let width = PLOT_WIDTH-8;
|
||||||
|
let height = PLOT_HEIGHT-8;
|
||||||
|
|
||||||
|
for (let db = -20; db >= -100; db -= 20)
|
||||||
|
{
|
||||||
|
let y = height*db/-100;
|
||||||
|
result.push(
|
||||||
|
(
|
||||||
|
<line x1={0} y1={y} x2={width} y2={y} key={"db" + db} />
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let minF = this.state.minF;
|
||||||
|
let maxF = this.state.maxF;
|
||||||
|
this.minF = minF;
|
||||||
|
this.maxF = maxF;
|
||||||
|
this.logMinF = Math.log(this.minF);
|
||||||
|
this.logMaxF = Math.log(this.maxF);
|
||||||
|
|
||||||
|
for (let decade = 10; decade < 100000; decade *= 10)
|
||||||
|
{
|
||||||
|
for (let minorTick = 1; minorTick <= 5; ++ minorTick)
|
||||||
|
{
|
||||||
|
let f = decade*minorTick;
|
||||||
|
if (f > minF && f < maxF)
|
||||||
|
{
|
||||||
|
let x = this.toX(f);
|
||||||
|
if (minorTick === 1)
|
||||||
|
{
|
||||||
|
result.push(
|
||||||
|
(
|
||||||
|
<line x1={x} y1={0} x2={x} y2={height} key={"hgrid"+f} strokeWidth={1}/>
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
result.push(
|
||||||
|
(
|
||||||
|
<line x1={x} y1={0} x2={x} y2={height} key={"hgrid"+f} />
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let classes = this.props.classes;
|
||||||
|
return (
|
||||||
|
<div className={classes.frame} style={{position: "relative"}} >
|
||||||
|
<div style={{position: "absolute", left: 4, top: 4}}>
|
||||||
|
<svg width={PLOT_WIDTH-8} height={PLOT_HEIGHT-8} stroke="#888" strokeWidth="0.5" opacity="1"
|
||||||
|
>
|
||||||
|
{this.grid()}
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div style={{position: "absolute", left: 4, top: 4}}>
|
||||||
|
<svg width={PLOT_WIDTH-8} height={PLOT_HEIGHT-8} preserveAspectRatio='none' viewBox={"0 0 " + this.numPoints + " " + 1000} stroke="none" fill="#0FC" strokeWidth="2.5" opacity="0.6"
|
||||||
|
>
|
||||||
|
<path d={this.state.path} />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export default ToobSpectrumResponseView;
|
||||||
@@ -40,16 +40,6 @@ const styles = (theme: Theme) => createStyles({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
interface SvgRect
|
|
||||||
{
|
|
||||||
x: number;
|
|
||||||
y: number;
|
|
||||||
width: number;
|
|
||||||
height: number;
|
|
||||||
color: string;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ToobWaveShapeProps extends WithStyles<typeof styles> {
|
interface ToobWaveShapeProps extends WithStyles<typeof styles> {
|
||||||
instanceId: number;
|
instanceId: number;
|
||||||
controlNumber: number;
|
controlNumber: number;
|
||||||
|
|||||||
+10
-4
@@ -345,10 +345,14 @@ export const VuMeter =
|
|||||||
|
|
||||||
addVuSubscription() {
|
addVuSubscription() {
|
||||||
this.removeVuSubscription();
|
this.removeVuSubscription();
|
||||||
if (this.props.instanceId !== -1) {
|
|
||||||
this.subscribedInstanceId = this.props.instanceId;
|
if (this.model.state.get() === State.Ready)
|
||||||
this.subscriptionHandle = this.model.addVuSubscription(this.props.instanceId, this.onVuChanged);
|
{
|
||||||
this.resetTelltales();
|
if (this.props.instanceId !== -1) {
|
||||||
|
this.subscribedInstanceId = this.props.instanceId;
|
||||||
|
this.subscriptionHandle = this.model.addVuSubscription(this.props.instanceId, this.onVuChanged);
|
||||||
|
this.resetTelltales();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
removeVuSubscription() {
|
removeVuSubscription() {
|
||||||
@@ -407,6 +411,8 @@ export const VuMeter =
|
|||||||
if (state === State.Ready)
|
if (state === State.Ready)
|
||||||
{
|
{
|
||||||
this.addVuSubscription(); // re-subscribe.
|
this.addVuSubscription(); // re-subscribe.
|
||||||
|
} else {
|
||||||
|
this.removeVuSubscription();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
src
|
||||||
|
src/NumericInput.tsx
|
||||||
|
src/RenameDialog.tsx
|
||||||
|
src/ToobInputStageView.tsx
|
||||||
|
src/ToobCabSimView.tsx
|
||||||
|
src/SearchFilter.tsx
|
||||||
|
src/Draggable.tsx
|
||||||
|
src/SelectHoverBackground.tsx
|
||||||
|
src/JackStatusView.tsx
|
||||||
|
src/SplitControlView.tsx
|
||||||
|
src/MidiBindingsDialog.tsx
|
||||||
|
src/WifiChannel.tsx
|
||||||
|
src/PluginControlView.tsx
|
||||||
|
src/TemporaryDrawer.tsx
|
||||||
|
src/LoadPluginDialogBackup.tsx
|
||||||
|
src/logo.svg
|
||||||
|
src/AlsaDeviceInfo.tsx
|
||||||
|
src/JackServerSettingsDialog.tsx
|
||||||
|
src/ZoomedUiControl.tsx
|
||||||
|
src/PedalBoardView.tsx
|
||||||
|
src/MainPage.tsx
|
||||||
|
src/App.tsx
|
||||||
|
src/PresetDialog.tsx
|
||||||
|
src/PluginPreset.tsx
|
||||||
|
src/react-app-env.d.ts
|
||||||
|
src/ToobSpectrumResponseView.tsx
|
||||||
|
src/SettingsDialog.tsx
|
||||||
|
src/SelectChannelsDialog.tsx
|
||||||
|
src/StringBuilder.tsx
|
||||||
|
src/ToobPowerStage2View.tsx
|
||||||
|
src/SearchControl.tsx
|
||||||
|
src/XxxSnippet.tsx
|
||||||
|
src/Units.tsx
|
||||||
|
src/Jack.tsx
|
||||||
|
src/PluginControl.tsx
|
||||||
|
src/ResizeResponsiveComponent.tsx
|
||||||
|
src/Lv2Plugin.tsx
|
||||||
|
src/index.tsx
|
||||||
|
src/NoChangePassword.tsx
|
||||||
|
src/VuMeter.tsx
|
||||||
|
src/ControlViewFactory.tsx
|
||||||
|
src/JackServerSettings.tsx
|
||||||
|
src/MidiBinding.tsx
|
||||||
|
src/UploadDialog.tsx
|
||||||
|
src/PiPedalSocket.tsx
|
||||||
|
src/PedalBoard.tsx
|
||||||
|
src/JackHostStatus.tsx
|
||||||
|
src/ZoomedDial.tsx
|
||||||
|
src/Rect.tsx
|
||||||
|
src/SvgPathBuilder.tsx
|
||||||
|
src/IControlViewFactory.tsx
|
||||||
|
src/PiPedalModel.tsx
|
||||||
|
src/PluginInfoDialog.tsx
|
||||||
|
src/reportWebVitals.ts
|
||||||
|
src/PiPedalError.tsx
|
||||||
|
src/BankDialog.tsx
|
||||||
|
src/PluginIcon.tsx
|
||||||
|
src/WifiConfigDialog.tsx
|
||||||
|
src/PresetSelector.tsx
|
||||||
|
src/LoadPluginDialog.tsx
|
||||||
|
src/ToobFrequencyResponseView.tsx
|
||||||
|
src/WifiConfigSettings.tsx
|
||||||
|
src/setupTests.ts
|
||||||
|
src/AboutDialog.tsx
|
||||||
|
src/index.css
|
||||||
|
src/Banks.tsx
|
||||||
|
src/DialogEx.tsx
|
||||||
|
src/ToobWaveShapeView.tsx
|
||||||
|
src/FullScreenIME.tsx
|
||||||
|
src/App.css
|
||||||
|
src/PluginPresetSelector.tsx
|
||||||
|
src/Utility.tsx
|
||||||
|
src/SelectMidiChannelsDialog.tsx
|
||||||
|
src/App.test.tsx
|
||||||
|
src/MidiBindingView.tsx
|
||||||
|
src/SplitUiControls.tsx
|
||||||
|
src/PluginClass.tsx
|
||||||
|
src/ObservableProperty.tsx
|
||||||
|
src/Pedal.tsx
|
||||||
|
src/GxTunerControl.tsx
|
||||||
|
src/DraggableGrid.tsx
|
||||||
|
src/ToobToneStackView.tsx
|
||||||
|
src/ToobSpectrumAnalyzerView.tsx
|
||||||
+1
-1
@@ -658,7 +658,7 @@ void Lv2Effect::WriteAtom(json_writer &writer, LV2_Atom*pAtom)
|
|||||||
);
|
);
|
||||||
} else if (pAtom->type == uris.atom_String)
|
} else if (pAtom->type == uris.atom_String)
|
||||||
{
|
{
|
||||||
const char *p = (const char*) (((char*) pAtom) + sizeof(LV2_Atom_String));
|
const char *p = (((const char*) pAtom) + sizeof(LV2_Atom_String));
|
||||||
writer.write(
|
writer.write(
|
||||||
p
|
p
|
||||||
);
|
);
|
||||||
|
|||||||
+6
-2
@@ -71,7 +71,11 @@ LV2_Worker_Status Worker::worker_respond_fn(LV2_Worker_Respond_Handle handle, ui
|
|||||||
|
|
||||||
LV2_Worker_Status Worker::WorkerResponse(uint32_t size, const void *data)
|
LV2_Worker_Status Worker::WorkerResponse(uint32_t size, const void *data)
|
||||||
{
|
{
|
||||||
if (responseRingBuffer.write(sizeof(size), (uint8_t *)&size))
|
if (responseRingBuffer.writeSpace() < sizeof(size)+size)
|
||||||
|
{
|
||||||
|
return LV2_WORKER_ERR_NO_SPACE;
|
||||||
|
}
|
||||||
|
if (!responseRingBuffer.write(sizeof(size), (uint8_t *)&size))
|
||||||
{
|
{
|
||||||
return LV2_WORKER_ERR_NO_SPACE;
|
return LV2_WORKER_ERR_NO_SPACE;
|
||||||
}
|
}
|
||||||
@@ -107,7 +111,7 @@ void Worker::ThreadProc()
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
size_t size;
|
uint32_t size;
|
||||||
while (requestRingBuffer.readSpace() > sizeof(size))
|
while (requestRingBuffer.readSpace() > sizeof(size))
|
||||||
{
|
{
|
||||||
if (!requestRingBuffer.read(sizeof(size), (uint8_t *)&size))
|
if (!requestRingBuffer.read(sizeof(size), (uint8_t *)&size))
|
||||||
|
|||||||
Reference in New Issue
Block a user