Dark Mode, Toob Neural Amp Modeler
@@ -1,10 +1,10 @@
|
|||||||
cmake_minimum_required(VERSION 3.16.0)
|
cmake_minimum_required(VERSION 3.16.0)
|
||||||
project(pipedal
|
project(pipedal
|
||||||
VERSION 1.1.27
|
VERSION 1.1.28
|
||||||
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 "v1.1.27")
|
set (DISPLAY_VERSION "v1.1.28")
|
||||||
|
|
||||||
set (CMAKE_INSTALL_PREFIX "/usr/")
|
set (CMAKE_INSTALL_PREFIX "/usr/")
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
|
|
||||||
<img src='docs/GithubBanner.png' width="100%" /><br/>
|
<img src='docs/GithubBanner.png' width="100%" /><br/>
|
||||||
|
|
||||||
Download: <a href='https://rerdavies.github.io/pipedal/download.html'>v1.1.27</a>
|
Download: <a href='https://rerdavies.github.io/pipedal/download.html'>v1.1.28</a>
|
||||||
|
|
||||||
Website: [https://rerdavies.github.io/pipedal](https://rerdavies.github.io/pipedal).
|
Website: [https://rerdavies.github.io/pipedal](https://rerdavies.github.io/pipedal).
|
||||||
|
|
||||||
|
|
||||||
> NEW version 1.1.27 release. See the [release notes](https://rerdavies.github.io/pipedal/ReleaseNotes) for details.
|
> NEW version 1.1.28 release. See the [release notes](https://rerdavies.github.io/pipedal/ReleaseNotes) for details.
|
||||||
|
|
||||||
Use your Raspberry Pi as a guitar effects pedal. Configure and control PiPedal with your phone or tablet.
|
Use your Raspberry Pi as a guitar effects pedal. Configure and control PiPedal with your phone or tablet.
|
||||||
PiPedal running on a Raspberry Pi 4 provides stable super-low-latency audio via external USB audio devices, or internal Raspberry Pi audio hats.
|
PiPedal running on a Raspberry Pi 4 provides stable super-low-latency audio via external USB audio devices, or internal Raspberry Pi audio hats.
|
||||||
|
|||||||
@@ -9,6 +9,6 @@ Package: pipedal
|
|||||||
Pre-Depends: hostapd;authbind;dnsmasq
|
Pre-Depends: hostapd;authbind;dnsmasq
|
||||||
Priority: optional
|
Priority: optional
|
||||||
Section: sound
|
Section: sound
|
||||||
Version: 1.1.27
|
Version: 1.1.28
|
||||||
Installed-Size: 15147
|
Installed-Size: 15147
|
||||||
|
|
||||||
|
|||||||
@@ -13,14 +13,14 @@ page_icon: img/Install4.jpg
|
|||||||
|
|
||||||
Download the most recent Debian (.deb) package for your platform:
|
Download the most recent Debian (.deb) package for your platform:
|
||||||
|
|
||||||
- [Ubuntu/Raspberry Pi OS (64-bit) v1.1.27](https://github.com/rerdavies/pipedal/releases/download/v1.1.27/pipedal_1.1.27_arm64.deb)
|
- [Ubuntu/Raspberry Pi OS (64-bit) v1.1.28](https://github.com/rerdavies/pipedal/releases/download/v1.1.28/pipedal_1.1.28_arm64.deb)
|
||||||
|
|
||||||
Install the package by running
|
Install the package by running
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo apt update
|
sudo apt update
|
||||||
cd ~/Downloads
|
cd ~/Downloads
|
||||||
sudo apt-get install ./pipedal_1.1.27_arm64.deb
|
sudo apt-get install ./pipedal_1.1.28_arm64.deb
|
||||||
```
|
```
|
||||||
On Raspberry Pi OS, if you have a graphical desktop installed, you can also install the package by double-clicking on the downloaded package in the File Manager.
|
On Raspberry Pi OS, if you have a graphical desktop installed, you can also install the package by double-clicking on the downloaded package in the File Manager.
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,18 @@
|
|||||||
# Release Notes
|
# Release Notes
|
||||||
|
|
||||||
|
## PiPedal 1.1.28
|
||||||
|
|
||||||
|
New in this release.
|
||||||
|
|
||||||
|
- TooB Neural Amp Modeler - an LV2 port of Steven Atkinson's astounding Neural Amp Modeler. Donwload model files from [ToneHunt.org](https://tonehunt.org). CPU is very high -- it runs on a Raspberry Pi 4 with just enough CPU left over for a couple of extra effects; but the results are worth it. TooB ML provides Neural Net modelled guitar amps with more modest CPU use (but considerably less flexibility).
|
||||||
|
|
||||||
|
- Dark mode. Go to the settings dialog to turn on Dark Mode.
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
|
||||||
|
- Plugin information is updated in the web app after reconnecting, in order to pick up new plugins that may have been detected while the web server was being restarted.
|
||||||
|
|
||||||
|
|
||||||
## PiPedal 1.1.27
|
## PiPedal 1.1.27
|
||||||
|
|
||||||
- Add missing lv2-dev dependency.
|
- Add missing lv2-dev dependency.
|
||||||
|
|||||||
@@ -4,14 +4,14 @@
|
|||||||
|
|
||||||
Download the most recent Debian (.deb) package for your platform:
|
Download the most recent Debian (.deb) package for your platform:
|
||||||
|
|
||||||
- [Ubuntu or Raspberry Pi OS (64-bit)](https://github.com/rerdavies/pipedal/releases/download/v1.1.27/pipedal_1.1.27_arm64.deb) v1.1.27
|
- [Ubuntu or Raspberry Pi OS (64-bit)](https://github.com/rerdavies/pipedal/releases/download/v1.1.28/pipedal_1.1.28_arm64.deb) v1.1.28
|
||||||
|
|
||||||
Install the package by running
|
Install the package by running
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo apt update
|
sudo apt update
|
||||||
cd ~/Downloads
|
cd ~/Downloads
|
||||||
sudo apt-get install ./pipedal_1.1.27_arm64.deb
|
sudo apt-get install ./pipedal_1.1.28_arm64.deb
|
||||||
```
|
```
|
||||||
|
|
||||||
Follow the instructions in [_Configuring PiPedal After Installation_](https://rerdavies.github.io/pipedal/Configuring.html) to complete the installation.
|
Follow the instructions in [_Configuring PiPedal After Installation_](https://rerdavies.github.io/pipedal/Configuring.html) to complete the installation.
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
|
|
||||||
|
|
||||||
<img src="GithubBanner.png" width="100%"/>
|
<img src="GithubBanner.png" width="100%"/>
|
||||||
<a href="Installing.html"><i>v1.1.27</i></a>
|
<a href="Installing.html"><i>v1.1.28</i></a>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
To download PiPedal, click [here](download.md).
|
To download PiPedal, click [here](download.md).
|
||||||
|
|
||||||
> NEW version 1.1.27 release. See the [release notes](https://rerdavies.github.io/pipedal/ReleaseNotes) for details.
|
> NEW version 1.1.28 release. See the [release notes](https://rerdavies.github.io/pipedal/ReleaseNotes) for details.
|
||||||
|
|
||||||
|
|
||||||
Use your Raspberry Pi as a guitar effects pedal. Configure and control PiPedal with your phone or tablet.
|
Use your Raspberry Pi as a guitar effects pedal. Configure and control PiPedal with your phone or tablet.
|
||||||
|
|||||||
@@ -53,7 +53,7 @@
|
|||||||
rdfs:comment "TooB amplifier cabinet simulator." ;
|
rdfs:comment "TooB amplifier cabinet simulator." ;
|
||||||
|
|
||||||
mod:brand "TooB";
|
mod:brand "TooB";
|
||||||
mod:label "Cab Simulator";
|
mod:label "TooB CabSim";
|
||||||
lv2:requiredFeature urid:map ;
|
lv2:requiredFeature urid:map ;
|
||||||
lv2:optionalFeature lv2:hardRTCapable;
|
lv2:optionalFeature lv2:hardRTCapable;
|
||||||
patch:readable
|
patch:readable
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ Source: https://www.openair.hosted.york.ac.uk/?page_id=483
|
|||||||
""" ;
|
""" ;
|
||||||
|
|
||||||
mod:brand "TooB";
|
mod:brand "TooB";
|
||||||
mod:label "Convolution Reverb";
|
mod:label "TooB CReverb";
|
||||||
lv2:requiredFeature urid:map;
|
lv2:requiredFeature urid:map;
|
||||||
lv2:optionalFeature state::freePath, state:makePath, state:mapPath, work:schedule ;
|
lv2:optionalFeature state::freePath, state:makePath, state:mapPath, work:schedule ;
|
||||||
lv2:extensionData state:interface;
|
lv2:extensionData state:interface;
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ Source: https://www.openair.hosted.york.ac.uk/?page_id=483
|
|||||||
""" ;
|
""" ;
|
||||||
|
|
||||||
mod:brand "TooB";
|
mod:brand "TooB";
|
||||||
mod:label "Convolution Reverb (Stereo)";
|
mod:label "TooB CReverb Stereo";
|
||||||
lv2:requiredFeature urid:map;
|
lv2:requiredFeature urid:map;
|
||||||
lv2:optionalFeature state::freePath, state:makePath, state:mapPath, work:schedule ;
|
lv2:optionalFeature state::freePath, state:makePath, state:mapPath, work:schedule ;
|
||||||
lv2:extensionData state:interface;
|
lv2:extensionData state:interface;
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ inputStage:filterGroup
|
|||||||
lv2:microVersion 16 ;
|
lv2:microVersion 16 ;
|
||||||
|
|
||||||
mod:brand "TooB";
|
mod:brand "TooB";
|
||||||
mod:label "Input Stage";
|
mod:label "TooB Input";
|
||||||
lv2:requiredFeature urid:map ;
|
lv2:requiredFeature urid:map ;
|
||||||
lv2:optionalFeature lv2:hardRTCapable;
|
lv2:optionalFeature lv2:hardRTCapable;
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
ToobAmp.so.1.0.16
|
ToobAmp.so.1.0.17
|
||||||
@@ -46,7 +46,7 @@ Emulation of a Boss CE-2 Chorus.
|
|||||||
""" ;
|
""" ;
|
||||||
|
|
||||||
mod:brand "TooB";
|
mod:brand "TooB";
|
||||||
mod:label "CE-2 Chorus";
|
mod:label "TooB CE-2";
|
||||||
lv2:optionalFeature lv2:hardRTCapable;
|
lv2:optionalFeature lv2:hardRTCapable;
|
||||||
|
|
||||||
lv2:port
|
lv2:port
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ A straighforward no-frills digital delay.
|
|||||||
""" ;
|
""" ;
|
||||||
|
|
||||||
mod:brand "TooB";
|
mod:brand "TooB";
|
||||||
mod:label "Delay";
|
mod:label "TooB Delay";
|
||||||
lv2:optionalFeature lv2:hardRTCapable;
|
lv2:optionalFeature lv2:hardRTCapable;
|
||||||
|
|
||||||
lv2:port
|
lv2:port
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ Emulation of a Boss BF-2 Flanger*.
|
|||||||
""" ;
|
""" ;
|
||||||
|
|
||||||
mod:brand "TooB";
|
mod:brand "TooB";
|
||||||
mod:label "BF-2 Flanger";
|
mod:label "TooB BF-2";
|
||||||
lv2:optionalFeature lv2:hardRTCapable;
|
lv2:optionalFeature lv2:hardRTCapable;
|
||||||
|
|
||||||
lv2:port
|
lv2:port
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ should use the monophonic version of this effect.
|
|||||||
""" ;
|
""" ;
|
||||||
|
|
||||||
mod:brand "TooB";
|
mod:brand "TooB";
|
||||||
mod:label "BF-2 Stereo Flanger";
|
mod:label "TooB BF-2 Stereo";
|
||||||
lv2:optionalFeature lv2:hardRTCapable;
|
lv2:optionalFeature lv2:hardRTCapable;
|
||||||
|
|
||||||
lv2:port
|
lv2:port
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ The core implementation is taken from the The Synthesis Toolkit in C++ (STK), ht
|
|||||||
""" ;
|
""" ;
|
||||||
|
|
||||||
mod:brand "TooB";
|
mod:brand "TooB";
|
||||||
mod:label "Freeverb";
|
mod:label "TooB Freeverb";
|
||||||
lv2:optionalFeature lv2:hardRTCapable;
|
lv2:optionalFeature lv2:hardRTCapable;
|
||||||
|
|
||||||
lv2:port
|
lv2:port
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ toobml:filterGroup
|
|||||||
|
|
||||||
<http://two-play.com/plugins/toob-ml>
|
<http://two-play.com/plugins/toob-ml>
|
||||||
a lv2:Plugin ,
|
a lv2:Plugin ,
|
||||||
lv2:SimulatorPlugin ;
|
lv2:AmplifierPlugin ;
|
||||||
doap:name "TooB ML Amplifier" ,
|
doap:name "TooB ML Amplifier" ,
|
||||||
"TooB ML Amplifier"@en-gb-gb
|
"TooB ML Amplifier"@en-gb-gb
|
||||||
;
|
;
|
||||||
@@ -63,7 +63,7 @@ and uses model files from from the GuitarML Neural Pi project (https://github.co
|
|||||||
""" ;
|
""" ;
|
||||||
|
|
||||||
mod:brand "TooB";
|
mod:brand "TooB";
|
||||||
mod:label "ML Amplifier";
|
mod:label "TooB ML";
|
||||||
lv2:requiredFeature urid:map, work:schedule ;
|
lv2:requiredFeature urid:map, work:schedule ;
|
||||||
lv2:optionalFeature lv2:hardRTCapable;
|
lv2:optionalFeature lv2:hardRTCapable;
|
||||||
lv2:extensionData state:interface, work:interface;
|
lv2:extensionData state:interface, work:interface;
|
||||||
|
|||||||
@@ -0,0 +1,310 @@
|
|||||||
|
@prefix doap: <http://usefulinc.com/ns/doap#> .
|
||||||
|
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
|
||||||
|
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
|
||||||
|
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
||||||
|
@prefix units: <http://lv2plug.in/ns/extensions/units#> .
|
||||||
|
@prefix urid: <http://lv2plug.in/ns/ext/urid#> .
|
||||||
|
@prefix atom: <http://lv2plug.in/ns/ext/atom#> .
|
||||||
|
@prefix midi: <http://lv2plug.in/ns/ext/midi#> .
|
||||||
|
@prefix epp: <http://lv2plug.in/ns/ext/port-props#> .
|
||||||
|
@prefix uiext: <http://lv2plug.in/ns/extensions/ui#> .
|
||||||
|
@prefix idpy: <http://harrisonconsoles.com/lv2/inlinedisplay#> .
|
||||||
|
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
|
||||||
|
@prefix mod: <http://moddevices.com/ns/mod#> .
|
||||||
|
@prefix param: <http://lv2plug.in/ns/ext/parameters#> .
|
||||||
|
@prefix work: <http://lv2plug.in/ns/ext/worker#> .
|
||||||
|
@prefix pg: <http://lv2plug.in/ns/ext/port-groups#> .
|
||||||
|
@prefix pipedal_ui: <http://github.com/rerdavies/pipedal/ui#> .
|
||||||
|
@prefix ui: <http://lv2plug.in/ns/extensions/ui#> .
|
||||||
|
|
||||||
|
@prefix atom: <http://lv2plug.in/ns/ext/atom#> .
|
||||||
|
@prefix patch: <http://lv2plug.in/ns/ext/patch#> .
|
||||||
|
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
||||||
|
@prefix state: <http://lv2plug.in/ns/ext/state#> .
|
||||||
|
@prefix urid: <http://lv2plug.in/ns/ext/urid#> .
|
||||||
|
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
||||||
|
@prefix toobNam: <http://two-play.com/plugins/toob-nam#> .
|
||||||
|
|
||||||
|
|
||||||
|
<http://two-play.com/rerdavies#me>
|
||||||
|
a foaf:Person ;
|
||||||
|
foaf:name "Robin Davies" ;
|
||||||
|
foaf:mbox <mailto:rerdavies@gmail.com> ;
|
||||||
|
foaf:homepage <https://github.com/sponsors/rerdavies> .
|
||||||
|
|
||||||
|
|
||||||
|
toobNam:modelFile
|
||||||
|
a lv2:Parameter;
|
||||||
|
rdfs:label "Model";
|
||||||
|
rdfs:range atom:Path.
|
||||||
|
|
||||||
|
toobNam:eqGroup
|
||||||
|
a param:ControlGroup ,
|
||||||
|
pg:InputGroup ;
|
||||||
|
lv2:name "Tone" ;
|
||||||
|
lv2:symbol "eqGroup" .
|
||||||
|
|
||||||
|
|
||||||
|
<http://two-play.com/plugins/toob-nam>
|
||||||
|
a lv2:Plugin ,
|
||||||
|
lv2:AmplifierPlugin ;
|
||||||
|
doap:name "TooB Neural Amp Modeler" ,
|
||||||
|
"TooB Neural Amp Modeler"@en-gb-gb
|
||||||
|
;
|
||||||
|
doap:license <https://two-play.com/TooB/licenses/isc> ;
|
||||||
|
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
||||||
|
lv2:minorVersion 0 ;
|
||||||
|
lv2:microVersion 16 ;
|
||||||
|
rdfs:comment """
|
||||||
|
A port of Steven Atkinson's Neural Amp Modeler to LV2.
|
||||||
|
|
||||||
|
TooB Neural Amp Modeler uses uplodable .nam model files. Download .nam files from http://tonehunt.org, and then upload them to TooB Neural Amp Modeler.
|
||||||
|
|
||||||
|
https://tonehunt.org provides a huge selection of downloadable amp model files.
|
||||||
|
|
||||||
|
TooB Neural Amp Modeler supports a much wider range of amp models than ToobML, but usually uses much more CPU.
|
||||||
|
You will need at least a Pi 4 to use Toob Neural Amp Modeler. If you are having trouble with CPU usage, tonehunt.org
|
||||||
|
does contain some smaller amp models. Search for the "feather" tag to find models that use less CPU.
|
||||||
|
|
||||||
|
If you are interested in building your own amp models, please visit https://www.neuralampmodeler.com/
|
||||||
|
|
||||||
|
TooB Neural Amp Modeler uses code from the NeuralAmp Modeler Core project. The TooB Team wishes to express gratitude to Steven Atkinson for
|
||||||
|
making this extraordinary technology available as open-source code.
|
||||||
|
|
||||||
|
Code from the the NeuralAmpModelerCore project (https://github.com/sdatkinson/NeuralAmpModelerCore) is provided under the following license.
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2023 Steven Atkinson
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
""" ;
|
||||||
|
|
||||||
|
mod:brand "TooB";
|
||||||
|
mod:label "TooB NAM";
|
||||||
|
lv2:optionalFeature lv2:hardRTCapable;
|
||||||
|
|
||||||
|
patch:readable
|
||||||
|
toobNam:modelFile;
|
||||||
|
patch:writable
|
||||||
|
toobNam:modelFile;
|
||||||
|
|
||||||
|
lv2:extensionData state:interface,
|
||||||
|
work:interface;
|
||||||
|
|
||||||
|
|
||||||
|
lv2:port
|
||||||
|
[
|
||||||
|
a lv2:InputPort ,
|
||||||
|
lv2:ControlPort ;
|
||||||
|
|
||||||
|
lv2:index 0;
|
||||||
|
lv2:symbol "inputGain" ;
|
||||||
|
lv2:name "Input Gain";
|
||||||
|
lv2:default 0.0 ;
|
||||||
|
lv2:minimum -20.0;
|
||||||
|
lv2:maximum 20.0;
|
||||||
|
units:unit units:db;
|
||||||
|
rdfs:comment "Input gain";
|
||||||
|
|
||||||
|
],
|
||||||
|
[
|
||||||
|
a lv2:InputPort ,
|
||||||
|
lv2:ControlPort ;
|
||||||
|
|
||||||
|
lv2:index 1;
|
||||||
|
lv2:symbol "outputGain" ;
|
||||||
|
lv2:name "Output Gain";
|
||||||
|
lv2:default 0.0 ;
|
||||||
|
lv2:minimum -40.0;
|
||||||
|
lv2:maximum 40.0;
|
||||||
|
units:unit units:db;
|
||||||
|
rdfs:comment "Output gain";
|
||||||
|
],
|
||||||
|
[
|
||||||
|
a lv2:InputPort ,
|
||||||
|
lv2:ControlPort ;
|
||||||
|
|
||||||
|
lv2:index 2;
|
||||||
|
lv2:symbol "gate" ;
|
||||||
|
lv2:name "Noise Gate";
|
||||||
|
lv2:default -80.0 ;
|
||||||
|
lv2:minimum -100.0;
|
||||||
|
lv2:maximum 0.0;
|
||||||
|
rdfs:comment "Noise gate threshold. Set to minimum to disable.";
|
||||||
|
units:unit units:db;
|
||||||
|
lv2:scalePoint [
|
||||||
|
rdfs:label "Off" ;
|
||||||
|
rdf:value -100.0
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
],
|
||||||
|
[
|
||||||
|
a lv2:OutputPort ,
|
||||||
|
lv2:ControlPort ;
|
||||||
|
|
||||||
|
lv2:index 3;
|
||||||
|
lv2:symbol "gateOut" ;
|
||||||
|
lv2:name "\u00A0";
|
||||||
|
lv2:default 0.0;
|
||||||
|
lv2:minimum 0.0;
|
||||||
|
lv2:maximum 1.0;
|
||||||
|
rdfs:comment "Gate Status";
|
||||||
|
lv2:portProperty lv2:toggled;
|
||||||
|
],
|
||||||
|
[
|
||||||
|
a lv2:InputPort ,
|
||||||
|
lv2:ControlPort ;
|
||||||
|
|
||||||
|
lv2:index 4;
|
||||||
|
lv2:symbol "bass" ;
|
||||||
|
lv2:name "Bass";
|
||||||
|
lv2:default 5.0;
|
||||||
|
lv2:minimum 0.0;
|
||||||
|
lv2:maximum 10.0;
|
||||||
|
rdfs:comment "Bass";
|
||||||
|
pg:group toobNam:eqGroup ;
|
||||||
|
|
||||||
|
],
|
||||||
|
[
|
||||||
|
a lv2:InputPort ,
|
||||||
|
lv2:ControlPort ;
|
||||||
|
|
||||||
|
lv2:index 5;
|
||||||
|
lv2:symbol "mid" ;
|
||||||
|
lv2:name "Mid";
|
||||||
|
lv2:default 5.0;
|
||||||
|
lv2:minimum 0.0;
|
||||||
|
lv2:maximum 10.0;
|
||||||
|
rdfs:comment "Mid";
|
||||||
|
pg:group toobNam:eqGroup ;
|
||||||
|
],
|
||||||
|
[
|
||||||
|
a lv2:InputPort ,
|
||||||
|
lv2:ControlPort ;
|
||||||
|
|
||||||
|
lv2:index 6;
|
||||||
|
lv2:symbol "treble" ;
|
||||||
|
lv2:name "Treble";
|
||||||
|
lv2:default 5.0;
|
||||||
|
lv2:minimum 0.0;
|
||||||
|
lv2:maximum 10.0;
|
||||||
|
rdfs:comment "Bass";
|
||||||
|
pg:group toobNam:eqGroup ;
|
||||||
|
],
|
||||||
|
[
|
||||||
|
a lv2:InputPort ,
|
||||||
|
lv2:ControlPort ;
|
||||||
|
|
||||||
|
lv2:index 7 ;
|
||||||
|
lv2:symbol "toneStack" ;
|
||||||
|
lv2:name "Type";
|
||||||
|
lv2:default 0.0 ;
|
||||||
|
lv2:minimum 2.0 ;
|
||||||
|
lv2:maximum 3.0;
|
||||||
|
lv2:portProperty lv2:enumeration ;
|
||||||
|
|
||||||
|
lv2:scalePoint [
|
||||||
|
rdfs:label "Bassman" ;
|
||||||
|
rdf:value 0.0
|
||||||
|
] , [
|
||||||
|
rdfs:label "JCM8000" ;
|
||||||
|
rdf:value 1.0
|
||||||
|
], [
|
||||||
|
rdfs:label "Baxandall" ;
|
||||||
|
rdf:value 2.0
|
||||||
|
],[
|
||||||
|
rdfs:label "Bypass" ;
|
||||||
|
rdf:value 3.0
|
||||||
|
];
|
||||||
|
pg:group toobNam:eqGroup ;
|
||||||
|
|
||||||
|
],
|
||||||
|
[
|
||||||
|
a lv2:AudioPort ,
|
||||||
|
lv2:InputPort ;
|
||||||
|
lv2:index 8 ;
|
||||||
|
lv2:symbol "in" ;
|
||||||
|
lv2:name "In"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
a lv2:AudioPort ,
|
||||||
|
lv2:OutputPort ;
|
||||||
|
lv2:index 9 ;
|
||||||
|
lv2:symbol "out" ;
|
||||||
|
lv2:name "Out"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
a atom:AtomPort ,
|
||||||
|
lv2:InputPort;
|
||||||
|
atom:bufferType atom:Sequence ;
|
||||||
|
atom:supports patch:Message;
|
||||||
|
lv2:designation lv2:control ;
|
||||||
|
atom:supports patch:Message ;
|
||||||
|
|
||||||
|
lv2:index 10 ;
|
||||||
|
lv2:symbol "control" ;
|
||||||
|
lv2:name "Control" ;
|
||||||
|
rdfs:comment "Control" ;
|
||||||
|
] , [
|
||||||
|
a atom:AtomPort ,
|
||||||
|
lv2:OutputPort ;
|
||||||
|
atom:bufferType atom:Sequence ;
|
||||||
|
atom:supports patch:Message;
|
||||||
|
lv2:designation lv2:control ;
|
||||||
|
lv2:index 11;
|
||||||
|
lv2:symbol "notify" ;
|
||||||
|
lv2:name "Notify" ;
|
||||||
|
rdfs:comment "Notification" ;
|
||||||
|
]
|
||||||
|
.
|
||||||
|
|
||||||
|
<http://two-play.com/plugins/toob-nam> pipedal_ui:ui toobNam:ui .
|
||||||
|
|
||||||
|
|
||||||
|
toobNam:ui
|
||||||
|
a pipedal_ui:ui ;
|
||||||
|
pipedal_ui:fileProperties
|
||||||
|
[
|
||||||
|
a pipedal_ui:fileProperty;
|
||||||
|
rdfs:label "Model (*.nam)" ;
|
||||||
|
pipedal_ui:directory "NeuralAmpModels";
|
||||||
|
lv2:index 8 ;
|
||||||
|
pipedal_ui:patchProperty toobNam:modelFile ;
|
||||||
|
pipedal_ui:fileTypes
|
||||||
|
[
|
||||||
|
a pipedal_ui:fileType;
|
||||||
|
rdfs:label ".nam file";
|
||||||
|
pipedal_ui:fileExtension ".nam";
|
||||||
|
pipedal_ui:mimeType "application/octet-stream";
|
||||||
|
];
|
||||||
|
];
|
||||||
|
pipedal_ui:frequencyPlot
|
||||||
|
[
|
||||||
|
pipedal_ui:patchProperty toobNam:FrequencyResponse;
|
||||||
|
lv2:index 7 ;
|
||||||
|
pg:group toobNam:eqGroup ;
|
||||||
|
|
||||||
|
pipedal_ui:width: 60;
|
||||||
|
]
|
||||||
|
|
||||||
|
.
|
||||||
|
|
||||||
@@ -12,6 +12,10 @@
|
|||||||
lv2:binary <ToobAmp.so> ;
|
lv2:binary <ToobAmp.so> ;
|
||||||
rdfs:seeAlso <ConvolutionReverb.ttl> .
|
rdfs:seeAlso <ConvolutionReverb.ttl> .
|
||||||
|
|
||||||
|
<http://two-play.com/plugins/toob-nam> a lv2:Plugin ;
|
||||||
|
lv2:binary <ToobAmp.so> ;
|
||||||
|
rdfs:seeAlso <ToobNeuralAmpModeler.ttl> .
|
||||||
|
|
||||||
<http://two-play.com/plugins/toob-convolution-reverb-stereo> a lv2:Plugin ;
|
<http://two-play.com/plugins/toob-convolution-reverb-stereo> a lv2:Plugin ;
|
||||||
lv2:binary <ToobAmp.so> ;
|
lv2:binary <ToobAmp.so> ;
|
||||||
rdfs:seeAlso <ConvolutionReverbStereo.ttl> .
|
rdfs:seeAlso <ConvolutionReverbStereo.ttl> .
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ add_custom_command(
|
|||||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/react
|
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/react
|
||||||
|
|
||||||
DEPENDS
|
DEPENDS
|
||||||
|
src/SelectThemeDialog.tsx
|
||||||
src/OkCancelDialog.tsx
|
src/OkCancelDialog.tsx
|
||||||
src/PluginControl.tsx
|
src/PluginControl.tsx
|
||||||
src/reportWebVitals.ts
|
src/reportWebVitals.ts
|
||||||
@@ -133,9 +134,9 @@ add_custom_command(
|
|||||||
public/img/fx_distortion.svg
|
public/img/fx_distortion.svg
|
||||||
public/img/Pi-Logo-3.png
|
public/img/Pi-Logo-3.png
|
||||||
public/img/fx_oscillator.svg
|
public/img/fx_oscillator.svg
|
||||||
public/img/save_bank_as_white.svg
|
src/svg/ic_save_bank_as.svg
|
||||||
public/img/edit_banks_white.svg
|
src/svg/ic_edit_banks.svg
|
||||||
public/img/settings_black_24dp.svg
|
src/svg/ic_settings.svg
|
||||||
public/img/fx_filter.svg
|
public/img/fx_filter.svg
|
||||||
public/img/delete_outline_black_24dp.svg
|
public/img/delete_outline_black_24dp.svg
|
||||||
public/img/fx_function.svg
|
public/img/fx_function.svg
|
||||||
@@ -150,7 +151,7 @@ add_custom_command(
|
|||||||
public/img/cc-by.png
|
public/img/cc-by.png
|
||||||
public/img/fx_split_a.svg
|
public/img/fx_split_a.svg
|
||||||
public/img/fx_utility.svg
|
public/img/fx_utility.svg
|
||||||
public/img/help_outline_white_24dp.svg
|
src/svg/ic_help_outline.svg
|
||||||
public/img/ic_navigate_before.svg
|
public/img/ic_navigate_before.svg
|
||||||
public/img/ic_drawer_2.svg
|
public/img/ic_drawer_2.svg
|
||||||
public/img/fx_parametric_eq.svg
|
public/img/fx_parametric_eq.svg
|
||||||
@@ -161,10 +162,8 @@ add_custom_command(
|
|||||||
public/img/fx_analyzer.svg
|
public/img/fx_analyzer.svg
|
||||||
public/img/fx_delay.svg
|
public/img/fx_delay.svg
|
||||||
public/img/fx_spectral.svg
|
public/img/fx_spectral.svg
|
||||||
public/img/edit_banks.svg
|
|
||||||
public/img/fx_chorus.svg
|
public/img/fx_chorus.svg
|
||||||
public/img/fx_simulator.svg
|
public/img/fx_simulator.svg
|
||||||
public/img/drive_file_rename_outline_black_24dp.svg
|
|
||||||
public/img/fx_mixer.svg
|
public/img/fx_mixer.svg
|
||||||
public/img/fx_eq.svg
|
public/img/fx_eq.svg
|
||||||
public/img/fx_modulator.svg
|
public/img/fx_modulator.svg
|
||||||
@@ -173,7 +172,6 @@ add_custom_command(
|
|||||||
public/img/fx_phaser.svg
|
public/img/fx_phaser.svg
|
||||||
public/img/ic_drawer.svg
|
public/img/ic_drawer.svg
|
||||||
public/img/fx_amplifier.svg
|
public/img/fx_amplifier.svg
|
||||||
public/img/save_bank_as.svg
|
|
||||||
public/img/fx_lr.svg
|
public/img/fx_lr.svg
|
||||||
public/img/fx_instrument.svg
|
public/img/fx_instrument.svg
|
||||||
public/img/Pi-Logo-3.svg
|
public/img/Pi-Logo-3.svg
|
||||||
@@ -183,14 +181,11 @@ add_custom_command(
|
|||||||
public/img/fx_empty.svg
|
public/img/fx_empty.svg
|
||||||
public/img/fx_dial.svg
|
public/img/fx_dial.svg
|
||||||
public/img/ic_logo.svg
|
public/img/ic_logo.svg
|
||||||
public/img/help_outline_black_24dp.svg
|
|
||||||
public/img/fx_flanger2.svg
|
public/img/fx_flanger2.svg
|
||||||
public/img/old_delete_outline_white_24dp.svg
|
public/img/old_delete_outline_white_24dp.svg
|
||||||
public/img/fx_split_b.svg
|
public/img/fx_split_b.svg
|
||||||
public/img/fx_spatial.svg
|
public/img/fx_spatial.svg
|
||||||
public/img/fx_converter.svg
|
public/img/fx_converter.svg
|
||||||
public/img/settings_white_24dp.svg
|
|
||||||
public/img/drive_file_rename_outline_white_24dp.svg
|
|
||||||
public/img/vst.svg
|
public/img/vst.svg
|
||||||
public/img/vst.png
|
public/img/vst.png
|
||||||
public/sample_lv2_plugins.json
|
public/sample_lv2_plugins.json
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><g><rect fill="none" height="24" width="24"/></g><g><g><polygon points="15,16 11,20 21,20 21,16"/><path d="M12.06,7.19L3,16.25V20h3.75l9.06-9.06L12.06,7.19z M5.92,18H5v-0.92l7.06-7.06l0.92,0.92L5.92,18z"/><path d="M18.71,8.04c0.39-0.39,0.39-1.02,0-1.41l-2.34-2.34C16.17,4.09,15.92,4,15.66,4c-0.25,0-0.51,0.1-0.7,0.29l-1.83,1.83 l3.75,3.75L18.71,8.04z"/></g></g></svg>
|
|
||||||
|
Before Width: | Height: | Size: 503 B |
@@ -1 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#FFFFFF"><g><rect fill="none" height="24" width="24"/></g><g><g><polygon points="15,16 11,20 21,20 21,16"/><path d="M12.06,7.19L3,16.25V20h3.75l9.06-9.06L12.06,7.19z M5.92,18H5v-0.92l7.06-7.06l0.92,0.92L5.92,18z"/><path d="M18.71,8.04c0.39-0.39,0.39-1.02,0-1.41l-2.34-2.34C16.17,4.09,15.92,4,15.66,4c-0.25,0-0.51,0.1-0.7,0.29l-1.83,1.83 l3.75,3.75L18.71,8.04z"/></g></g></svg>
|
|
||||||
|
Before Width: | Height: | Size: 503 B |
@@ -1 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#FFFFFF"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M11 18h2v-2h-2v2zm1-16C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm0-14c-2.21 0-4 1.79-4 4h2c0-1.1.9-2 2-2s2 .9 2 2c0 2-3 1.75-3 5h2c0-2.25 3-2.5 3-5 0-2.21-1.79-4-4-4z"/></svg>
|
|
||||||
|
Before Width: | Height: | Size: 402 B |
@@ -1,15 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve" fill="#FFFFFF">
|
|
||||||
<path d="M16,1H4C2.9,1,2,1.9,2,3v14h2V3h12V1z"/>
|
|
||||||
<path d="M20.993,10.993L20.99,7c0-1.1-0.891-2-1.99-2h-4h-3H8C6.9,5,6.01,5.9,6.01,7l-0.003,3.993L6,11v10c0,1.1,0.891,2,1.99,2H8
|
|
||||||
h11h0.01c1.1,0,1.99-0.9,1.99-2V11L20.993,10.993z M19,12v9H8v-9V7h5h1h5V12z"/>
|
|
||||||
<rect x="10" y="9" width="2" height="2"/>
|
|
||||||
<rect x="14" y="9" width="3" height="2"/>
|
|
||||||
<rect x="10" y="13" width="2" height="2"/>
|
|
||||||
<rect x="14" y="13" width="3" height="2"/>
|
|
||||||
<rect x="10" y="17" width="2" height="2"/>
|
|
||||||
<rect x="14" y="17" width="3" height="2"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1012 B |
@@ -1,26 +1,24 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
<head>
|
||||||
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
||||||
<meta name="theme-color" content="#000000" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<meta
|
<meta name="theme-color" content="#000000" />
|
||||||
name="description"
|
<meta name="description" content="PiPedal Guitar Pedals" />
|
||||||
content="PiPedal Guitar Pedals"
|
<!--
|
||||||
/>
|
|
||||||
<!--
|
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" />
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" />
|
||||||
-->
|
-->
|
||||||
<link rel="stylesheet" href="/css/roboto.css" />
|
<link rel="stylesheet" href="/css/roboto.css" />
|
||||||
|
|
||||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||||
<!--
|
<!--
|
||||||
manifest.json provides metadata used when your web app is installed on a
|
manifest.json provides metadata used when your web app is installed on a
|
||||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
||||||
-->
|
-->
|
||||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||||
<!--
|
<!--
|
||||||
Notice the use of %PUBLIC_URL% in the tags above.
|
Notice the use of %PUBLIC_URL% in the tags above.
|
||||||
It will be replaced with the URL of the `public` folder during the build.
|
It will be replaced with the URL of the `public` folder during the build.
|
||||||
Only files inside the `public` folder can be referenced from the HTML.
|
Only files inside the `public` folder can be referenced from the HTML.
|
||||||
@@ -29,14 +27,30 @@
|
|||||||
work correctly both with client-side routing and a non-root public URL.
|
work correctly both with client-side routing and a non-root public URL.
|
||||||
Learn how to configure a non-root public URL by running `npm run build`.
|
Learn how to configure a non-root public URL by running `npm run build`.
|
||||||
-->
|
-->
|
||||||
<title>PiPedal</title>
|
<title>PiPedal</title>
|
||||||
<style>
|
<style>
|
||||||
BODY { background: #D0D0D0; }
|
BODY {
|
||||||
@media (prefers-color-scheme: dark) {
|
background: #D0D0D0;
|
||||||
BODY { background: #333; }
|
}
|
||||||
}
|
</style>
|
||||||
|
|
||||||
</style>
|
<style id="bgStyle">
|
||||||
|
BODY {
|
||||||
|
background: #333;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
const darkMode = localStorage.getItem("darkMode"); if (darkMode) { }
|
||||||
|
if (darkMode)
|
||||||
|
{
|
||||||
|
let bgStyle = document.getElementById("bgStyle");
|
||||||
|
if (bgStyle)
|
||||||
|
{
|
||||||
|
// disable the style block.
|
||||||
|
bgStyle.setAttribute('media',"max-width: 1px");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body >
|
<body >
|
||||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
@@ -52,4 +66,4 @@
|
|||||||
To create a production bundle, use `npm run build` or `yarn build`.
|
To create a production bundle, use `npm run build` or `yarn build`.
|
||||||
-->
|
-->
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -25,10 +25,12 @@ import isDarkMode from './DarkMode';
|
|||||||
|
|
||||||
declare module '@mui/material/styles' {
|
declare module '@mui/material/styles' {
|
||||||
interface Theme {
|
interface Theme {
|
||||||
mainBackground: string;
|
mainBackground: React.CSSProperties['color'];
|
||||||
|
toolbarColor: React.CSSProperties['color'];
|
||||||
}
|
}
|
||||||
interface ThemeOptions {
|
interface ThemeOptions {
|
||||||
mainBackground?: string;
|
mainBackground?: React.CSSProperties['color'];
|
||||||
|
toolbarColor?: React.CSSProperties['color'];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -50,13 +52,14 @@ const theme = createTheme(
|
|||||||
palette: {
|
palette: {
|
||||||
mode: 'dark',
|
mode: 'dark',
|
||||||
primary: {
|
primary: {
|
||||||
main: "#6750A4" // #5B5690 #60529A #5C5694
|
main: '#A770E4'// #6750A4" // #5B5690 #60529A #5C5694
|
||||||
},
|
},
|
||||||
secondary: {
|
secondary: {
|
||||||
main: "#FF6060"
|
main: "#FF6060"
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mainBackground: "#222"
|
mainBackground: "#222",
|
||||||
|
toolbarColor: '#FFFFFF'
|
||||||
}
|
}
|
||||||
:
|
:
|
||||||
{
|
{
|
||||||
@@ -69,7 +72,9 @@ const theme = createTheme(
|
|||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
mainBackground: "#FFFFFF"
|
mainBackground: "#FFFFFF",
|
||||||
|
toolbarColor: '#FFFFFF'
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -16,8 +16,3 @@ div {
|
|||||||
min-width: 0;
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
|
||||||
:root {
|
|
||||||
color-scheme: dark;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -62,14 +62,27 @@ import JackStatusView from './JackStatusView';
|
|||||||
import { Theme } from '@mui/material/styles';
|
import { Theme } from '@mui/material/styles';
|
||||||
import isDarkMode from './DarkMode';
|
import isDarkMode from './DarkMode';
|
||||||
|
|
||||||
|
import {ReactComponent as RenameOutlineIcon} from './svg/drive_file_rename_outline_black_24dp.svg';
|
||||||
|
import {ReactComponent as SaveBankAsIcon} from './svg/ic_save_bank_as.svg';
|
||||||
|
import {ReactComponent as EditBanksIcon} from './svg/ic_edit_banks.svg';
|
||||||
|
import {ReactComponent as SettingsIcon} from './svg/ic_settings.svg';
|
||||||
|
import {ReactComponent as HelpOutlineIcon} from './svg/ic_help_outline.svg';
|
||||||
|
|
||||||
|
|
||||||
const appStyles = (theme: Theme) => createStyles({
|
const appStyles = (theme: Theme) => createStyles({
|
||||||
menuIcon: {
|
"&": { // :root
|
||||||
fill: "green"
|
colorScheme: (isDarkMode()? "dark": "light")
|
||||||
},
|
},
|
||||||
appBar: {
|
menuListItem: {
|
||||||
|
color: "#FE8!important" as any, //theme.palette.text.primary,
|
||||||
|
fill: "#FE8!important" as any, //theme.palette.text.primary,
|
||||||
|
},
|
||||||
|
menuIcon: {
|
||||||
|
fill: (theme.palette.text.primary + "!important") as any, //theme.palette.text.primary,
|
||||||
|
opacity: 0.6
|
||||||
|
},
|
||||||
|
toolBar: {
|
||||||
|
color: "white"
|
||||||
},
|
},
|
||||||
listSubheader: {
|
listSubheader: {
|
||||||
backgroundImage: "linear-gradient(255,255,255,0.15),rgba(255,255,255,0.15)"
|
backgroundImage: "linear-gradient(255,255,255,0.15),rgba(255,255,255,0.15)"
|
||||||
@@ -499,7 +512,7 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
|||||||
|
|
||||||
private unmountListener(e: Event) {
|
private unmountListener(e: Event) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (this.model_.state.get() === State.Ready && !this.model_.isAndroidHosted()) {
|
if ((!this.model_.reloadRequested) && this.model_.state.get() === State.Ready && !this.model_.isAndroidHosted()) {
|
||||||
(e as any).returnValue = "Are you sure you want to leave this page?";
|
(e as any).returnValue = "Are you sure you want to leave this page?";
|
||||||
return "Are you sure you want to leave this page?";
|
return "Are you sure you want to leave this page?";
|
||||||
}
|
}
|
||||||
@@ -652,6 +665,7 @@ render() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{
|
<div style={{
|
||||||
|
colorScheme: isDarkMode() ? "dark": "light", // affects scrollbar color
|
||||||
minHeight: 345, minWidth: 390,
|
minHeight: 345, minWidth: 390,
|
||||||
position: "absolute", width: "100%", height: "100%", background: "#F88", userSelect: "none",
|
position: "absolute", width: "100%", height: "100%", background: "#F88", userSelect: "none",
|
||||||
display: "flex", flexDirection: "column", flexWrap: "nowrap",
|
display: "flex", flexDirection: "column", flexWrap: "nowrap",
|
||||||
@@ -666,14 +680,15 @@ render() {
|
|||||||
<CssBaseline />
|
<CssBaseline />
|
||||||
{(!this.state.tinyToolBar) ?
|
{(!this.state.tinyToolBar) ?
|
||||||
(
|
(
|
||||||
<AppBar className="appBar" position="absolute" >
|
<AppBar position="absolute" >
|
||||||
<Toolbar variant="dense" >
|
<Toolbar variant="dense" className={classes.toolBar} >
|
||||||
<IconButton
|
<IconButton
|
||||||
edge="start"
|
edge="start"
|
||||||
aria-label="menu"
|
aria-label="menu"
|
||||||
|
color="inherit"
|
||||||
onClick={() => { this.showDrawer() }}
|
onClick={() => { this.showDrawer() }}
|
||||||
size="large">
|
size="large">
|
||||||
<MenuButton />
|
<MenuButton style={{opacity: 0.75}} />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<div style={{ flex: "0 1 400px", minWidth: 100 }}>
|
<div style={{ flex: "0 1 400px", minWidth: 100 }}>
|
||||||
<PresetSelector />
|
<PresetSelector />
|
||||||
@@ -683,11 +698,12 @@ render() {
|
|||||||
<IconButton
|
<IconButton
|
||||||
aria-label="menu"
|
aria-label="menu"
|
||||||
onClick={() => { this.toggleFullScreen(); }}
|
onClick={() => { this.toggleFullScreen(); }}
|
||||||
|
color="inherit"
|
||||||
size="large">
|
size="large">
|
||||||
{this.state.isFullScreen ? (
|
{this.state.isFullScreen ? (
|
||||||
<FullscreenExitIcon />
|
<FullscreenExitIcon style={{opacity: 0.75}} />
|
||||||
) : (
|
) : (
|
||||||
<FullscreenIcon />
|
<FullscreenIcon style={{opacity: 0.75}} />
|
||||||
|
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -701,6 +717,7 @@ render() {
|
|||||||
style={{ position: "absolute", left: 12, top: 8, zIndex: 2 }}
|
style={{ position: "absolute", left: 12, top: 8, zIndex: 2 }}
|
||||||
aria-label="menu"
|
aria-label="menu"
|
||||||
onClick={() => { this.showDrawer() }}
|
onClick={() => { this.showDrawer() }}
|
||||||
|
color="inherit"
|
||||||
size="large">
|
size="large">
|
||||||
<MenuButton />
|
<MenuButton />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
@@ -708,6 +725,7 @@ render() {
|
|||||||
<IconButton
|
<IconButton
|
||||||
style={{ position: "absolute", right: 8, top: 8, zIndex: 2 }}
|
style={{ position: "absolute", right: 8, top: 8, zIndex: 2 }}
|
||||||
aria-label="menu"
|
aria-label="menu"
|
||||||
|
color="inherit"
|
||||||
onClick={() => { this.toggleFullScreen(); }}
|
onClick={() => { this.toggleFullScreen(); }}
|
||||||
size="large">
|
size="large">
|
||||||
{this.state.isFullScreen ? (
|
{this.state.isFullScreen ? (
|
||||||
@@ -756,26 +774,20 @@ render() {
|
|||||||
<Divider />
|
<Divider />
|
||||||
<List>
|
<List>
|
||||||
<ListItem button key='RenameBank' onClick={() => { this.handleDrawerRenameBank() }}>
|
<ListItem button key='RenameBank' onClick={() => { this.handleDrawerRenameBank() }}>
|
||||||
<ListItemIcon>
|
<ListItemIcon >
|
||||||
<img className='menuIcon'
|
<RenameOutlineIcon color='inherit' className={classes.menuIcon} />
|
||||||
src={isDarkMode()? "img/drive_file_rename_outline_white_24dp.svg" :"img/drive_file_rename_outline_black_24dp.svg"}
|
|
||||||
alt="" style={{ opacity: 0.6 }} />
|
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText primary='Rename Bank' />
|
<ListItemText primary='Rename Bank' />
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem button key='SaveBank' onClick={() => { this.handleDrawerSaveBankAs() }} >
|
<ListItem button key='SaveBank' onClick={() => { this.handleDrawerSaveBankAs() }} >
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<img className='menuIcon'
|
<SaveBankAsIcon color="inherit" className={classes.menuIcon}/>
|
||||||
src={isDarkMode()? "img/save_bank_as_white.svg" :"img/save_bank_as.svg"}
|
|
||||||
alt="" style={{ opacity: 0.6 }} />
|
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText primary='Save As New Bank' />
|
<ListItemText primary='Save As New Bank' />
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem button key='CreateBank' onClick={() => { this.handleDrawerManageBanks(); }}>
|
<ListItem button key='EditBanks' onClick={() => { this.handleDrawerManageBanks(); }}>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<img className='menuIcon'
|
<EditBanksIcon color="inherit" className={classes.menuIcon}/>
|
||||||
src={isDarkMode()? "img/edit_banks_white.svg" :"img/edit_banks.svg"}
|
|
||||||
alt="" style={{ opacity: 0.6 }} />
|
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText primary='Manage Banks...' />
|
<ListItemText primary='Manage Banks...' />
|
||||||
</ListItem>
|
</ListItem>
|
||||||
@@ -784,23 +796,19 @@ render() {
|
|||||||
<List>
|
<List>
|
||||||
<ListItem button key='Settings' onClick={() => { this.handleDrawerSettingsClick() }}>
|
<ListItem button key='Settings' onClick={() => { this.handleDrawerSettingsClick() }}>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<img className='menuIcon'
|
<SettingsIcon color="inherit" className={classes.menuIcon}/>
|
||||||
src={isDarkMode()? "img/settings_white_24dp.svg" :"img/settings_black_24dp.svg"}
|
|
||||||
alt="" style={{ opacity: 0.6 }} />
|
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText primary='Settings' />
|
<ListItemText primary='Settings' />
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem button key='About' onClick={() => { this.handleDrawerAboutClick() }}>
|
<ListItem button key='About' onClick={() => { this.handleDrawerAboutClick() }}>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<img className='menuIcon'
|
<HelpOutlineIcon color="inherit" className={classes.menuIcon}/>
|
||||||
src= {isDarkMode() ? "img/help_outline_white_24dp.svg": "img/help_outline_black_24dp.svg"}
|
|
||||||
alt="" style={{ opacity: 0.6 }} />
|
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText primary='About' />
|
<ListItemText primary='About' />
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem button key='Donations' onClick={() => { this.handleDrawerDonationClick() }}>
|
<ListItem button key='Donations' onClick={() => { this.handleDrawerDonationClick() }}>
|
||||||
<ListItemIcon>
|
<ListItemIcon >
|
||||||
<VolunteerActivismIcon style={{ opacity: 0.6 }}/>
|
<VolunteerActivismIcon className={classes.menuIcon} color="inherit" />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText primary='Donations' />
|
<ListItemText primary='Donations' />
|
||||||
</ListItem>
|
</ListItem>
|
||||||
|
|||||||
@@ -19,8 +19,10 @@
|
|||||||
|
|
||||||
|
|
||||||
export default function isDarkMode(): boolean {
|
export default function isDarkMode(): boolean {
|
||||||
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
let value = localStorage.getItem("darkMode");
|
||||||
return true;
|
return value === "true";
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
|
export function setDarkMode(value: boolean): void {
|
||||||
|
localStorage.setItem("darkMode",value? "true": "false");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -602,7 +602,7 @@ export const LoadPluginDialog =
|
|||||||
<SelectHoverBackground selected={value.uri === this.state.selected_uri} showHover={true} />
|
<SelectHoverBackground selected={value.uri === this.state.selected_uri} showHover={true} />
|
||||||
<div className={classes.content}>
|
<div className={classes.content}>
|
||||||
<div className={classes.iconBorder} >
|
<div className={classes.iconBorder} >
|
||||||
<PluginIcon pluginType={value.plugin_type} size={24} />
|
<PluginIcon pluginType={value.plugin_type} size={24} opacity={0.6} />
|
||||||
</div>
|
</div>
|
||||||
<div className={classes.content2}>
|
<div className={classes.content2}>
|
||||||
<div className={classes.label} style={{ display: "flex", flexFlow: "row nowrap", alignItems: "center" }} >
|
<div className={classes.label} style={{ display: "flex", flexFlow: "row nowrap", alignItems: "center" }} >
|
||||||
|
|||||||
@@ -204,6 +204,42 @@ export class UiPropertyNotification {
|
|||||||
plugin: string = "";
|
plugin: string = "";
|
||||||
protocol: string = "";
|
protocol: string = "";
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
export class UiFrequencyPlot {
|
||||||
|
deserialize(input: any): UiFrequencyPlot
|
||||||
|
{
|
||||||
|
this.patchProperty = input.patchProperty;
|
||||||
|
this.index = input.index;
|
||||||
|
this.portGroup = input.portGroup;
|
||||||
|
this.xLeft = input.xLeft;
|
||||||
|
this.xRight = input.xRight;
|
||||||
|
this.xLog = input.xLog;
|
||||||
|
this.yTop = input.yTop;
|
||||||
|
this.yBottom = input.yBottom;
|
||||||
|
this.width = input.width;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
static deserialize_array(input: any): UiFrequencyPlot[]
|
||||||
|
{
|
||||||
|
let result: UiFrequencyPlot[] = [];
|
||||||
|
for (let i = 0; i < input.length; ++i)
|
||||||
|
{
|
||||||
|
result[i] = new UiFrequencyPlot().deserialize(input[i]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
patchProperty: string = "";
|
||||||
|
index: number = -1;
|
||||||
|
portGroup: string = "";
|
||||||
|
xLeft: number = -1;
|
||||||
|
xRight: number = -1;
|
||||||
|
xLog: boolean = true;
|
||||||
|
yTop: number = -1;
|
||||||
|
yBottom: number = -1;
|
||||||
|
width: number = -1;
|
||||||
|
|
||||||
};
|
};
|
||||||
export class UiFileProperty {
|
export class UiFileProperty {
|
||||||
deserialize(input: any): UiFileProperty
|
deserialize(input: any): UiFileProperty
|
||||||
@@ -253,6 +289,10 @@ export class UiFileProperty {
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (fileType.fileExtension === "*" || fileType.fileExtension === "")
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -270,6 +310,8 @@ export class Lv2Plugin implements Deserializable<Lv2Plugin> {
|
|||||||
{
|
{
|
||||||
this.uri = input.uri;
|
this.uri = input.uri;
|
||||||
this.name = input.name;
|
this.name = input.name;
|
||||||
|
this.brand = input.name? input.name: "";
|
||||||
|
this.label = input.label? input.label: this.name;
|
||||||
this.plugin_class = input.plugin_class;
|
this.plugin_class = input.plugin_class;
|
||||||
this.supported_features = input.supported_features;
|
this.supported_features = input.supported_features;
|
||||||
this.required_features = input.required_features;
|
this.required_features = input.required_features;
|
||||||
@@ -285,6 +327,13 @@ export class Lv2Plugin implements Deserializable<Lv2Plugin> {
|
|||||||
} else {
|
} else {
|
||||||
this.fileProperties = [];
|
this.fileProperties = [];
|
||||||
}
|
}
|
||||||
|
if (input.frequencyPlots)
|
||||||
|
{
|
||||||
|
this.frequencyPlots = UiFrequencyPlot.deserialize_array(input.frequencyPlots)
|
||||||
|
} else {
|
||||||
|
this.frequencyPlots = [];
|
||||||
|
}
|
||||||
|
|
||||||
if (input.uiPortNotifications)
|
if (input.uiPortNotifications)
|
||||||
{
|
{
|
||||||
this.uiPortNotifications = UiPropertyNotification.deserialize_array(input.uiPortNotifications);
|
this.uiPortNotifications = UiPropertyNotification.deserialize_array(input.uiPortNotifications);
|
||||||
@@ -297,6 +346,8 @@ export class Lv2Plugin implements Deserializable<Lv2Plugin> {
|
|||||||
|
|
||||||
uri: string = "";
|
uri: string = "";
|
||||||
name: string = "";
|
name: string = "";
|
||||||
|
brand: string = "";
|
||||||
|
label: string = "";
|
||||||
plugin_class: string = "";
|
plugin_class: string = "";
|
||||||
supported_features: string[] = Lv2Plugin.EmptyFeatures;
|
supported_features: string[] = Lv2Plugin.EmptyFeatures;
|
||||||
required_features: string[] = Lv2Plugin.EmptyFeatures;
|
required_features: string[] = Lv2Plugin.EmptyFeatures;
|
||||||
@@ -306,7 +357,8 @@ export class Lv2Plugin implements Deserializable<Lv2Plugin> {
|
|||||||
comment: string = "";
|
comment: string = "";
|
||||||
ports: Port[] = Port.EmptyPorts;
|
ports: Port[] = Port.EmptyPorts;
|
||||||
port_groups: PortGroup[] = [];
|
port_groups: PortGroup[] = [];
|
||||||
fileProperties: UiFileProperty[] = [];
|
fileProperties: UiFileProperty[] = [];
|
||||||
|
frequencyPlots: UiFrequencyPlot[] = [];
|
||||||
uiPortNotifications: UiPropertyNotification[] = [];
|
uiPortNotifications: UiPropertyNotification[] = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -668,6 +720,8 @@ export class UiPlugin implements Deserializable<UiPlugin> {
|
|||||||
{
|
{
|
||||||
this.uri = input.uri;
|
this.uri = input.uri;
|
||||||
this.name = input.name;
|
this.name = input.name;
|
||||||
|
this.brand = input.brand ? input.brand: "";
|
||||||
|
this.label = input.label? input.label: this.name;
|
||||||
this.plugin_type = input.plugin_type as PluginType;
|
this.plugin_type = input.plugin_type as PluginType;
|
||||||
this.plugin_display_type = input.plugin_display_type;
|
this.plugin_display_type = input.plugin_display_type;
|
||||||
this.author_name = input.author_name;
|
this.author_name = input.author_name;
|
||||||
@@ -685,6 +739,12 @@ export class UiPlugin implements Deserializable<UiPlugin> {
|
|||||||
} else {
|
} else {
|
||||||
this.fileProperties = [];
|
this.fileProperties = [];
|
||||||
}
|
}
|
||||||
|
if (input.frequencyPlots)
|
||||||
|
{
|
||||||
|
this.frequencyPlots = UiFrequencyPlot.deserialize_array(input.frequencyPlots)
|
||||||
|
} else {
|
||||||
|
this.frequencyPlots = [];
|
||||||
|
}
|
||||||
|
|
||||||
this.is_vst3 = input.is_vst3;
|
this.is_vst3 = input.is_vst3;
|
||||||
return this;
|
return this;
|
||||||
@@ -738,6 +798,8 @@ export class UiPlugin implements Deserializable<UiPlugin> {
|
|||||||
|
|
||||||
uri: string = "";
|
uri: string = "";
|
||||||
name: string = "";
|
name: string = "";
|
||||||
|
brand: string = "";
|
||||||
|
label: string = "";
|
||||||
plugin_type: PluginType = PluginType.InvalidPlugin;
|
plugin_type: PluginType = PluginType.InvalidPlugin;
|
||||||
plugin_display_type: string = "";
|
plugin_display_type: string = "";
|
||||||
author_name: string = "";
|
author_name: string = "";
|
||||||
@@ -749,7 +811,8 @@ export class UiPlugin implements Deserializable<UiPlugin> {
|
|||||||
description: string = "";
|
description: string = "";
|
||||||
controls: UiControl[] = [];
|
controls: UiControl[] = [];
|
||||||
port_groups: PortGroup[] = [];
|
port_groups: PortGroup[] = [];
|
||||||
fileProperties: UiFileProperty[] = [];
|
fileProperties: UiFileProperty[] = [];
|
||||||
|
frequencyPlots: UiFrequencyPlot[] = [];
|
||||||
is_vst3 : boolean = false;
|
is_vst3 : boolean = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ import MidiBindingsDialog from './MidiBindingsDialog';
|
|||||||
import PluginPresetSelector from './PluginPresetSelector';
|
import PluginPresetSelector from './PluginPresetSelector';
|
||||||
import {ReactComponent as OldDeleteIcon} from "./svg/old_delete_outline_24dp.svg";
|
import {ReactComponent as OldDeleteIcon} from "./svg/old_delete_outline_24dp.svg";
|
||||||
import {ReactComponent as MidiIcon} from "./svg/ic_midi.svg";
|
import {ReactComponent as MidiIcon} from "./svg/ic_midi.svg";
|
||||||
|
import isDarkMode from './DarkMode';
|
||||||
|
|
||||||
|
|
||||||
const SPLIT_CONTROLBAR_THRESHHOLD = 650;
|
const SPLIT_CONTROLBAR_THRESHHOLD = 650;
|
||||||
@@ -463,7 +463,7 @@ export const MainPage =
|
|||||||
</div>
|
</div>
|
||||||
<div style={{ flex: "0 0 auto", display: (canInsert || canAppend) ? "block" : "none", paddingRight: 8 }}>
|
<div style={{ flex: "0 0 auto", display: (canInsert || canAppend) ? "block" : "none", paddingRight: 8 }}>
|
||||||
<IconButton onClick={(e) => { this.onAddClick(e) }} size="large">
|
<IconButton onClick={(e) => { this.onAddClick(e) }} size="large">
|
||||||
<AddIcon style={{opacity: 0.6}} />
|
<AddIcon style={{height: 24, width: 24,fill: this.props.theme.palette.text.primary, opacity: 0.6}} />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<Menu
|
<Menu
|
||||||
id="add-menu"
|
id="add-menu"
|
||||||
@@ -495,7 +495,8 @@ export const MainPage =
|
|||||||
onClick={this.onLoadClick}
|
onClick={this.onLoadClick}
|
||||||
disabled={this.state.selectedPedal === -1 || (!canLoad) || (this.getSelectedPedalboardItem()?.isSplit() ?? true)}
|
disabled={this.state.selectedPedal === -1 || (!canLoad) || (this.getSelectedPedalboardItem()?.isSplit() ?? true)}
|
||||||
startIcon={<InputIcon />}
|
startIcon={<InputIcon />}
|
||||||
style={{ textTransform: "none" }}
|
style={{ textTransform: "none",
|
||||||
|
background: (isDarkMode() ? "#6750A4": undefined) }}
|
||||||
>
|
>
|
||||||
Load
|
Load
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -298,7 +298,7 @@ class PedalLayout {
|
|||||||
if (uiPlugin != null) {
|
if (uiPlugin != null) {
|
||||||
this.pluginType = uiPlugin.plugin_type;
|
this.pluginType = uiPlugin.plugin_type;
|
||||||
this.iconUrl = SelectIconUri(uiPlugin.plugin_type);
|
this.iconUrl = SelectIconUri(uiPlugin.plugin_type);
|
||||||
this.name = uiPlugin.name;
|
this.name = uiPlugin.label;
|
||||||
this.numberOfInputs = Math.max(uiPlugin.audio_inputs,2);
|
this.numberOfInputs = Math.max(uiPlugin.audio_inputs,2);
|
||||||
this.numberOfOutputs = Math.max(uiPlugin.audio_outputs,2);
|
this.numberOfOutputs = Math.max(uiPlugin.audio_outputs,2);
|
||||||
} else {
|
} else {
|
||||||
@@ -679,7 +679,7 @@ const PedalboardView =
|
|||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
if (!Utility.isTouchDevice()) {
|
if (!Utility.needsZoomedControls()) {
|
||||||
if (this.props.onDoubleClick && instanceId) {
|
if (this.props.onDoubleClick && instanceId) {
|
||||||
this.props.onDoubleClick(instanceId);
|
this.props.onDoubleClick(instanceId);
|
||||||
}
|
}
|
||||||
@@ -1014,7 +1014,7 @@ const PedalboardView =
|
|||||||
}}>
|
}}>
|
||||||
<Typography variant="caption" display="block" noWrap={true}
|
<Typography variant="caption" display="block" noWrap={true}
|
||||||
style={{ width: CELL_WIDTH - 4, textAlign: "center", flex: "0 1 auto" }}
|
style={{ width: CELL_WIDTH - 4, textAlign: "center", flex: "0 1 auto" }}
|
||||||
>{item.pedalItem?.pluginName}</Typography>
|
>{item.name}</Typography>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
result.push(<div key={this.renderKey++} className={classes.pedalItem} style={{ left: item.bounds.x, top: item.bounds.y }} >
|
result.push(<div key={this.renderKey++} className={classes.pedalItem} style={{ left: item.bounds.x, top: item.bounds.y }} >
|
||||||
|
|||||||
@@ -38,7 +38,12 @@ import GovernorSettings from './GovernorSettings';
|
|||||||
import WifiChannel from './WifiChannel';
|
import WifiChannel from './WifiChannel';
|
||||||
import AlsaDeviceInfo from './AlsaDeviceInfo';
|
import AlsaDeviceInfo from './AlsaDeviceInfo';
|
||||||
import { AndroidHostInterface, FakeAndroidHost } from './AndroidHost';
|
import { AndroidHostInterface, FakeAndroidHost } from './AndroidHost';
|
||||||
|
import isDarkMode, {setDarkMode} from './DarkMode';
|
||||||
|
|
||||||
|
export enum ColorTheme {
|
||||||
|
Light,
|
||||||
|
Dark
|
||||||
|
};
|
||||||
|
|
||||||
export enum State {
|
export enum State {
|
||||||
Loading,
|
Loading,
|
||||||
@@ -470,8 +475,11 @@ export class PiPedalModel //implements PiPedalModel
|
|||||||
let value = body as number;
|
let value = body as number;
|
||||||
this._setInputVolume(value,false);
|
this._setInputVolume(value,false);
|
||||||
} else if (message === "onLv2StateChanged") {
|
} else if (message === "onLv2StateChanged") {
|
||||||
let instanceId = body as number;
|
|
||||||
this.onLv2StateChanged(instanceId);
|
let instanceId = body.instanceId as number;
|
||||||
|
let state = body.state as [boolean,any];
|
||||||
|
|
||||||
|
this.onLv2StateChanged(instanceId,state);
|
||||||
} else if (message === "onVst3ControlChanged") {
|
} else if (message === "onVst3ControlChanged") {
|
||||||
let controlChangedBody = body as Vst3ControlChangedBody;
|
let controlChangedBody = body as Vst3ControlChangedBody;
|
||||||
this._setVst3PedalboardControlValue(
|
this._setVst3PedalboardControlValue(
|
||||||
@@ -665,6 +673,10 @@ export class PiPedalModel //implements PiPedalModel
|
|||||||
this.getWebSocket().request<number>("hello")
|
this.getWebSocket().request<number>("hello")
|
||||||
.then(clientId => {
|
.then(clientId => {
|
||||||
this.clientId = clientId;
|
this.clientId = clientId;
|
||||||
|
return this.getWebSocket().request<any>("plugins");
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
this.ui_plugins.set(UiPlugin.deserialize_array(data));
|
||||||
return this.getWebSocket().request<Pedalboard>("currentPedalboard");
|
return this.getWebSocket().request<Pedalboard>("currentPedalboard");
|
||||||
})
|
})
|
||||||
.then(data => {
|
.then(data => {
|
||||||
@@ -1116,7 +1128,9 @@ export class PiPedalModel //implements PiPedalModel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private onLv2StateChanged(instanceId: number): void {
|
private onLv2StateChanged(instanceId: number, state: [boolean,any]): void {
|
||||||
|
let item = this.pedalboard.get().getItem(instanceId);
|
||||||
|
item.lv2State = state;
|
||||||
for (let item of this.stateChangedListeners) {
|
for (let item of this.stateChangedListeners) {
|
||||||
if (item.instanceId === instanceId) {
|
if (item.instanceId === instanceId) {
|
||||||
item.onStateChanged(instanceId);
|
item.onStateChanged(instanceId);
|
||||||
@@ -2531,6 +2545,27 @@ export class PiPedalModel //implements PiPedalModel
|
|||||||
return nullCast(this.webSocket).request<number>("newPreset");
|
return nullCast(this.webSocket).request<number>("newPreset");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getTheme(): ColorTheme {
|
||||||
|
return isDarkMode() ? ColorTheme.Dark: ColorTheme.Light;
|
||||||
|
}
|
||||||
|
|
||||||
|
setTheme(value: ColorTheme) {
|
||||||
|
if (this.getTheme() !== value)
|
||||||
|
{
|
||||||
|
setDarkMode(value === ColorTheme.Dark);
|
||||||
|
this.reloadPage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reloadRequested: boolean = false;
|
||||||
|
|
||||||
|
reloadPage() {
|
||||||
|
this.reloadRequested = true;
|
||||||
|
// eslint-disable-next-line no-restricted-globals
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let instance: PiPedalModel | undefined = undefined;
|
let instance: PiPedalModel | undefined = undefined;
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ const PluginControl =
|
|||||||
this.onInputKeyPress = this.onInputKeyPress.bind(this);
|
this.onInputKeyPress = this.onInputKeyPress.bind(this);
|
||||||
}
|
}
|
||||||
isTouchDevice(): boolean {
|
isTouchDevice(): boolean {
|
||||||
return Utility.isTouchDevice();
|
return Utility.needsZoomedControls();
|
||||||
}
|
}
|
||||||
|
|
||||||
showZoomedControl()
|
showZoomedControl()
|
||||||
@@ -547,7 +547,7 @@ const PluginControl =
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<Select variant="standard"
|
<Select variant="standard"
|
||||||
ref={this.selectRef}
|
ref={this.selectRef}
|
||||||
value={control.clampSelectValue(value)}
|
value={control.clampSelectValue(value)}
|
||||||
onChange={this.onSelectChanged}
|
onChange={this.onSelectChanged}
|
||||||
@@ -556,7 +556,7 @@ const PluginControl =
|
|||||||
id: 'id' + control.symbol,
|
id: 'id' + control.symbol,
|
||||||
style: { fontSize: FONT_SIZE }
|
style: { fontSize: FONT_SIZE }
|
||||||
}}
|
}}
|
||||||
style={{ marginLeft: 4, marginRight: 4, width: 140 }}
|
style={{ marginLeft: 4, marginRight: 4, width: 140,fontSize: 14 }}
|
||||||
>
|
>
|
||||||
{control.scale_points.map((scale_point: ScalePoint) => (
|
{control.scale_points.map((scale_point: ScalePoint) => (
|
||||||
<MenuItem key={scale_point.value} value={scale_point.value}>{scale_point.label}</MenuItem>
|
<MenuItem key={scale_point.value} value={scale_point.value}>{scale_point.label}</MenuItem>
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import { WithStyles } from '@mui/styles';
|
|||||||
import createStyles from '@mui/styles/createStyles';
|
import createStyles from '@mui/styles/createStyles';
|
||||||
import withStyles from '@mui/styles/withStyles';
|
import withStyles from '@mui/styles/withStyles';
|
||||||
import { PiPedalModel, PiPedalModelFactory } from './PiPedalModel';
|
import { PiPedalModel, PiPedalModelFactory } from './PiPedalModel';
|
||||||
import { UiPlugin, UiControl, UiFileProperty, ScalePoint } from './Lv2Plugin';
|
import { UiPlugin, UiControl, UiFileProperty,UiFrequencyPlot, ScalePoint } from './Lv2Plugin';
|
||||||
import {
|
import {
|
||||||
Pedalboard, PedalboardItem, ControlValue
|
Pedalboard, PedalboardItem, ControlValue
|
||||||
} from './Pedalboard';
|
} from './Pedalboard';
|
||||||
@@ -39,6 +39,7 @@ import FilePropertyDialog from './FilePropertyDialog';
|
|||||||
import JsonAtom from './JsonAtom';
|
import JsonAtom from './JsonAtom';
|
||||||
import PluginOutputControl from './PluginOutputControl';
|
import PluginOutputControl from './PluginOutputControl';
|
||||||
import Units from './Units';
|
import Units from './Units';
|
||||||
|
import ToobFrequencyResponseView from './ToobFrequencyResponseView';
|
||||||
|
|
||||||
|
|
||||||
export const StandardItemSize = { width: 80, height: 110 };
|
export const StandardItemSize = { width: 80, height: 110 };
|
||||||
@@ -335,6 +336,14 @@ const PluginControlView =
|
|||||||
/>
|
/>
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
makeFrequencyPlotUI(frequencyPlot: UiFrequencyPlot): ReactNode {
|
||||||
|
return ((
|
||||||
|
<ToobFrequencyResponseView instanceId={this.props.instanceId}
|
||||||
|
propertyName={frequencyPlot.patchProperty}
|
||||||
|
width={frequencyPlot.width}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
}
|
||||||
makeStandardControl(uiControl: UiControl, controlValues: ControlValue[]): ReactNode {
|
makeStandardControl(uiControl: UiControl, controlValues: ControlValue[]): ReactNode {
|
||||||
let symbol = uiControl.symbol;
|
let symbol = uiControl.symbol;
|
||||||
if (!uiControl.is_input) {
|
if (!uiControl.is_input) {
|
||||||
@@ -445,6 +454,48 @@ const PluginControlView =
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (let i = 0; i < plugin.frequencyPlots.length; ++i) {
|
||||||
|
let frequencyPlot = plugin.frequencyPlots[i];
|
||||||
|
let frequencyPlotUi = this.makeFrequencyPlotUI(frequencyPlot);
|
||||||
|
|
||||||
|
if (frequencyPlot.portGroup !== "" && plugin.getPortGroupByUri(frequencyPlot.portGroup)) {
|
||||||
|
let portGroup = nullCast(plugin.getPortGroupByUri(frequencyPlot.portGroup));
|
||||||
|
let controlGroup = portGroupMap[portGroup.symbol];
|
||||||
|
if (controlGroup) {
|
||||||
|
let insertPosition = controlGroup.indexes.length;
|
||||||
|
if (frequencyPlot.index !== -1) {
|
||||||
|
for (let i = 0; i < controlGroup.controls.length; ++i) {
|
||||||
|
if (controlGroup.indexes[i] >= frequencyPlot.index) {
|
||||||
|
insertPosition = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let index = frequencyPlot.index !== -1 ? frequencyPlot.index : 100;
|
||||||
|
controlGroup.controls.splice(insertPosition, 0, frequencyPlotUi);
|
||||||
|
controlGroup.indexes.splice(insertPosition, 0, index);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
let index = frequencyPlot.index !== -1 ? frequencyPlot.index : 100;
|
||||||
|
let controlGroup = new ControlGroup(
|
||||||
|
portGroup.name,
|
||||||
|
[index],
|
||||||
|
[frequencyPlotUi]);
|
||||||
|
result.push(
|
||||||
|
controlGroup
|
||||||
|
);
|
||||||
|
portGroupMap[portGroup.symbol] = controlGroup;
|
||||||
|
|
||||||
|
}
|
||||||
|
} else if (frequencyPlot.index !== -1) {
|
||||||
|
result.splice(frequencyPlot.index, 0, frequencyPlotUi);
|
||||||
|
} else {
|
||||||
|
result.push(
|
||||||
|
frequencyPlotUi
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,10 @@ const styles = (theme: Theme) =>
|
|||||||
top: theme.spacing(1),
|
top: theme.spacing(1),
|
||||||
color: theme.palette.grey[500],
|
color: theme.palette.grey[500],
|
||||||
},
|
},
|
||||||
|
icon: {
|
||||||
|
fill: theme.palette.text.primary,
|
||||||
|
opacity: 0.6
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
export interface PluginInfoDialogTitleProps extends WithStyles<typeof styles> {
|
export interface PluginInfoDialogTitleProps extends WithStyles<typeof styles> {
|
||||||
@@ -228,7 +232,7 @@ const PluginInfoDialog = withStyles(styles)((props: PluginInfoProps) => {
|
|||||||
style={{ display: (props.plugin_uri !== "") ? "inline-flex" : "none" }}
|
style={{ display: (props.plugin_uri !== "") ? "inline-flex" : "none" }}
|
||||||
onClick={handleClickOpen}
|
onClick={handleClickOpen}
|
||||||
size="large">
|
size="large">
|
||||||
<InfoOutlinedIcon style={{opacity: 0.6}} />
|
<InfoOutlinedIcon className={classes.icon} color='inherit' />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
{open && (
|
{open && (
|
||||||
<Dialog onClose={handleClose} open={open} fullWidth >
|
<Dialog onClose={handleClose} open={open} fullWidth >
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import withStyles from '@mui/styles/withStyles';
|
|||||||
import { UiControl } from './Lv2Plugin';
|
import { UiControl } from './Lv2Plugin';
|
||||||
import Typography from '@mui/material/Typography';
|
import Typography from '@mui/material/Typography';
|
||||||
import { PiPedalModel, PiPedalModelFactory, MonitorPortHandle,State } from './PiPedalModel';
|
import { PiPedalModel, PiPedalModelFactory, MonitorPortHandle,State } from './PiPedalModel';
|
||||||
|
import isDarkMode from './DarkMode';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -77,11 +78,13 @@ const PluginOutputControl =
|
|||||||
|
|
||||||
private model: PiPedalModel;
|
private model: PiPedalModel;
|
||||||
private vuRef: React.RefObject<HTMLDivElement>;
|
private vuRef: React.RefObject<HTMLDivElement>;
|
||||||
|
private lampRef: React.RefObject<HTMLDivElement>;
|
||||||
|
|
||||||
|
|
||||||
constructor(props: PluginOutputControlProps) {
|
constructor(props: PluginOutputControlProps) {
|
||||||
super(props);
|
super(props);
|
||||||
this.vuRef = React.createRef<HTMLDivElement>();
|
this.vuRef = React.createRef<HTMLDivElement>();
|
||||||
|
this.lampRef = React.createRef<HTMLDivElement>();
|
||||||
this.state = {
|
this.state = {
|
||||||
hasValue: false,
|
hasValue: false,
|
||||||
value: 0
|
value: 0
|
||||||
@@ -130,6 +133,12 @@ const PluginOutputControl =
|
|||||||
private animationHandle: number | undefined = undefined;
|
private animationHandle: number | undefined = undefined;
|
||||||
|
|
||||||
private updateValue(value: number) {
|
private updateValue(value: number) {
|
||||||
|
if (this.lampRef.current)
|
||||||
|
{
|
||||||
|
let control = this.props.uiControl;
|
||||||
|
let range = (value-control.min_value)/(control.max_value-control.min_value);
|
||||||
|
this.lampRef.current.style.opacity = range +"";
|
||||||
|
}
|
||||||
if (this.vuRef.current) {
|
if (this.vuRef.current) {
|
||||||
let control = this.props.uiControl;
|
let control = this.props.uiControl;
|
||||||
let range = (value-control.min_value)/(control.max_value-control.min_value);
|
let range = (value-control.min_value)/(control.max_value-control.min_value);
|
||||||
@@ -241,6 +250,38 @@ const PluginOutputControl =
|
|||||||
</div >
|
</div >
|
||||||
|
|
||||||
);
|
);
|
||||||
|
} else if (control.toggled_property && control.scale_points.length === 0) {
|
||||||
|
item_width = undefined;
|
||||||
|
let attachedLamp = control.name === "" || control.name === "\u00A0" ;
|
||||||
|
return (
|
||||||
|
<div style={{ display: "flex", flexDirection: "column", width: item_width,
|
||||||
|
marginTop: 8, marginBottom: 8, marginRight: 8,marginLeft: (attachedLamp? 0: 8), height: 98
|
||||||
|
}}>
|
||||||
|
{/* TITLE SECTION */}
|
||||||
|
<div style={{ flex: "0 0 auto", width: "100%", marginBottom: 8, marginLeft: 0, marginRight: 0 }}>
|
||||||
|
<Typography variant="caption" display="block" style={{
|
||||||
|
width: "100%",
|
||||||
|
textAlign: "center"
|
||||||
|
}}> {control.name === "" ? "\u00A0": control.name}</Typography>
|
||||||
|
</div>
|
||||||
|
{/* CONTROL SECTION */}
|
||||||
|
|
||||||
|
<div style={{ flex: "1 1 auto", display: "flex", justifyContent: "left", alignItems: "start", flexFlow: "row nowrap" }}>
|
||||||
|
<div style={{ width: 12, height: 12, background: isDarkMode()? "#111" : "#444", borderRadius: 5, position: "relative" }}>
|
||||||
|
<div ref={this.lampRef} style={{ width: 8, height: 8,
|
||||||
|
background: (isDarkMode()? "radial-gradient(circle at center, #F00 0, #F00 20%, #333 100%)"
|
||||||
|
: "radial-gradient(circle at center, #F44 0, #F44 40%, #644 100%)"),
|
||||||
|
opacity: 0, borderRadius: 3,margin: 2,position: "absolute" }} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* LABEL/EDIT SECTION*, strictly a placeholder for visual alignment purposes.*/}
|
||||||
|
<div style={{ flex: "0 0 auto", position: "relative", width: 30, height: 27 }}>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div >
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<div style={{ display: "flex", flexDirection: "column", width: item_width, margin: 8, height: 98 }}>
|
<div style={{ display: "flex", flexDirection: "column", width: item_width, margin: 8, height: 98 }}>
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ interface PresetSelectorState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const selectColor = isDarkMode()? "#888": "black";
|
const selectColor = isDarkMode()? "#888": "#FFFFFF";
|
||||||
|
|
||||||
const styles = (theme: Theme) => createStyles({
|
const styles = (theme: Theme) => createStyles({
|
||||||
select: { // fu fu fu.Overrides for white selector on dark background.
|
select: { // fu fu fu.Overrides for white selector on dark background.
|
||||||
@@ -301,17 +301,17 @@ const PresetSelector =
|
|||||||
}}>
|
}}>
|
||||||
<div style={{ flex: "0 0 auto" }}>
|
<div style={{ flex: "0 0 auto" }}>
|
||||||
<IconButton
|
<IconButton
|
||||||
style={{ flex: "0 0 auto", opacity: this.state.presets.presetChanged ? 1.0 : 0.0 }}
|
style={{ flex: "0 0 auto", opacity: this.state.presets.presetChanged ? 1.0 : 0.0, color: "#FFFFFF" }}
|
||||||
onClick={(e) => { this.handleSave(); }}
|
onClick={(e) => { this.handleSave(); }}
|
||||||
size="large">
|
size="large">
|
||||||
<SaveIconOutline style={{ opacity: 0.75 }} />
|
<SaveIconOutline style={{ opacity: 0.75 }} color="inherit" />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style={{ flex: "1 1 auto", minWidth: 60, maxWidth: 300, position: "relative", paddingRight: 12 }} >
|
<div style={{ flex: "1 1 auto", minWidth: 60, maxWidth: 300, position: "relative", paddingRight: 12 }} >
|
||||||
<Select variant="standard"
|
<Select variant="standard"
|
||||||
className={classes.select}
|
className={classes.select}
|
||||||
style={{ width: "100%", position: "relative", top: 0 }} disabled={!this.state.enabled}
|
style={{ width: "100%", position: "relative", top: 0, color: "#FFFFFF" }} disabled={!this.state.enabled}
|
||||||
onChange={(e, extra) => this.handleChange(e, extra)}
|
onChange={(e, extra) => this.handleChange(e, extra)}
|
||||||
onClose={(e) => this.handleSelectClose(e)}
|
onClose={(e) => this.handleSelectClose(e)}
|
||||||
displayEmpty
|
displayEmpty
|
||||||
@@ -336,12 +336,13 @@ const PresetSelector =
|
|||||||
}
|
}
|
||||||
</Select>
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ flex: "0 0 auto" }}>
|
<div style={{ flex: "0 0 auto"}}>
|
||||||
<IconButton
|
<IconButton
|
||||||
style={{ flex: "0 0 auto" }}
|
style={{ flex: "0 0 auto", color: "#FFFFFF" }}
|
||||||
onClick={(e) => this.handlePresetMenuClick(e)}
|
onClick={(e) => this.handlePresetMenuClick(e)}
|
||||||
size="large">
|
size="large"
|
||||||
<MoreVertIcon style={{ opacity: 0.75 }} />
|
>
|
||||||
|
<MoreVertIcon style={{ opacity: 0.75 }} color="inherit" />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<Menu
|
<Menu
|
||||||
id="edit-presets-menu"
|
id="edit-presets-menu"
|
||||||
|
|||||||
@@ -0,0 +1,85 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||||
|
// Copyright (c) 2023 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 { useState } from 'react';
|
||||||
|
import Button from '@mui/material/Button';
|
||||||
|
import DialogTitle from '@mui/material/DialogTitle';
|
||||||
|
import DialogContent from '@mui/material/DialogContent';
|
||||||
|
import DialogActions from '@mui/material/DialogActions';
|
||||||
|
import Dialog from '@mui/material/Dialog';
|
||||||
|
import FormControlLabel from '@mui/material/FormControlLabel';
|
||||||
|
import FormControl from '@mui/material/FormControl';
|
||||||
|
|
||||||
|
import RadioGroup from '@mui/material/RadioGroup';
|
||||||
|
import Radio from '@mui/material/Radio';
|
||||||
|
import {ColorTheme} from './PiPedalModel';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export interface SelectThemesDialogProps {
|
||||||
|
open: boolean;
|
||||||
|
defaultTheme: ColorTheme;
|
||||||
|
onClose: () => void;
|
||||||
|
onOk: (value: ColorTheme) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
function SelectThemesDialog(props: SelectThemesDialogProps) {
|
||||||
|
//const classes = useStyles();
|
||||||
|
const { onClose, defaultTheme, open,onOk } = props;
|
||||||
|
const [ selectedTheme, setSelectedTheme ] = useState(defaultTheme);
|
||||||
|
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
let value = ((event.target as HTMLInputElement).value) === '0' ? ColorTheme.Light: ColorTheme.Dark;
|
||||||
|
setSelectedTheme(value);
|
||||||
|
};
|
||||||
|
const handleClose = (): void => {
|
||||||
|
onClose();
|
||||||
|
};
|
||||||
|
const handleOk = (): void => {
|
||||||
|
onOk(selectedTheme)
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog onClose={handleClose} open={open}>
|
||||||
|
<DialogTitle id="simple-dialog-title">Theme</DialogTitle>
|
||||||
|
<DialogContent>
|
||||||
|
<FormControl>
|
||||||
|
<RadioGroup
|
||||||
|
defaultValue={defaultTheme}
|
||||||
|
onChange={handleChange}
|
||||||
|
>
|
||||||
|
<FormControlLabel value={ColorTheme.Light} control={<Radio size='small' />} label="Light" />
|
||||||
|
<FormControlLabel value={ColorTheme.Dark} control={<Radio size='small' />} label="Dark" />
|
||||||
|
</RadioGroup>
|
||||||
|
</FormControl>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button onClick={handleClose} color="primary">
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
<Button onClick={handleOk} color="secondary" >
|
||||||
|
OK
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SelectThemesDialog;
|
||||||
@@ -23,7 +23,7 @@ import OkCancelDialog from './OkCancelDialog';
|
|||||||
import ListSelectDialog from './ListSelectDialog';
|
import ListSelectDialog from './ListSelectDialog';
|
||||||
import IconButton from '@mui/material/IconButton';
|
import IconButton from '@mui/material/IconButton';
|
||||||
import Typography from '@mui/material/Typography';
|
import Typography from '@mui/material/Typography';
|
||||||
import { PiPedalModel, PiPedalModelFactory, State } from './PiPedalModel';
|
import { PiPedalModel, PiPedalModelFactory, State, ColorTheme } from './PiPedalModel';
|
||||||
import ButtonBase from "@mui/material/ButtonBase";
|
import ButtonBase from "@mui/material/ButtonBase";
|
||||||
import AppBar from '@mui/material/AppBar';
|
import AppBar from '@mui/material/AppBar';
|
||||||
import Button from '@mui/material/Button';
|
import Button from '@mui/material/Button';
|
||||||
@@ -45,6 +45,7 @@ import DialogEx from './DialogEx'
|
|||||||
import GovernorSettings from './GovernorSettings';
|
import GovernorSettings from './GovernorSettings';
|
||||||
import { AlsaMidiDeviceInfo } from './AlsaMidiDeviceInfo';
|
import { AlsaMidiDeviceInfo } from './AlsaMidiDeviceInfo';
|
||||||
import SystemMidiBindingsDialog from './SystemMidiBindingsDialog';
|
import SystemMidiBindingsDialog from './SystemMidiBindingsDialog';
|
||||||
|
import SelectThemeDialog from './SelectThemeDialog';
|
||||||
|
|
||||||
import Slide, { SlideProps } from '@mui/material/Slide';
|
import Slide, { SlideProps } from '@mui/material/Slide';
|
||||||
import { createStyles, Theme } from '@mui/material/styles';
|
import { createStyles, Theme } from '@mui/material/styles';
|
||||||
@@ -79,6 +80,7 @@ interface SettingsDialogState {
|
|||||||
showInputSelectDialog: boolean;
|
showInputSelectDialog: boolean;
|
||||||
showOutputSelectDialog: boolean;
|
showOutputSelectDialog: boolean;
|
||||||
showMidiSelectDialog: boolean;
|
showMidiSelectDialog: boolean;
|
||||||
|
showThemeSelectDialog: boolean;
|
||||||
showJackServerSettingsDialog: boolean;
|
showJackServerSettingsDialog: boolean;
|
||||||
shuttingDown: boolean;
|
shuttingDown: boolean;
|
||||||
restarting: boolean;
|
restarting: boolean;
|
||||||
@@ -184,6 +186,7 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
|
|||||||
showInputSelectDialog: false,
|
showInputSelectDialog: false,
|
||||||
showOutputSelectDialog: false,
|
showOutputSelectDialog: false,
|
||||||
showMidiSelectDialog: false,
|
showMidiSelectDialog: false,
|
||||||
|
showThemeSelectDialog: false,
|
||||||
showJackServerSettingsDialog: false,
|
showJackServerSettingsDialog: false,
|
||||||
shuttingDown: false,
|
shuttingDown: false,
|
||||||
restarting: false,
|
restarting: false,
|
||||||
@@ -384,6 +387,11 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
|
|||||||
showMidiSelectDialog: true
|
showMidiSelectDialog: true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
handleThemeSelection() {
|
||||||
|
this.setState({
|
||||||
|
showThemeSelectDialog: true
|
||||||
|
});
|
||||||
|
}
|
||||||
handleMidiMessageSettings() {
|
handleMidiMessageSettings() {
|
||||||
this.setState({
|
this.setState({
|
||||||
showSystemMidiBindingsDialog: true
|
showSystemMidiBindingsDialog: true
|
||||||
@@ -553,22 +561,22 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div >
|
<div >
|
||||||
{this.props.onboarding &&
|
{this.props.onboarding &&
|
||||||
(
|
(
|
||||||
<div>
|
<div>
|
||||||
<Typography display="block" variant="body1" color="textSecondary" style={{paddingLeft: 24,paddingBottom: 8 }}>
|
<Typography display="block" variant="body1" color="textSecondary" style={{ paddingLeft: 24, paddingBottom: 8 }}>
|
||||||
Select and configure an audio device. You may optionally configure MIDI inputs, and set up a Wi-Fi Direct Hotspot now as well.
|
Select and configure an audio device. You may optionally configure MIDI inputs, and set up a Wi-Fi Direct Hotspot now as well.
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography display="block" variant="body1" color="textSecondary" style={{paddingLeft: 24,paddingBottom: 8 }}>
|
<Typography display="block" variant="body1" color="textSecondary" style={{ paddingLeft: 24, paddingBottom: 8 }}>
|
||||||
Access and modify these settings later by selecting the <i>Settings</i> menu item on the main menu.
|
Access and modify these settings later by selecting the <i>Settings</i> menu item on the main menu.
|
||||||
</Typography>
|
</Typography>
|
||||||
<Divider />
|
<Divider />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<Typography className={classes.sectionHead} display="block" variant="caption" color="secondary">
|
<Typography className={classes.sectionHead} display="block" variant="caption" color="secondary">
|
||||||
STATUS
|
STATUS
|
||||||
</Typography>
|
</Typography>
|
||||||
{(!isConfigValid) ?
|
{(!isConfigValid) ?
|
||||||
(
|
(
|
||||||
@@ -582,7 +590,7 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
|
|||||||
(
|
(
|
||||||
<div className={classes.cpuStatusColor} style={{ paddingLeft: 48, position: "relative", top: -12 }}>
|
<div className={classes.cpuStatusColor} style={{ paddingLeft: 48, position: "relative", top: -12 }}>
|
||||||
{JackHostStatus.getDisplayView("", this.state.jackStatus)}
|
{JackHostStatus.getDisplayView("", this.state.jackStatus)}
|
||||||
{ (!this.props.onboarding) && JackHostStatus.getCpuInfo("Governor:\u00A0", this.state.jackStatus)}
|
{(!this.props.onboarding) && JackHostStatus.getCpuInfo("Governor:\u00A0", this.state.jackStatus)}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -657,7 +665,7 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
|
|||||||
<SelectHoverBackground selected={false} showHover={true} />
|
<SelectHoverBackground selected={false} showHover={true} />
|
||||||
<div style={{ width: "100%" }}>
|
<div style={{ width: "100%" }}>
|
||||||
<Typography className={classes.primaryItem} display="block" variant="body2" noWrap>System MIDI Bindings</Typography>
|
<Typography className={classes.primaryItem} display="block" variant="body2" noWrap>System MIDI Bindings</Typography>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</ButtonBase>
|
</ButtonBase>
|
||||||
|
|
||||||
@@ -713,7 +721,7 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
|
|||||||
</div>
|
</div>
|
||||||
</ButtonBase>
|
</ButtonBase>
|
||||||
</div>
|
</div>
|
||||||
{ (!this.props.onboarding) ? (
|
{(!this.props.onboarding) ? (
|
||||||
<div >
|
<div >
|
||||||
<Divider />
|
<Divider />
|
||||||
<Typography className={classes.sectionHead} display="block" variant="caption" color="secondary">SYSTEM</Typography>
|
<Typography className={classes.sectionHead} display="block" variant="caption" color="secondary">SYSTEM</Typography>
|
||||||
@@ -735,7 +743,23 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
|
|||||||
|
|
||||||
<ButtonBase
|
<ButtonBase
|
||||||
className={classes.setting}
|
className={classes.setting}
|
||||||
onClick={() => { this.setState({ showStatusMonitorDialog: true }); }} >
|
onClick={() => { this.handleThemeSelection(); }} >
|
||||||
|
<SelectHoverBackground selected={false} showHover={true} />
|
||||||
|
<div style={{ width: "100%" }}>
|
||||||
|
<Typography className={classes.primaryItem} display="block" variant="body2" color="textPrimary" noWrap>
|
||||||
|
Color Theme</Typography>
|
||||||
|
<Typography className={classes.secondaryItem} display="block" variant="caption" color="textSecondary" noWrap>
|
||||||
|
{ this.model.getTheme() === ColorTheme.Dark ? "Dark" :"Light"}
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
</ButtonBase>
|
||||||
|
|
||||||
|
|
||||||
|
<ButtonBase
|
||||||
|
className={classes.setting}
|
||||||
|
onClick={() => {
|
||||||
|
this.model.setShowStatusMonitor(!this.state.showStatusMonitor)
|
||||||
|
}} >
|
||||||
<SelectHoverBackground selected={false} showHover={true} />
|
<SelectHoverBackground selected={false} showHover={true} />
|
||||||
<div style={{ width: "100%" }}>
|
<div style={{ width: "100%" }}>
|
||||||
<div style={{
|
<div style={{
|
||||||
@@ -746,6 +770,7 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
|
|||||||
<Typography className={classes.primaryItem} display="block" variant="body2" color="textPrimary" noWrap>
|
<Typography className={classes.primaryItem} display="block" variant="body2" color="textPrimary" noWrap>
|
||||||
Show status monitor on main screen.</Typography>
|
Show status monitor on main screen.</Typography>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style={{ flex: "0 0 auto" }}>
|
<div style={{ flex: "0 0 auto" }}>
|
||||||
<Switch
|
<Switch
|
||||||
checked={this.state.showStatusMonitor}
|
checked={this.state.showStatusMonitor}
|
||||||
@@ -787,16 +812,18 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
|
|||||||
</div >
|
</div >
|
||||||
</ButtonBase>
|
</ButtonBase>
|
||||||
</div>
|
</div>
|
||||||
): (
|
) : (
|
||||||
<div>
|
<div>
|
||||||
<Divider/>
|
<Divider />
|
||||||
<div style={{display: "grid", placeContent: "end", maxWidth: 550, marginLeft: 16,marginRight: 16,
|
<div style={{
|
||||||
marginTop: 16,marginBottom: 16}}>
|
display: "grid", placeContent: "end", maxWidth: 550, marginLeft: 16, marginRight: 16,
|
||||||
<Button variant="outlined" onClick={()=> {this.onOnboardingContinue()}} disabled={this.state.continueDisabled} style={{width: 120}}>Continue</Button>
|
marginTop: 16, marginBottom: 16
|
||||||
|
}}>
|
||||||
|
<Button variant="outlined" onClick={() => { this.onOnboardingContinue() }} disabled={this.state.continueDisabled} style={{ width: 120 }}>Continue</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -849,6 +876,20 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
|
|||||||
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
(this.state.showThemeSelectDialog) &&
|
||||||
|
(
|
||||||
|
<SelectThemeDialog open={this.state.showThemeSelectDialog}
|
||||||
|
onClose={()=> { this.setState({showThemeSelectDialog: false});} }
|
||||||
|
onOk={(selectedTheme: ColorTheme) => {
|
||||||
|
this.model.setTheme(selectedTheme);
|
||||||
|
this.setState({showThemeSelectDialog: false});
|
||||||
|
}}
|
||||||
|
defaultTheme={this.model.getTheme()}
|
||||||
|
/>
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
<WifiConfigDialog wifiConfigSettings={this.state.wifiConfigSettings} open={this.state.showWifiConfigDialog}
|
<WifiConfigDialog wifiConfigSettings={this.state.wifiConfigSettings} open={this.state.showWifiConfigDialog}
|
||||||
onClose={() => this.setState({ showWifiConfigDialog: false })}
|
onClose={() => this.setState({ showWifiConfigDialog: false })}
|
||||||
onOk={(wifiConfigSettings) => this.handleApplyWifiConfig(wifiConfigSettings)}
|
onOk={(wifiConfigSettings) => this.handleApplyWifiConfig(wifiConfigSettings)}
|
||||||
@@ -869,8 +910,8 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
|
|||||||
/>
|
/>
|
||||||
<SystemMidiBindingsDialog
|
<SystemMidiBindingsDialog
|
||||||
open={this.state.showSystemMidiBindingsDialog}
|
open={this.state.showSystemMidiBindingsDialog}
|
||||||
onClose={()=> { this.setState({showSystemMidiBindingsDialog: false});}}
|
onClose={() => { this.setState({ showSystemMidiBindingsDialog: false }); }}
|
||||||
/>
|
/>
|
||||||
</DialogEx >
|
</DialogEx >
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -25,11 +25,11 @@ import createStyles from '@mui/styles/createStyles';
|
|||||||
import withStyles from '@mui/styles/withStyles';
|
import withStyles from '@mui/styles/withStyles';
|
||||||
|
|
||||||
import { PiPedalModelFactory, PiPedalModel, State } from "./PiPedalModel";
|
import { PiPedalModelFactory, PiPedalModel, State } from "./PiPedalModel";
|
||||||
import { StandardItemSize } from './PluginControlView';
|
|
||||||
import Utility from './Utility';
|
import Utility from './Utility';
|
||||||
import SvgPathBuilder from './SvgPathBuilder';
|
import SvgPathBuilder from './SvgPathBuilder';
|
||||||
|
|
||||||
|
|
||||||
|
const StandardItemSize = { width: 80, height: 110 };
|
||||||
|
|
||||||
const FREQUENCY_RESPONSE_VECTOR_URI = "http://two-play.com/plugins/toob#frequencyResponseVector";
|
const FREQUENCY_RESPONSE_VECTOR_URI = "http://two-play.com/plugins/toob#frequencyResponseVector";
|
||||||
|
|
||||||
@@ -47,13 +47,15 @@ const styles = (theme: Theme) => createStyles({
|
|||||||
|
|
||||||
interface ToobFrequencyResponseProps extends WithStyles<typeof styles> {
|
interface ToobFrequencyResponseProps extends WithStyles<typeof styles> {
|
||||||
instanceId: number;
|
instanceId: number;
|
||||||
maxDb?: number;
|
propertyName?: string;
|
||||||
minDb?: number;
|
width?: number;
|
||||||
minFrequency?: number;
|
|
||||||
maxFrequency?: number;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
interface ToobFrequencyResponseState {
|
interface ToobFrequencyResponseState {
|
||||||
|
minDb: number;
|
||||||
|
maxDb: number;
|
||||||
|
minF: number;
|
||||||
|
maxF: number;
|
||||||
path: string;
|
path: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,7 +72,11 @@ const ToobFrequencyResponseView =
|
|||||||
super(props);
|
super(props);
|
||||||
this.model = PiPedalModelFactory.getInstance();
|
this.model = PiPedalModelFactory.getInstance();
|
||||||
this.state = {
|
this.state = {
|
||||||
path: ""
|
path: "",
|
||||||
|
minDb: -30,
|
||||||
|
maxDb: 5,
|
||||||
|
minF: 30,
|
||||||
|
maxF: 20000
|
||||||
};
|
};
|
||||||
|
|
||||||
this.pathRef = React.createRef();
|
this.pathRef = React.createRef();
|
||||||
@@ -146,24 +152,61 @@ const ToobFrequencyResponseView =
|
|||||||
onFrequencyResponseUpdated(data: number[]) {
|
onFrequencyResponseUpdated(data: number[]) {
|
||||||
if (!this.mounted) return;
|
if (!this.mounted) return;
|
||||||
let pathBuilder = new SvgPathBuilder();
|
let pathBuilder = new SvgPathBuilder();
|
||||||
|
|
||||||
|
let minF = data[0];
|
||||||
|
let maxF = data[1];
|
||||||
|
let dbMin = data[2];
|
||||||
|
let dbMax = data[3];
|
||||||
|
let logMin = Math.log(minF);
|
||||||
|
let logMax = Math.log(maxF);
|
||||||
|
|
||||||
|
let toX_ = (frequency: number): number => {
|
||||||
|
var logV = Math.log(frequency);
|
||||||
|
return (this.xMax - this.xMin) * (logV - logMin) / (logMax - logMin) + this.xMin;
|
||||||
|
|
||||||
|
};
|
||||||
|
let toY_ = (value: number): number => {
|
||||||
|
|
||||||
|
var db;
|
||||||
|
if (value < this.MIN_DB_AF) {
|
||||||
|
db = -192.0;
|
||||||
|
} else {
|
||||||
|
db = 20 * Math.log10(value);
|
||||||
|
}
|
||||||
|
var y = (db - dbMin) / (dbMax - dbMin) * (this.yMax - this.yMin) + this.yMin;
|
||||||
|
return y;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (data.length > 2) {
|
if (data.length > 2) {
|
||||||
pathBuilder.moveTo(this.toX(data[0]), this.toY(data[1]))
|
pathBuilder.moveTo(toX_(data[4]), toY_(data[5]))
|
||||||
for (let i = 2; i < data.length; i += 2) {
|
for (let i = 6; i < data.length; i += 2) {
|
||||||
pathBuilder.lineTo(this.toX(data[i]), this.toY(data[i + 1]));
|
pathBuilder.lineTo(toX_(data[i]), toY_(data[i + 1]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.currentPath = pathBuilder.toString();
|
this.currentPath = pathBuilder.toString();
|
||||||
this.setState({ path: this.currentPath });
|
this.setState({
|
||||||
|
minF: data[0],
|
||||||
|
maxF: data[1],
|
||||||
|
maxDb: data[2],
|
||||||
|
minDb: data[3],
|
||||||
|
path: this.currentPath
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getPropertyUri()
|
||||||
|
{
|
||||||
|
return this.props.propertyName? this.props.propertyName: FREQUENCY_RESPONSE_VECTOR_URI;
|
||||||
|
}
|
||||||
updateAllWaveShapes() {
|
updateAllWaveShapes() {
|
||||||
if (this.requestOutstanding) { // throttling.
|
if (this.requestOutstanding) { // throttling.
|
||||||
this.requestDeferred = true;
|
this.requestDeferred = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.requestOutstanding = true;
|
this.requestOutstanding = true;
|
||||||
this.model.getPatchProperty<any>(this.props.instanceId, FREQUENCY_RESPONSE_VECTOR_URI)
|
this.model.getPatchProperty<any>(this.props.instanceId, this.getPropertyUri())
|
||||||
.then((json) => {
|
.then((json) => {
|
||||||
if (json && json.otype_ === "Vector" && json.vtype_ === "Float") {
|
if (json && json.otype_ === "Vector" && json.vtype_ === "Float") {
|
||||||
this.onFrequencyResponseUpdated(json.value as number[]);
|
this.onFrequencyResponseUpdated(json.value as number[]);
|
||||||
@@ -237,11 +280,11 @@ const ToobFrequencyResponseView =
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
// deliberately reversed to flip up and down.
|
// deliberately reversed to flip up and down.
|
||||||
this.dbMax = this.props.minDb ?? this.dbMinDefault;
|
this.dbMax = this.state.minDb;
|
||||||
this.dbMin = this.props.maxDb ?? this.dbMaxDefault;
|
this.dbMin = this.state.maxDb;
|
||||||
|
|
||||||
this.fMin = this.props.minFrequency ?? 30;
|
this.fMin = this.state.minF;
|
||||||
this.fMax = this.props.maxFrequency ?? 20000;
|
this.fMax = this.state.maxF;
|
||||||
this.logMin = Math.log(this.fMin);
|
this.logMin = Math.log(this.fMin);
|
||||||
this.logMax = Math.log(this.fMax);
|
this.logMax = Math.log(this.fMax);
|
||||||
|
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ const ToobMLView =
|
|||||||
{
|
{
|
||||||
let group = controls[4] as ControlGroup;
|
let group = controls[4] as ControlGroup;
|
||||||
group.controls.splice(0,0,
|
group.controls.splice(0,0,
|
||||||
( <ToobFrequencyResponseView instanceId={this.props.instanceId} minDb={-20} maxDb={20} />)
|
( <ToobFrequencyResponseView instanceId={this.props.instanceId} />)
|
||||||
);
|
);
|
||||||
|
|
||||||
let gainControl: React.ReactElement = controls[2] as React.ReactElement;
|
let gainControl: React.ReactElement = controls[2] as React.ReactElement;
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ const ToobToneStackView =
|
|||||||
{
|
{
|
||||||
controls.splice(0,0,
|
controls.splice(0,0,
|
||||||
( <ToobFrequencyResponseView instanceId={this.props.instanceId}
|
( <ToobFrequencyResponseView instanceId={this.props.instanceId}
|
||||||
minDb={-20} maxDb={20} />)
|
/>)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
controls.splice(0,0,
|
controls.splice(0,0,
|
||||||
|
|||||||
@@ -206,7 +206,7 @@ export default class UploadFileDialog extends ResizeResponsiveComponent<UploadFi
|
|||||||
upload.abortController = new AbortController();
|
upload.abortController = new AbortController();
|
||||||
if (!this.wantsFile(this.uploadList[i].file))
|
if (!this.wantsFile(this.uploadList[i].file))
|
||||||
{
|
{
|
||||||
throw new Error("Invalid file type.");
|
throw new Error("Invalid file extension.");
|
||||||
}
|
}
|
||||||
let filename = await this.model.uploadFile(this.props.uploadPage, this.uploadList[i].file, "application/octet-stream", upload.abortController);
|
let filename = await this.model.uploadFile(this.props.uploadPage, this.uploadList[i].file, "application/octet-stream", upload.abortController);
|
||||||
this.props.onUploaded(filename);
|
this.props.onUploaded(filename);
|
||||||
|
|||||||
@@ -41,11 +41,11 @@ const Utility = class {
|
|||||||
static isLandscape(): boolean {
|
static isLandscape(): boolean {
|
||||||
return window.innerWidth > window.innerHeight;
|
return window.innerWidth > window.innerHeight;
|
||||||
}
|
}
|
||||||
static isTouchDevice(): boolean {
|
static needsZoomedControls(): boolean {
|
||||||
if (!this.isLandscape()) return false;
|
if (!this.isLandscape()) return false;
|
||||||
|
|
||||||
if (window.innerHeight > 500) return false;
|
if (window.innerHeight > 500) return false;
|
||||||
|
if (window.innerHeight > 300) return true;
|
||||||
return (('ontouchstart' in window) &&
|
return (('ontouchstart' in window) &&
|
||||||
((navigator.maxTouchPoints??0) > 0) );
|
((navigator.maxTouchPoints??0) > 0) );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import { WithStyles } from '@mui/styles';
|
|||||||
import withStyles from '@mui/styles/withStyles';
|
import withStyles from '@mui/styles/withStyles';
|
||||||
import createStyles from '@mui/styles/createStyles';
|
import createStyles from '@mui/styles/createStyles';
|
||||||
import { PiPedalModel, PiPedalModelFactory, ZoomedControlInfo } from './PiPedalModel';
|
import { PiPedalModel, PiPedalModelFactory, ZoomedControlInfo } from './PiPedalModel';
|
||||||
|
import {ReactComponent as DialIcon} from './svg/fx_dial.svg';
|
||||||
|
|
||||||
const SELECTED_OPACITY = 0.8;
|
const SELECTED_OPACITY = 0.8;
|
||||||
const DEFAULT_OPACITY = 0.6;
|
const DEFAULT_OPACITY = 0.6;
|
||||||
@@ -34,6 +35,12 @@ const DEAD_ZONE_SIZE = 5;
|
|||||||
|
|
||||||
|
|
||||||
const styles = (theme: Theme) => createStyles({
|
const styles = (theme: Theme) => createStyles({
|
||||||
|
dialIcon: {
|
||||||
|
overscrollBehavior: "none", touchAction: "none",
|
||||||
|
fill: theme.palette.text.primary,
|
||||||
|
opacity: DEFAULT_OPACITY,
|
||||||
|
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -56,7 +63,7 @@ const ZoomedDial = withStyles(styles, { withTheme: true })(
|
|||||||
class extends React.Component<ZoomedDialProps, ZoomedDialState> {
|
class extends React.Component<ZoomedDialProps, ZoomedDialState> {
|
||||||
|
|
||||||
model: PiPedalModel = PiPedalModelFactory.getInstance();
|
model: PiPedalModel = PiPedalModelFactory.getInstance();
|
||||||
imgRef: React.RefObject<HTMLImageElement> = React.createRef();
|
imgRef: React.RefObject<SVGSVGElement> = React.createRef();
|
||||||
|
|
||||||
constructor(props: ZoomedDialProps) {
|
constructor(props: ZoomedDialProps) {
|
||||||
super(props);
|
super(props);
|
||||||
@@ -75,7 +82,7 @@ const ZoomedDial = withStyles(styles, { withTheme: true })(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onPointerUp(e: PointerEvent<HTMLImageElement>) {
|
onPointerUp(e: PointerEvent<SVGSVGElement>) {
|
||||||
|
|
||||||
if (this.isCapturedPointer(e)) {
|
if (this.isCapturedPointer(e)) {
|
||||||
--this.pointersDown;
|
--this.pointersDown;
|
||||||
@@ -94,7 +101,7 @@ const ZoomedDial = withStyles(styles, { withTheme: true })(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
releaseCapture(e: PointerEvent<HTMLImageElement>)
|
releaseCapture(e: PointerEvent<SVGSVGElement>)
|
||||||
{
|
{
|
||||||
let img = this.imgRef.current;
|
let img = this.imgRef.current;
|
||||||
|
|
||||||
@@ -118,7 +125,7 @@ const ZoomedDial = withStyles(styles, { withTheme: true })(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
onPointerLostCapture(e: PointerEvent<HTMLImageElement>) {
|
onPointerLostCapture(e: PointerEvent<SVGSVGElement>) {
|
||||||
if (this.isCapturedPointer(e)) {
|
if (this.isCapturedPointer(e)) {
|
||||||
--this.pointersDown;
|
--this.pointersDown;
|
||||||
|
|
||||||
@@ -128,10 +135,10 @@ const ZoomedDial = withStyles(styles, { withTheme: true })(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onTouchStart(e: TouchEvent<HTMLImageElement>) {
|
onTouchStart(e: TouchEvent<SVGSVGElement>) {
|
||||||
//must be defined to get onTouchMove
|
//must be defined to get onTouchMove
|
||||||
}
|
}
|
||||||
onTouchMove(e: TouchEvent<HTMLImageElement>) {
|
onTouchMove(e: TouchEvent<SVGSVGElement>) {
|
||||||
// e.preventDefault();
|
// e.preventDefault();
|
||||||
e.stopPropagation(); // cancels scroll!!!
|
e.stopPropagation(); // cancels scroll!!!
|
||||||
|
|
||||||
@@ -150,7 +157,7 @@ const ZoomedDial = withStyles(styles, { withTheme: true })(
|
|||||||
currentAngle: number = 0;
|
currentAngle: number = 0;
|
||||||
lastPointerAngle: number = 0;
|
lastPointerAngle: number = 0;
|
||||||
|
|
||||||
isValidPointer(e: PointerEvent<HTMLImageElement>): boolean {
|
isValidPointer(e: PointerEvent<SVGSVGElement>): boolean {
|
||||||
if (e.pointerType === "mouse") {
|
if (e.pointerType === "mouse") {
|
||||||
return e.button === 0;
|
return e.button === 0;
|
||||||
} else if (e.pointerType === "pen") {
|
} else if (e.pointerType === "pen") {
|
||||||
@@ -202,7 +209,7 @@ const ZoomedDial = withStyles(styles, { withTheme: true })(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pointerToAngle(e: PointerEvent<HTMLImageElement>): number {
|
pointerToAngle(e: PointerEvent<SVGSVGElement>): number {
|
||||||
|
|
||||||
if (this.imgRef.current) {
|
if (this.imgRef.current) {
|
||||||
let img = this.imgRef.current;
|
let img = this.imgRef.current;
|
||||||
@@ -220,10 +227,10 @@ const ZoomedDial = withStyles(styles, { withTheme: true })(
|
|||||||
}
|
}
|
||||||
return NaN;
|
return NaN;
|
||||||
}
|
}
|
||||||
captureElement?: HTMLElement;
|
captureElement?: SVGSVGElement;
|
||||||
pointersDown: number = 0;
|
pointersDown: number = 0;
|
||||||
|
|
||||||
onPointerDown(e: PointerEvent<HTMLImageElement>): void {
|
onPointerDown(e: PointerEvent<SVGSVGElement>): void {
|
||||||
if (!this.mouseDown && this.isValidPointer(e)) {
|
if (!this.mouseDown && this.isValidPointer(e)) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
@@ -262,7 +269,7 @@ const ZoomedDial = withStyles(styles, { withTheme: true })(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
isCapturedPointer(e: PointerEvent<HTMLImageElement>): boolean {
|
isCapturedPointer(e: PointerEvent<SVGSVGElement>): boolean {
|
||||||
return this.mouseDown
|
return this.mouseDown
|
||||||
&& e.pointerId === this.pointerId
|
&& e.pointerId === this.pointerId
|
||||||
&& e.pointerType === this.pointerType;
|
&& e.pointerType === this.pointerType;
|
||||||
@@ -271,7 +278,7 @@ const ZoomedDial = withStyles(styles, { withTheme: true })(
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
onPointerMove(e: PointerEvent<HTMLImageElement>): void {
|
onPointerMove(e: PointerEvent<SVGSVGElement>): void {
|
||||||
if (this.isCapturedPointer(e)) {
|
if (this.isCapturedPointer(e)) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.updateAngle(e)
|
this.updateAngle(e)
|
||||||
@@ -286,7 +293,7 @@ const ZoomedDial = withStyles(styles, { withTheme: true })(
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
updateAngle(e: PointerEvent<HTMLImageElement>): void {
|
updateAngle(e: PointerEvent<SVGSVGElement>): void {
|
||||||
let angle: number = this.pointerToAngle(e);
|
let angle: number = this.pointerToAngle(e);
|
||||||
if (!isNaN(angle)) {
|
if (!isNaN(angle)) {
|
||||||
if (!isNaN(this.lastPointerAngle)) {
|
if (!isNaN(this.lastPointerAngle)) {
|
||||||
@@ -352,14 +359,13 @@ const ZoomedDial = withStyles(styles, { withTheme: true })(
|
|||||||
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
let classes = this.props.classes;
|
||||||
return (
|
return (
|
||||||
<img ref={this.imgRef} src="img/fx_dial.svg" alt=""
|
<DialIcon ref={this.imgRef} className={classes.dialIcon}
|
||||||
style={{
|
style={{
|
||||||
overscrollBehavior: "none", touchAction: "none",
|
transform: this.getDefaultRotationTransform(),
|
||||||
width: this.props.size, height: this.props.size, opacity: DEFAULT_OPACITY,
|
width: this.props.size, height: this.props.size,
|
||||||
transform: this.getDefaultRotationTransform()
|
|
||||||
}}
|
}}
|
||||||
draggable="true"
|
|
||||||
onTouchStart={this.onTouchStart} onTouchMove={this.onTouchMove}
|
onTouchStart={this.onTouchStart} onTouchMove={this.onTouchMove}
|
||||||
onPointerDown={this.onPointerDown} onPointerUp={this.onPointerUp}
|
onPointerDown={this.onPointerDown} onPointerUp={this.onPointerUp}
|
||||||
onPointerMoveCapture={this.onPointerMove} onDrag={this.onDrag}
|
onPointerMoveCapture={this.onPointerMove} onDrag={this.onDrag}
|
||||||
|
|||||||
@@ -215,8 +215,8 @@ const ZoomedUiControl = withStyles(styles, { withTheme: true })(
|
|||||||
onClose={() => { this.props.onDialogClose() }}
|
onClose={() => { this.props.onDialogClose() }}
|
||||||
onAbort={() => { this.props.onDialogClose() }}
|
onAbort={() => { this.props.onDialogClose() }}
|
||||||
>
|
>
|
||||||
<div style={{
|
<div style={{
|
||||||
width: 380, height: 300, background: "FFFF",
|
width: 380, height: 300,
|
||||||
display: "flex", flexFlow: "row", alignItems: "center", alignContent: " center", justifyContent: "center"
|
display: "flex", flexFlow: "row", alignItems: "center", alignContent: " center", justifyContent: "center"
|
||||||
}}>
|
}}>
|
||||||
<IconButton sx={{ height: "100%", width: 48, borderRadius: "0% 50% 50% 0%" }} onClick={
|
<IconButton sx={{ height: "100%", width: 48, borderRadius: "0% 50% 50% 0%" }} onClick={
|
||||||
@@ -227,7 +227,7 @@ const ZoomedUiControl = withStyles(styles, { withTheme: true })(
|
|||||||
<NavigateBeforeIcon />
|
<NavigateBeforeIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<div style={{
|
<div style={{
|
||||||
width: 200, flexGrow: 1, height: 300, background: "#FFF",
|
width: 200, flexGrow: 1, height: 300,
|
||||||
display: "flex", flexFlow: "column", alignItems: "center", alignContent: "center", justifyContent: "center"
|
display: "flex", flexFlow: "column", alignItems: "center", alignContent: "center", justifyContent: "center"
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px">
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<polygon points="15,16 11,20 21,20 21,16"/>
|
||||||
|
<path d="M12.06,7.19L3,16.25V20h3.75l9.06-9.06L12.06,7.19z M5.92,18H5v-0.92l7.06-7.06l0.92,0.92L5.92,18z"/>
|
||||||
|
<path d="M18.71,8.04c0.39-0.39,0.39-1.02,0-1.41l-2.34-2.34C16.17,4.09,15.92,4,15.66,4c-0.25,0-0.51,0.1-0.7,0.29l-1.83,1.83 l3.75,3.75L18.71,8.04z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 507 B |
@@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
||||||
|
<rect x="6" y="9" width="2" height="2"/>
|
||||||
|
<rect x="6" y="13" width="2" height="2"/>
|
||||||
|
<rect x="6" y="17" width="2" height="2"/>
|
||||||
|
<rect x="10" y="17" width="3" height="2"/>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path d="M17.059,5.19l-7.061,7.06V16h3.75l7.061-7.061L17.059,5.19z M12.918,14h-0.92v-0.92l5.061-5.061l0.92,0.92L12.918,14z"/>
|
||||||
|
<path d="M23.708,6.04c0.39-0.39,0.39-1.02,0-1.41l-2.34-2.34c-0.2-0.2-0.45-0.29-0.71-0.29c-0.25,0-0.51,0.1-0.7,0.29l-1.83,1.83
|
||||||
|
l3.75,3.75L23.708,6.04z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<path d="M15,16.641V21H4v-9V7h5h1h3.672l1.904-1.904C15.393,5.04,15.202,5,15,5h-4H8H4C2.9,5,2.01,5.9,2.01,7l-0.003,3.993L2,11v10
|
||||||
|
c0,1.1,0.891,2,1.99,2H4h11h0.01c1.1,0,1.99-0.9,1.99-2v-6.359L15,16.641z"/>
|
||||||
|
<polygon points="11.672,9 10,9 10,10.672 "/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 402 B After Width: | Height: | Size: 402 B |
|
Before Width: | Height: | Size: 997 B After Width: | Height: | Size: 997 B |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M19.43 12.98c.04-.32.07-.64.07-.98 0-.34-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.09-.16-.26-.25-.44-.25-.06 0-.12.01-.17.03l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.46 2.18 14.25 2 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.06-.02-.12-.03-.18-.03-.17 0-.34.09-.43.25l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98 0 .33.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.09.16.26.25.44.25.06 0 .12-.01.17-.03l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.06.02.12.03.18.03.17 0 .34-.09.43-.25l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zm-1.98-1.71c.04.31.05.52.05.73 0 .21-.02.43-.05.73l-.14 1.13.89.7 1.08.84-.7 1.21-1.27-.51-1.04-.42-.9.68c-.43.32-.84.56-1.25.73l-1.06.43-.16 1.13-.2 1.35h-1.4l-.19-1.35-.16-1.13-1.06-.43c-.43-.18-.83-.41-1.23-.71l-.91-.7-1.06.43-1.27.51-.7-1.21 1.08-.84.89-.7-.14-1.13c-.03-.31-.05-.54-.05-.74s.02-.43.05-.73l.14-1.13-.89-.7-1.08-.84.7-1.21 1.27.51 1.04.42.9-.68c.43-.32.84-.56 1.25-.73l1.06-.43.16-1.13.2-1.35h1.39l.19 1.35.16 1.13 1.06.43c.43.18.83.41 1.23.71l.91.7 1.06-.43 1.27-.51.7 1.21-1.07.85-.89.7.14 1.13zM12 8c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm0 6c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z"/></svg>
|
||||||
|
After Width: | Height: | Size: 1.4 KiB |
@@ -991,7 +991,7 @@ int main(int argc, char **argv)
|
|||||||
parser.AddOption("--help", &help);
|
parser.AddOption("--help", &help);
|
||||||
parser.AddOption("--prefix", &prefixOption);
|
parser.AddOption("--prefix", &prefixOption);
|
||||||
parser.AddOption("--port", &portOption);
|
parser.AddOption("--port", &portOption);
|
||||||
parser.AddOption("--enable-ap", &enable_ap);
|
parser.AddOption("--enable-legacy-ap", &enable_ap);
|
||||||
parser.AddOption("--disable-ap", &disable_ap);
|
parser.AddOption("--disable-ap", &disable_ap);
|
||||||
parser.AddOption("--enable-p2p", &enable_p2p);
|
parser.AddOption("--enable-p2p", &enable_p2p);
|
||||||
parser.AddOption("--disable-p2p", &disable_p2p);
|
parser.AddOption("--disable-p2p", &disable_p2p);
|
||||||
|
|||||||
@@ -378,6 +378,8 @@ void PiPedalModel::OnNotifyMaybeLv2StateChanged(uint64_t instanceId)
|
|||||||
|
|
||||||
|
|
||||||
IPiPedalModelSubscriber **t = new IPiPedalModelSubscriber *[this->subscribers.size()];
|
IPiPedalModelSubscriber **t = new IPiPedalModelSubscriber *[this->subscribers.size()];
|
||||||
|
|
||||||
|
Lv2PluginState newState = item->lv2State();
|
||||||
for (size_t i = 0; i < subscribers.size(); ++i)
|
for (size_t i = 0; i < subscribers.size(); ++i)
|
||||||
{
|
{
|
||||||
t[i] = this->subscribers[i];
|
t[i] = this->subscribers[i];
|
||||||
@@ -386,7 +388,7 @@ void PiPedalModel::OnNotifyMaybeLv2StateChanged(uint64_t instanceId)
|
|||||||
{
|
{
|
||||||
for (size_t i = 0; i < n; ++i)
|
for (size_t i = 0; i < n; ++i)
|
||||||
{
|
{
|
||||||
t[i]->OnLv2StateChanged(instanceId);
|
t[i]->OnLv2StateChanged(instanceId,newState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete[] t;
|
delete[] t;
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ namespace pipedal
|
|||||||
virtual void OnInputVolumeChanged(float value) = 0;
|
virtual void OnInputVolumeChanged(float value) = 0;
|
||||||
virtual void OnOutputVolumeChanged(float value) = 0;
|
virtual void OnOutputVolumeChanged(float value) = 0;
|
||||||
|
|
||||||
virtual void OnLv2StateChanged(int64_t pedalItemId) = 0;
|
virtual void OnLv2StateChanged(int64_t pedalItemId,const Lv2PluginState&newState ) = 0;
|
||||||
virtual void OnVst3ControlChanged(int64_t clientId, int64_t pedalItemId, const std::string &symbol, float value, const std::string &state) = 0;
|
virtual void OnVst3ControlChanged(int64_t clientId, int64_t pedalItemId, const std::string &symbol, float value, const std::string &state) = 0;
|
||||||
virtual void OnPedalboardChanged(int64_t clientId, const Pedalboard &pedalboard) = 0;
|
virtual void OnPedalboardChanged(int64_t clientId, const Pedalboard &pedalboard) = 0;
|
||||||
virtual void OnPresetsChanged(int64_t clientId, const PresetIndex &presets) = 0;
|
virtual void OnPresetsChanged(int64_t clientId, const PresetIndex &presets) = 0;
|
||||||
|
|||||||
@@ -57,6 +57,21 @@ JSON_MAP_REFERENCE(GetPatchPropertyBody, instanceId)
|
|||||||
JSON_MAP_REFERENCE(GetPatchPropertyBody, propertyUri)
|
JSON_MAP_REFERENCE(GetPatchPropertyBody, propertyUri)
|
||||||
JSON_MAP_END()
|
JSON_MAP_END()
|
||||||
|
|
||||||
|
|
||||||
|
class Lv2StateChangedBody {
|
||||||
|
public:
|
||||||
|
uint64_t instanceId_;
|
||||||
|
Lv2PluginState state_;
|
||||||
|
DECLARE_JSON_MAP(Lv2StateChangedBody);
|
||||||
|
};
|
||||||
|
|
||||||
|
JSON_MAP_BEGIN(Lv2StateChangedBody)
|
||||||
|
JSON_MAP_REFERENCE(Lv2StateChangedBody, instanceId)
|
||||||
|
JSON_MAP_REFERENCE(Lv2StateChangedBody, state)
|
||||||
|
JSON_MAP_END()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class SetPatchPropertyBody {
|
class SetPatchPropertyBody {
|
||||||
public:
|
public:
|
||||||
uint64_t instanceId_;
|
uint64_t instanceId_;
|
||||||
@@ -1493,9 +1508,10 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void OnLv2StateChanged(int64_t instanceId)
|
virtual void OnLv2StateChanged(int64_t instanceId, const Lv2PluginState &state)
|
||||||
{
|
{
|
||||||
Send("onLv2StateChanged",instanceId);
|
Lv2StateChangedBody message { (uint64_t)instanceId, state};
|
||||||
|
Send("onLv2StateChanged",message);
|
||||||
|
|
||||||
}
|
}
|
||||||
virtual void OnErrorMessage(const std::string&message)
|
virtual void OnErrorMessage(const std::string&message)
|
||||||
|
|||||||
@@ -26,14 +26,16 @@
|
|||||||
#include "PluginHost.hpp"
|
#include "PluginHost.hpp"
|
||||||
#include "ss.hpp"
|
#include "ss.hpp"
|
||||||
#include "MimeTypes.hpp"
|
#include "MimeTypes.hpp"
|
||||||
|
#include "AutoLilvNode.hpp"
|
||||||
|
|
||||||
using namespace pipedal;
|
using namespace pipedal;
|
||||||
|
|
||||||
|
|
||||||
PiPedalUI::PiPedalUI(PluginHost *pHost, const LilvNode *uiNode, const std::filesystem::path &resourcePath)
|
PiPedalUI::PiPedalUI(PluginHost *pHost, const LilvNode *uiNode, const std::filesystem::path &resourcePath)
|
||||||
{
|
{
|
||||||
auto pWorld = pHost->getWorld();
|
auto pWorld = pHost->getWorld();
|
||||||
|
|
||||||
LilvNodes *fileNodes = lilv_world_find_nodes(pWorld, uiNode, pHost->lilvUris.pipedalUI__fileProperties, nullptr);
|
AutoLilvNodes fileNodes = lilv_world_find_nodes(pWorld, uiNode, pHost->lilvUris.pipedalUI__fileProperties, nullptr);
|
||||||
LILV_FOREACH(nodes, i, fileNodes)
|
LILV_FOREACH(nodes, i, fileNodes)
|
||||||
{
|
{
|
||||||
const LilvNode *fileNode = lilv_nodes_get(fileNodes, i);
|
const LilvNode *fileNode = lilv_nodes_get(fileNodes, i);
|
||||||
@@ -47,8 +49,23 @@ PiPedalUI::PiPedalUI(PluginHost *pHost, const LilvNode *uiNode, const std::files
|
|||||||
pHost->LogWarning(SS("Failed to read pipedalui::fileProperties. " << e.what()));
|
pHost->LogWarning(SS("Failed to read pipedalui::fileProperties. " << e.what()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
AutoLilvNodes frequencyPlotNodes = lilv_world_find_nodes(pWorld, uiNode, pHost->lilvUris.pipedalUI__frequencyPlot, nullptr);
|
||||||
|
LILV_FOREACH(nodes, i, frequencyPlotNodes)
|
||||||
|
{
|
||||||
|
const LilvNode *frequencyPlotNode = lilv_nodes_get(frequencyPlotNodes, i);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
UiFrequencyPlot::ptr frequencyPlotUI =
|
||||||
|
std::make_shared<UiFrequencyPlot>(pHost, frequencyPlotNode, resourcePath);
|
||||||
|
this->frequencyPlots_.push_back(std::move(frequencyPlotUI));
|
||||||
|
}
|
||||||
|
catch (const std::exception &e)
|
||||||
|
{
|
||||||
|
pHost->LogWarning(SS("Failed to read pipedalui::frequencyPlots. " << e.what()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LilvNodes *portNotifications = lilv_world_find_nodes(pWorld, uiNode, pHost->lilvUris.ui__portNotification, nullptr);
|
AutoLilvNodes portNotifications = lilv_world_find_nodes(pWorld, uiNode, pHost->lilvUris.ui__portNotification, nullptr);
|
||||||
LILV_FOREACH(nodes, i, portNotifications)
|
LILV_FOREACH(nodes, i, portNotifications)
|
||||||
{
|
{
|
||||||
const LilvNode *portNotificationNode = lilv_nodes_get(portNotifications, i);
|
const LilvNode *portNotificationNode = lilv_nodes_get(portNotifications, i);
|
||||||
@@ -62,8 +79,6 @@ PiPedalUI::PiPedalUI(PluginHost *pHost, const LilvNode *uiNode, const std::files
|
|||||||
pHost->LogWarning(SS("Failed to read ui:portNotifications. " << e.what()));
|
pHost->LogWarning(SS("Failed to read ui:portNotifications. " << e.what()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lilv_nodes_free(fileNodes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UiFileType::UiFileType(PluginHost *pHost, const LilvNode *node)
|
UiFileType::UiFileType(PluginHost *pHost, const LilvNode *node)
|
||||||
@@ -330,7 +345,15 @@ UiFileProperty::UiFileProperty(const std::string &name, const std::string &patch
|
|||||||
directory_(directory)
|
directory_(directory)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
PiPedalUI::PiPedalUI(std::vector<UiFileProperty::ptr> &&fileProperties)
|
PiPedalUI::PiPedalUI(
|
||||||
|
std::vector<UiFileProperty::ptr> &&fileProperties,
|
||||||
|
std::vector<UiFrequencyPlot::ptr>&& frequencyPlots)
|
||||||
|
{
|
||||||
|
this->fileProperties_ = std::move(fileProperties);
|
||||||
|
this->frequencyPlots_ = std::move(frequencyPlots);
|
||||||
|
}
|
||||||
|
PiPedalUI::PiPedalUI(
|
||||||
|
std::vector<UiFileProperty::ptr> &&fileProperties)
|
||||||
{
|
{
|
||||||
this->fileProperties_ = std::move(fileProperties);
|
this->fileProperties_ = std::move(fileProperties);
|
||||||
}
|
}
|
||||||
@@ -357,6 +380,66 @@ UiFileType::UiFileType(const std::string&label, const std::string &fileType)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static float GetFloat(LilvWorld *pWorld,const LilvNode*node,const LilvNode*property,float defaultValue)
|
||||||
|
{
|
||||||
|
AutoLilvNode value = lilv_world_get(
|
||||||
|
pWorld,
|
||||||
|
node,
|
||||||
|
property,
|
||||||
|
nullptr);
|
||||||
|
return value.AsFloat(defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
UiFrequencyPlot::UiFrequencyPlot(PluginHost*pHost, const LilvNode*node,
|
||||||
|
const std::filesystem::path&resourcePath)
|
||||||
|
{
|
||||||
|
auto pWorld = pHost->getWorld();
|
||||||
|
|
||||||
|
AutoLilvNode patchProperty = lilv_world_get(
|
||||||
|
pWorld,
|
||||||
|
node,
|
||||||
|
pHost->lilvUris.pipedalUI__patchProperty,
|
||||||
|
nullptr);
|
||||||
|
if (patchProperty)
|
||||||
|
{
|
||||||
|
this->patchProperty_ = patchProperty.AsUri();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw std::logic_error("PiPedal FileProperty is missing pipedalui:patchProperty value.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AutoLilvNode index = lilv_world_get(
|
||||||
|
pWorld,
|
||||||
|
node,
|
||||||
|
pHost->lilvUris.lv2core__index,
|
||||||
|
nullptr);
|
||||||
|
if (index)
|
||||||
|
{
|
||||||
|
this->index_ = index.AsInt(-1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->index_ = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
AutoLilvNode portGroup = lilv_world_get(pWorld,node,pHost->lilvUris.portgroups__group,nullptr);
|
||||||
|
if (portGroup)
|
||||||
|
{
|
||||||
|
this->portGroup_ = portGroup.AsUri();
|
||||||
|
}
|
||||||
|
this->xLeft_ = GetFloat(pWorld,node,pHost->lilvUris.pipedalUI__xLeft,100);
|
||||||
|
this->xRight_ = GetFloat(pWorld,node,pHost->lilvUris.pipedalUI__xRight,22000);
|
||||||
|
this->yTop_ = GetFloat(pWorld,node,pHost->lilvUris.pipedalUI__yTop,5);
|
||||||
|
this->yBottom_ = GetFloat(pWorld,node,pHost->lilvUris.pipedalUI__yBottom,-35);
|
||||||
|
this->xLog_ = GetFloat(pWorld,node,pHost->lilvUris.pipedalUI__xLog,-35);
|
||||||
|
this->width_ = GetFloat(pWorld,node,pHost->lilvUris.pipedalUI__width,60);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
JSON_MAP_BEGIN(UiPortNotification)
|
JSON_MAP_BEGIN(UiPortNotification)
|
||||||
JSON_MAP_REFERENCE(UiPortNotification, portIndex)
|
JSON_MAP_REFERENCE(UiPortNotification, portIndex)
|
||||||
JSON_MAP_REFERENCE(UiPortNotification, symbol)
|
JSON_MAP_REFERENCE(UiPortNotification, symbol)
|
||||||
@@ -377,4 +460,17 @@ JSON_MAP_REFERENCE(UiFileProperty, directory)
|
|||||||
JSON_MAP_REFERENCE(UiFileProperty, patchProperty)
|
JSON_MAP_REFERENCE(UiFileProperty, patchProperty)
|
||||||
JSON_MAP_REFERENCE(UiFileProperty, fileTypes)
|
JSON_MAP_REFERENCE(UiFileProperty, fileTypes)
|
||||||
JSON_MAP_REFERENCE(UiFileProperty, portGroup)
|
JSON_MAP_REFERENCE(UiFileProperty, portGroup)
|
||||||
|
JSON_MAP_END()
|
||||||
|
|
||||||
|
JSON_MAP_BEGIN(UiFrequencyPlot)
|
||||||
|
JSON_MAP_REFERENCE(UiFrequencyPlot, patchProperty)
|
||||||
|
JSON_MAP_REFERENCE(UiFrequencyPlot, index)
|
||||||
|
JSON_MAP_REFERENCE(UiFrequencyPlot, portGroup)
|
||||||
|
JSON_MAP_REFERENCE(UiFrequencyPlot, xLeft)
|
||||||
|
JSON_MAP_REFERENCE(UiFrequencyPlot, xRight)
|
||||||
|
JSON_MAP_REFERENCE(UiFrequencyPlot, xLog)
|
||||||
|
JSON_MAP_REFERENCE(UiFrequencyPlot, yTop)
|
||||||
|
JSON_MAP_REFERENCE(UiFrequencyPlot, yBottom)
|
||||||
|
JSON_MAP_REFERENCE(UiFrequencyPlot, width)
|
||||||
|
|
||||||
JSON_MAP_END()
|
JSON_MAP_END()
|
||||||
@@ -50,12 +50,20 @@
|
|||||||
#define PIPEDAL_UI__outputPorts PIPEDAL_UI_PREFIX "outputPorts"
|
#define PIPEDAL_UI__outputPorts PIPEDAL_UI_PREFIX "outputPorts"
|
||||||
#define PIPEDAL_UI__text PIPEDAL_UI_PREFIX "text"
|
#define PIPEDAL_UI__text PIPEDAL_UI_PREFIX "text"
|
||||||
|
|
||||||
|
#define PIPEDAL_UI__frequencyPlot PIPEDAL_UI_PREFIX "frequencyPlot"
|
||||||
|
#define PIPEDAL_UI__xLeft PIPEDAL_UI_PREFIX "xLeft"
|
||||||
|
#define PIPEDAL_UI__xRight PIPEDAL_UI_PREFIX "xRight"
|
||||||
|
#define PIPEDAL_UI__xLog PIPEDAL_UI_PREFIX "xLog"
|
||||||
|
#define PIPEDAL_UI__yTop PIPEDAL_UI_PREFIX "yTop"
|
||||||
|
#define PIPEDAL_UI__yBottom PIPEDAL_UI_PREFIX "yBottom"
|
||||||
|
#define PIPEDAL_UI__width PIPEDAL_UI_PREFIX "width"
|
||||||
|
|
||||||
|
|
||||||
namespace pipedal {
|
namespace pipedal {
|
||||||
|
|
||||||
class PluginHost;
|
class PluginHost;
|
||||||
|
|
||||||
|
|
||||||
class UiFileType {
|
class UiFileType {
|
||||||
private:
|
private:
|
||||||
std::string label_;
|
std::string label_;
|
||||||
@@ -126,18 +134,55 @@ namespace pipedal {
|
|||||||
public:
|
public:
|
||||||
DECLARE_JSON_MAP(UiFileProperty);
|
DECLARE_JSON_MAP(UiFileProperty);
|
||||||
};
|
};
|
||||||
|
class UiFrequencyPlot {
|
||||||
|
private:
|
||||||
|
std::string patchProperty_;
|
||||||
|
std::int64_t index_ = -1;
|
||||||
|
std::string portGroup_;
|
||||||
|
float xLeft_ = 100;
|
||||||
|
float xRight_ = 22000;
|
||||||
|
float yTop_ = 5;
|
||||||
|
float yBottom_ = -30;
|
||||||
|
bool xLog_ = true;
|
||||||
|
float width_ = 60;
|
||||||
|
public:
|
||||||
|
using ptr = std::shared_ptr<UiFrequencyPlot>;
|
||||||
|
UiFrequencyPlot() { }
|
||||||
|
UiFrequencyPlot(PluginHost*pHost, const LilvNode*node,
|
||||||
|
const std::filesystem::path&resourcePath);
|
||||||
|
|
||||||
|
const std::string &patchProperty() const { return patchProperty_; }
|
||||||
|
int64_t index() const { return index_; }
|
||||||
|
const std::string&portGroup() const { return portGroup_; }
|
||||||
|
float xLeft() const { return xLeft_; }
|
||||||
|
float xRight() const { return xRight_; }
|
||||||
|
float xLog() const { return xLog_; }
|
||||||
|
float yTop() const { return yTop_; }
|
||||||
|
float yBottom() const { return yBottom_; }
|
||||||
|
float width() const { return width_; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
DECLARE_JSON_MAP(UiFrequencyPlot);
|
||||||
|
};
|
||||||
|
|
||||||
class PiPedalUI {
|
class PiPedalUI {
|
||||||
public:
|
public:
|
||||||
using ptr = std::shared_ptr<PiPedalUI>;
|
using ptr = std::shared_ptr<PiPedalUI>;
|
||||||
PiPedalUI(PluginHost*pHost, const LilvNode*uiNode, const std::filesystem::path&resourcePath);
|
PiPedalUI(PluginHost*pHost, const LilvNode*uiNode, const std::filesystem::path&resourcePath);
|
||||||
|
PiPedalUI(
|
||||||
PiPedalUI(std::vector<UiFileProperty::ptr> &&fileProperites);
|
std::vector<UiFileProperty::ptr> &&fileProperties,
|
||||||
|
std::vector<UiFrequencyPlot::ptr> &&frequencyPlots);
|
||||||
|
PiPedalUI(
|
||||||
|
std::vector<UiFileProperty::ptr> &&fileProperties);
|
||||||
|
|
||||||
const std::vector<UiFileProperty::ptr>& fileProperties() const
|
const std::vector<UiFileProperty::ptr>& fileProperties() const
|
||||||
{
|
{
|
||||||
return fileProperties_;
|
return fileProperties_;
|
||||||
}
|
}
|
||||||
|
const std::vector<UiFrequencyPlot::ptr>& frequencyPlots() const
|
||||||
|
{
|
||||||
|
return frequencyPlots_;
|
||||||
|
}
|
||||||
|
|
||||||
const std::vector<UiPortNotification::ptr> &portNotifications() const { return portNotifications_; }
|
const std::vector<UiPortNotification::ptr> &portNotifications() const { return portNotifications_; }
|
||||||
|
|
||||||
@@ -155,6 +200,7 @@ namespace pipedal {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<UiFileProperty::ptr> fileProperties_;
|
std::vector<UiFileProperty::ptr> fileProperties_;
|
||||||
|
std::vector<UiFrequencyPlot::ptr> frequencyPlots_;
|
||||||
std::vector<UiPortNotification::ptr> portNotifications_;
|
std::vector<UiPortNotification::ptr> portNotifications_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ PiPedalVersion::PiPedalVersion(PiPedalModel&model)
|
|||||||
std::string p2pAddr = GetInterfaceIpv4Address("p2p-wlan0-0");
|
std::string p2pAddr = GetInterfaceIpv4Address("p2p-wlan0-0");
|
||||||
if (p2pAddr.length() != 0)
|
if (p2pAddr.length() != 0)
|
||||||
{
|
{
|
||||||
this->webAddresses_.push_back(MakeWebAddress(p2pAddr,port));
|
this->webAddresses_.push_back(MakeWebAddress(p2pAddr,port) + " (WiFi Direct)");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -145,6 +145,14 @@ void PluginHost::LilvUris::Initialize(LilvWorld *pWorld)
|
|||||||
pipedalUI__outputPorts = lilv_new_uri(pWorld, PIPEDAL_UI__outputPorts);
|
pipedalUI__outputPorts = lilv_new_uri(pWorld, PIPEDAL_UI__outputPorts);
|
||||||
pipedalUI__text = lilv_new_uri(pWorld, PIPEDAL_UI__text);
|
pipedalUI__text = lilv_new_uri(pWorld, PIPEDAL_UI__text);
|
||||||
|
|
||||||
|
pipedalUI__frequencyPlot = lilv_new_uri(pWorld, PIPEDAL_UI__frequencyPlot);
|
||||||
|
pipedalUI__xLeft = lilv_new_uri(pWorld, PIPEDAL_UI__xLeft);
|
||||||
|
pipedalUI__xRight = lilv_new_uri(pWorld, PIPEDAL_UI__xRight);
|
||||||
|
pipedalUI__yTop = lilv_new_uri(pWorld, PIPEDAL_UI__yTop);
|
||||||
|
pipedalUI__yBottom = lilv_new_uri(pWorld, PIPEDAL_UI__yBottom);
|
||||||
|
pipedalUI__xLog = lilv_new_uri(pWorld, PIPEDAL_UI__xLog);
|
||||||
|
pipedalUI__width = lilv_new_uri(pWorld, PIPEDAL_UI__width);
|
||||||
|
|
||||||
ui__portNotification = lilv_new_uri(pWorld, LV2_UI__portNotification);
|
ui__portNotification = lilv_new_uri(pWorld, LV2_UI__portNotification);
|
||||||
ui__plugin = lilv_new_uri(pWorld, LV2_UI__plugin);
|
ui__plugin = lilv_new_uri(pWorld, LV2_UI__plugin);
|
||||||
ui__protocol = lilv_new_uri(pWorld, LV2_UI__protocol);
|
ui__protocol = lilv_new_uri(pWorld, LV2_UI__protocol);
|
||||||
@@ -154,6 +162,9 @@ void PluginHost::LilvUris::Initialize(LilvWorld *pWorld)
|
|||||||
lv2__symbol = lilv_new_uri(pWorld, LV2_CORE__symbol);
|
lv2__symbol = lilv_new_uri(pWorld, LV2_CORE__symbol);
|
||||||
lv2__port = lilv_new_uri(pWorld, LV2_CORE__port);
|
lv2__port = lilv_new_uri(pWorld, LV2_CORE__port);
|
||||||
|
|
||||||
|
#define MOD_PREFIX "http://moddevices.com/ns/mod#"
|
||||||
|
mod__label = lilv_new_uri(pWorld,MOD_PREFIX "label");
|
||||||
|
mod__brand = lilv_new_uri(pWorld,MOD_PREFIX "brand");
|
||||||
// ui:portNotification
|
// ui:portNotification
|
||||||
// [
|
// [
|
||||||
// ui:portIndex 3;
|
// ui:portIndex 3;
|
||||||
@@ -639,11 +650,25 @@ Lv2PluginInfo::Lv2PluginInfo(PluginHost *lv2Host, LilvWorld *pWorld, const LilvP
|
|||||||
|
|
||||||
this->has_factory_presets_ = HasFactoryPresets(lv2Host, pPlugin);
|
this->has_factory_presets_ = HasFactoryPresets(lv2Host, pPlugin);
|
||||||
|
|
||||||
|
AutoLilvNode plugUri = lilv_plugin_get_uri(pPlugin);
|
||||||
this->uri_ = nodeAsString(lilv_plugin_get_uri(pPlugin));
|
this->uri_ = nodeAsString(lilv_plugin_get_uri(pPlugin));
|
||||||
|
|
||||||
AutoLilvNode name = (lilv_plugin_get_name(pPlugin));
|
AutoLilvNode name = (lilv_plugin_get_name(pPlugin));
|
||||||
this->name_ = nodeAsString(name);
|
this->name_ = nodeAsString(name);
|
||||||
|
|
||||||
|
AutoLilvNode brand = lilv_world_get(pWorld,plugUri,lv2Host->lilvUris.mod__brand, nullptr);
|
||||||
|
this->brand_ = nodeAsString(brand);
|
||||||
|
|
||||||
|
AutoLilvNode label = lilv_world_get(pWorld,plugUri,lv2Host->lilvUris.mod__label, nullptr);
|
||||||
|
this->label_ = nodeAsString(label);
|
||||||
|
if (label_.length() == 0)
|
||||||
|
{
|
||||||
|
this->label_ = name;
|
||||||
|
} else {
|
||||||
|
std::cout << this->label_ << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
AutoLilvNode author_name = (lilv_plugin_get_author_name(pPlugin));
|
AutoLilvNode author_name = (lilv_plugin_get_author_name(pPlugin));
|
||||||
this->author_name_ = nodeAsString(author_name);
|
this->author_name_ = nodeAsString(author_name);
|
||||||
|
|
||||||
@@ -1015,6 +1040,8 @@ bool PluginHost::is_a(const std::string &class_, const std::string &target_class
|
|||||||
Lv2PluginUiInfo::Lv2PluginUiInfo(PluginHost *pHost, const Lv2PluginInfo *plugin)
|
Lv2PluginUiInfo::Lv2PluginUiInfo(PluginHost *pHost, const Lv2PluginInfo *plugin)
|
||||||
: uri_(plugin->uri()),
|
: uri_(plugin->uri()),
|
||||||
name_(plugin->name()),
|
name_(plugin->name()),
|
||||||
|
brand_(plugin->brand()),
|
||||||
|
label_(plugin->label()),
|
||||||
author_name_(plugin->author_name()),
|
author_name_(plugin->author_name()),
|
||||||
author_homepage_(plugin->author_homepage()),
|
author_homepage_(plugin->author_homepage()),
|
||||||
plugin_type_(uri_to_plugin_type(plugin->plugin_class())),
|
plugin_type_(uri_to_plugin_type(plugin->plugin_class())),
|
||||||
@@ -1082,6 +1109,7 @@ Lv2PluginUiInfo::Lv2PluginUiInfo(PluginHost *pHost, const Lv2PluginInfo *plugin)
|
|||||||
if (piPedalUI)
|
if (piPedalUI)
|
||||||
{
|
{
|
||||||
this->fileProperties_ = piPedalUI->fileProperties();
|
this->fileProperties_ = piPedalUI->fileProperties();
|
||||||
|
this->frequencyPlots_ = piPedalUI->frequencyPlots();
|
||||||
this->uiPortNotifications_ = piPedalUI->portNotifications();
|
this->uiPortNotifications_ = piPedalUI->portNotifications();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1401,6 +1429,8 @@ json_map::storage_type<Lv2PluginInfo> Lv2PluginInfo::jmap{{
|
|||||||
json_map::reference("bundle_path", &Lv2PluginInfo::bundle_path_),
|
json_map::reference("bundle_path", &Lv2PluginInfo::bundle_path_),
|
||||||
json_map::reference("uri", &Lv2PluginInfo::uri_),
|
json_map::reference("uri", &Lv2PluginInfo::uri_),
|
||||||
json_map::reference("name", &Lv2PluginInfo::name_),
|
json_map::reference("name", &Lv2PluginInfo::name_),
|
||||||
|
json_map::reference("brand", &Lv2PluginInfo::brand_),
|
||||||
|
json_map::reference("label", &Lv2PluginInfo::label_),
|
||||||
json_map::reference("plugin_class", &Lv2PluginInfo::plugin_class_),
|
json_map::reference("plugin_class", &Lv2PluginInfo::plugin_class_),
|
||||||
json_map::reference("supported_features", &Lv2PluginInfo::supported_features_),
|
json_map::reference("supported_features", &Lv2PluginInfo::supported_features_),
|
||||||
json_map::reference("required_features", &Lv2PluginInfo::required_features_),
|
json_map::reference("required_features", &Lv2PluginInfo::required_features_),
|
||||||
@@ -1466,6 +1496,8 @@ json_map::storage_type<Lv2PluginUiInfo>
|
|||||||
{
|
{
|
||||||
json_map::reference("uri", &Lv2PluginUiInfo::uri_),
|
json_map::reference("uri", &Lv2PluginUiInfo::uri_),
|
||||||
json_map::reference("name", &Lv2PluginUiInfo::name_),
|
json_map::reference("name", &Lv2PluginUiInfo::name_),
|
||||||
|
json_map::reference("brand", &Lv2PluginUiInfo::brand_),
|
||||||
|
json_map::reference("label", &Lv2PluginUiInfo::label_),
|
||||||
json_map::enum_reference("plugin_type", &Lv2PluginUiInfo::plugin_type_, get_plugin_type_enum_converter()),
|
json_map::enum_reference("plugin_type", &Lv2PluginUiInfo::plugin_type_, get_plugin_type_enum_converter()),
|
||||||
json_map::reference("plugin_display_type", &Lv2PluginUiInfo::plugin_display_type_),
|
json_map::reference("plugin_display_type", &Lv2PluginUiInfo::plugin_display_type_),
|
||||||
json_map::reference("author_name", &Lv2PluginUiInfo::author_name_),
|
json_map::reference("author_name", &Lv2PluginUiInfo::author_name_),
|
||||||
@@ -1479,5 +1511,6 @@ json_map::storage_type<Lv2PluginUiInfo>
|
|||||||
json_map::reference("port_groups", &Lv2PluginUiInfo::port_groups_),
|
json_map::reference("port_groups", &Lv2PluginUiInfo::port_groups_),
|
||||||
json_map::reference("is_vst3", &Lv2PluginUiInfo::is_vst3_),
|
json_map::reference("is_vst3", &Lv2PluginUiInfo::is_vst3_),
|
||||||
json_map::reference("fileProperties", &Lv2PluginUiInfo::fileProperties_),
|
json_map::reference("fileProperties", &Lv2PluginUiInfo::fileProperties_),
|
||||||
|
json_map::reference("frequencyPlots", &Lv2PluginUiInfo::frequencyPlots_),
|
||||||
json_map::reference("uiPortNotifications", &Lv2PluginUiInfo::uiPortNotifications_),
|
json_map::reference("uiPortNotifications", &Lv2PluginUiInfo::uiPortNotifications_),
|
||||||
}};
|
}};
|
||||||
|
|||||||
@@ -346,6 +346,8 @@ namespace pipedal
|
|||||||
std::string uri_;
|
std::string uri_;
|
||||||
std::string name_;
|
std::string name_;
|
||||||
std::string plugin_class_;
|
std::string plugin_class_;
|
||||||
|
std::string brand_;
|
||||||
|
std::string label_;
|
||||||
std::vector<std::string> supported_features_;
|
std::vector<std::string> supported_features_;
|
||||||
std::vector<std::string> required_features_;
|
std::vector<std::string> required_features_;
|
||||||
std::vector<std::string> optional_features_;
|
std::vector<std::string> optional_features_;
|
||||||
@@ -367,6 +369,8 @@ namespace pipedal
|
|||||||
LV2_PROPERTY_GETSET(bundle_path)
|
LV2_PROPERTY_GETSET(bundle_path)
|
||||||
LV2_PROPERTY_GETSET(uri)
|
LV2_PROPERTY_GETSET(uri)
|
||||||
LV2_PROPERTY_GETSET(name)
|
LV2_PROPERTY_GETSET(name)
|
||||||
|
LV2_PROPERTY_GETSET(brand)
|
||||||
|
LV2_PROPERTY_GETSET(label)
|
||||||
LV2_PROPERTY_GETSET(plugin_class)
|
LV2_PROPERTY_GETSET(plugin_class)
|
||||||
LV2_PROPERTY_GETSET(supported_features)
|
LV2_PROPERTY_GETSET(supported_features)
|
||||||
LV2_PROPERTY_GETSET(required_features)
|
LV2_PROPERTY_GETSET(required_features)
|
||||||
@@ -574,6 +578,8 @@ namespace pipedal
|
|||||||
private:
|
private:
|
||||||
std::string uri_;
|
std::string uri_;
|
||||||
std::string name_;
|
std::string name_;
|
||||||
|
std::string brand_;
|
||||||
|
std::string label_;
|
||||||
std::string author_name_;
|
std::string author_name_;
|
||||||
std::string author_homepage_;
|
std::string author_homepage_;
|
||||||
PluginType plugin_type_;
|
PluginType plugin_type_;
|
||||||
@@ -588,11 +594,14 @@ namespace pipedal
|
|||||||
std::vector<Lv2PluginUiPort> controls_;
|
std::vector<Lv2PluginUiPort> controls_;
|
||||||
std::vector<Lv2PluginUiPortGroup> port_groups_;
|
std::vector<Lv2PluginUiPortGroup> port_groups_;
|
||||||
std::vector<UiFileProperty::ptr> fileProperties_;
|
std::vector<UiFileProperty::ptr> fileProperties_;
|
||||||
|
std::vector<UiFrequencyPlot::ptr> frequencyPlots_;
|
||||||
std::vector<UiPortNotification::ptr> uiPortNotifications_;
|
std::vector<UiPortNotification::ptr> uiPortNotifications_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LV2_PROPERTY_GETSET(uri)
|
LV2_PROPERTY_GETSET(uri)
|
||||||
LV2_PROPERTY_GETSET(name)
|
LV2_PROPERTY_GETSET(name)
|
||||||
|
LV2_PROPERTY_GETSET(brand)
|
||||||
|
LV2_PROPERTY_GETSET(label)
|
||||||
LV2_PROPERTY_GETSET(author_name)
|
LV2_PROPERTY_GETSET(author_name)
|
||||||
LV2_PROPERTY_GETSET(author_homepage)
|
LV2_PROPERTY_GETSET(author_homepage)
|
||||||
LV2_PROPERTY_GETSET_SCALAR(plugin_type)
|
LV2_PROPERTY_GETSET_SCALAR(plugin_type)
|
||||||
@@ -606,6 +615,7 @@ namespace pipedal
|
|||||||
LV2_PROPERTY_GETSET(port_groups)
|
LV2_PROPERTY_GETSET(port_groups)
|
||||||
LV2_PROPERTY_GETSET_SCALAR(is_vst3)
|
LV2_PROPERTY_GETSET_SCALAR(is_vst3)
|
||||||
LV2_PROPERTY_GETSET(fileProperties)
|
LV2_PROPERTY_GETSET(fileProperties)
|
||||||
|
LV2_PROPERTY_GETSET(frequencyPlots)
|
||||||
LV2_PROPERTY_GETSET(uiPortNotifications)
|
LV2_PROPERTY_GETSET(uiPortNotifications)
|
||||||
|
|
||||||
static json_map::storage_type<Lv2PluginUiInfo> jmap;
|
static json_map::storage_type<Lv2PluginUiInfo> jmap;
|
||||||
@@ -676,6 +686,15 @@ namespace pipedal
|
|||||||
AutoLilvNode pipedalUI__fileExtension;
|
AutoLilvNode pipedalUI__fileExtension;
|
||||||
AutoLilvNode pipedalUI__mimeType;
|
AutoLilvNode pipedalUI__mimeType;
|
||||||
|
|
||||||
|
AutoLilvNode pipedalUI__frequencyPlot;
|
||||||
|
AutoLilvNode pipedalUI__xLeft;
|
||||||
|
AutoLilvNode pipedalUI__xRight;
|
||||||
|
AutoLilvNode pipedalUI__xLog;
|
||||||
|
AutoLilvNode pipedalUI__yTop;
|
||||||
|
AutoLilvNode pipedalUI__yBottom;
|
||||||
|
AutoLilvNode pipedalUI__width;
|
||||||
|
|
||||||
|
|
||||||
AutoLilvNode pipedalUI__outputPorts;
|
AutoLilvNode pipedalUI__outputPorts;
|
||||||
AutoLilvNode pipedalUI__text;
|
AutoLilvNode pipedalUI__text;
|
||||||
|
|
||||||
@@ -696,9 +715,14 @@ namespace pipedal
|
|||||||
AutoLilvNode lv2__symbol;
|
AutoLilvNode lv2__symbol;
|
||||||
AutoLilvNode lv2__port;
|
AutoLilvNode lv2__port;
|
||||||
|
|
||||||
|
AutoLilvNode ui__FrequencyPlot;
|
||||||
|
|
||||||
AutoLilvNode patch__writable;
|
AutoLilvNode patch__writable;
|
||||||
AutoLilvNode patch__readable;
|
AutoLilvNode patch__readable;
|
||||||
|
|
||||||
|
AutoLilvNode mod__brand;
|
||||||
|
AutoLilvNode mod__label;
|
||||||
|
|
||||||
AutoLilvNode dc__format;
|
AutoLilvNode dc__format;
|
||||||
};
|
};
|
||||||
LilvUris lilvUris;
|
LilvUris lilvUris;
|
||||||
|
|||||||