Merge pull request #283 from rerdavies/dev
Dev Merge to fix docs links.
@@ -20,15 +20,15 @@ An RT_PREEMPT kernel provides slightly better realtime audio than a PREEMPT_DYNA
|
||||
## Support for WIFI Auto-Hotspots on Ubuntu Server
|
||||
|
||||
The following information applies when installing PiPedal on Ubuntu Server 24.0x only. This information does not apply
|
||||
to Unbuntu Desktop installs or Raspberry Pi OS Lite installs.
|
||||
to Unbuntu Desktop installs or Raspberry Pi OS Lite installs, which use the Network Manager TCP/IP stack by default.
|
||||
|
||||
PiPedal's Auto-Hotspot feature only works on Linux systems that are using the Network Manager network services stack.
|
||||
Ubuntu Server 24.x (and probably other server-specific installs on other Debian distros) uses the Netplan network services stack by instead. It does so because the Netplan network stack is the preferred network stack when managing
|
||||
farms of cloud servers.
|
||||
|
||||
It's easy enough to reconfigure Ubuntu Server to run the Network Manager network stack instead. However you should be
|
||||
aware that Netplan TCP/IP configuration settings will not be migrated to Network Manager. If you perform this step on a server on which changes have beeen madce to Netplan configuration files, you will need to manually migrate those
|
||||
changes to Network Manager configuration files. On a clean install of Ubuntu Server, this will not be a problem.
|
||||
aware that Netplan TCP/IP configuration settings will not be migrated to Network Manager. If you perform this step on a server on which changes have beeen made to Netplan configuration files, you will lose those configuration changes, and will need to reimplement them in Network Manager. If you are
|
||||
a Netplan configuration (or are working with a clean install), then the default Network Manager configuration will work perfectly well too.
|
||||
|
||||
To reconfigure Ubuntu Server to use the Network Manager network stack (and therefore enable PiPedal's Auto-Hotspot feature), run the following command:
|
||||
|
||||
@@ -123,11 +123,33 @@ The following table shows measured round-trip audio latencies for a MOTU M2 exte
|
||||
<tr><td>128</td><td>442/9.2ms</td><td>571/11.9ms</td><td>699/14.6ms</td></tr>
|
||||
</table>
|
||||
|
||||
LINUX Kernel version 5.16 includes fixes to ALSA audio that are supposed to dramatically improve USB audio latency. As of July 2022, these fixes have not yet made it into Raspberry Pi OS, but are probably available on non-LTS versions of Ubuntu.
|
||||
Selecting 2 buffers provides lower latency, but leaves very little CPU time for audio processing, so you may experience more underruns if
|
||||
you select 2. Selecting 4 buffers provides much more time for proessing. Using a buffer size of 16 increases CPU load slightly, since there a
|
||||
certain amoung of CPU overhead associated with handling of each buffer. That being said, 16x4 audio buffer configuration is a highly recommended
|
||||
choice if your audio adapter can support it. It provides excellent latency with very little chance of overruns.
|
||||
|
||||
PiPedal uses the ALSA audio stack; so (unlike Jack Audio) there is no performance penalty for using 44100Hz sample rates. However, using a 48000Hz sampling rates does provide significant improvements in high-frequency audio quality when performing digital audio signal processing.
|
||||
All things being equal, you should perfer 48000hz sample rates to 44100Hz sample rates. The higher sample rate makes it easier for plugins to implement
|
||||
audio effects without high-frequency artifacts; and Nueral Amp Models are usually designed to work best at 48000Hz sample rates.
|
||||
|
||||
### Activating the Wi-Fi Auto-Hotspot
|
||||
### Configuring Input Trim Levels on Older USB Audio Devices
|
||||
|
||||
For best results, you should set the input gain of your audio device so that the signal level is as high as possible without clipping. If you click on the
|
||||
input node of a preset, the left VU meter will show the audio input levels as received directly from your audio adapter.
|
||||
|
||||
Some older USB audio devices do not provide volume knobs to control input gain of the audio signal, and the default trim settings are often less than
|
||||
ideal. To configure the input gain on these devices, use the following procedure.
|
||||
|
||||
- ssh to the host, or launch a terminal window on the host if you have configured your Raspberry Pi to boot to a graphical desktop.
|
||||
- Run `alsamixer` to configure the input gain.
|
||||
- Press F6 to select the sound card.
|
||||
- Press TAB to scroll across pages/channels until you reach the CAPTURE slider(s).
|
||||
- Connect and play your instrument, while watch the input VU meter in the PiPedal UI. Use the UP and DOWN arrow keys to adjust the input gain.
|
||||
- Press the ESC key to close alsa mixer.
|
||||
- Run `sudo alsactl store` to save the settings permanantly.
|
||||
|
||||
|
||||
|
||||
## Activating the Wi-Fi Auto-Hotspot
|
||||
|
||||
The PiPedal <b><i>Auto-Hotspot</i></b> feature allows you to connect to your Raspberry Pi even if you don't have
|
||||
access to a Wi-Fi router. For example, if you are performing at a live venue, you probably will not
|
||||
@@ -188,14 +210,12 @@ automatically connect to your laptop hotspot whenever it sees it, after you have
|
||||
credentials on your Raspberry Pi. After the first time, all you need to do is turn on your laptop hotspot, and Raspberry Pi OS will
|
||||
connect to it.
|
||||
|
||||
Usually, you cannect from your laptop using the same web address: http://raspberrpi (or the hostname of your raspberry pi, if you have
|
||||
changed it). Unlike Android phones (where mDNS name resolution doesn't work on Android-hosted hotspots), mDNS/Bonjour name resolution usually
|
||||
Usually, you can conect from your laptop using the same web address: `http://raspberrypi` (`http://raspberrypi.local` on Ubuntu), or the hostname of your raspberry pi, if you have changed it. Unlike Android phones (where mDNS name resolution doesn't work on Android-hosted hotspots), mDNS/Bonjour name resolution usually
|
||||
works on laptop-hosted hotspots when using Windows or Mac OS. If are running Linux on your laptop, you may need to install and configure the
|
||||
Avahi package to get mDNS/Bonjour name resolution to work.
|
||||
|
||||
And if that doesn't work, you can configure PiPedal to launch an auto-hotspot, and then connect from your laptop to the PiPedal hotspot on your Raspberry Pi.
|
||||
When the Raspberry Pi hosts the hotspot, mDNS discovery is definitely enabled; so you should be able to connect using http://raspberrypi. But if that doesn't work, PiPedal's IP address will always be 10.40.1, when the PiPedal Wi-Fi hotspot is running, so you can always connect using http://10.40.0.1.
|
||||
|
||||
When the Raspberry Pi hosts the hotspot, mDNS discovery is definitely enabled; so you should be able to connect using http://raspberrypi. But if that doesn't work, PiPedal's IP address will always be 10.40.0.1, when the PiPedal Wi-Fi hotspot is running, so you can always connect using http://10.40.0.1.
|
||||
|
||||
|
||||
--------
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
## PiPedal 1.4.71 Beta
|
||||
|
||||
- Resolves installation issues on Ubuntu Server.
|
||||
- Resolves installation issues on Ubuntu Server./
|
||||
|
||||
## PiPedal 1.4.70 Beta
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ cabir:impulseFile3
|
||||
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
||||
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
||||
lv2:minorVersion 0 ;
|
||||
lv2:microVersion 57 ;
|
||||
lv2:microVersion 58 ;
|
||||
rdfs:comment """
|
||||
|
||||
TooB Cab IR is a convolution-based guitar cabinet impulse response simulator.
|
||||
@@ -274,7 +274,7 @@ Limitations of Liability that apply to these works.
|
||||
lv2:name "Predelay";
|
||||
lv2:portProperty epp:notOnGUI;
|
||||
|
||||
lv2:default 0 ;
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0 ;
|
||||
lv2:maximum 1 ;
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
@prefix urid: <http://lv2plug.in/ns/ext/urid#> .
|
||||
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
||||
@prefix pipedal_ui: <http://github.com/rerdavies/pipedal/ui#> .
|
||||
@prefix pipedal_patch: <http://github.com/rerdavies/pipedal/patch#> .
|
||||
@prefix toob: <http://two-play.com/plugins/toob#> .
|
||||
|
||||
@prefix cabsim: <two-play.com/plugins/toob-cab-sim#> .
|
||||
@@ -49,13 +50,13 @@ toob:frequencyResponseVector
|
||||
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
||||
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
||||
lv2:minorVersion 0 ;
|
||||
lv2:microVersion 57 ;
|
||||
lv2:microVersion 58 ;
|
||||
|
||||
mod:brand "TooB";
|
||||
mod:label "TooB CabSim";
|
||||
lv2:requiredFeature urid:map ;
|
||||
lv2:optionalFeature lv2:hardRTCapable;
|
||||
patch:readable
|
||||
pipedal_patch:readable
|
||||
toob:frequencyResponseVector;
|
||||
|
||||
rdfs:comment """
|
||||
|
||||
@@ -53,7 +53,7 @@ toobimpulse:impulseFile
|
||||
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
||||
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
||||
lv2:minorVersion 0 ;
|
||||
lv2:microVersion 57 ;
|
||||
lv2:microVersion 58 ;
|
||||
rdfs:comment """
|
||||
|
||||
Convolution reverb is a notoriously compute-intensive effect. If you are having performance issues, use the Max T control to constrain the length of the impulse file to
|
||||
|
||||
@@ -51,7 +51,7 @@ toobimpulse:impulseFile
|
||||
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
||||
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
||||
lv2:minorVersion 0 ;
|
||||
lv2:microVersion 57 ;
|
||||
lv2:microVersion 58 ;
|
||||
rdfs:comment """
|
||||
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
@prefix pg: <http://lv2plug.in/ns/ext/port-groups#> .
|
||||
@prefix pipedal_ui: <http://github.com/rerdavies/pipedal/ui#> .
|
||||
@prefix pipedal_patch: <http://github.com/rerdavies/pipedal/patch#> .
|
||||
@prefix toob: <http://two-play.com/plugins/toob#> .
|
||||
|
||||
@prefix inputStage: <http://two-play.com/plugins/toob-input_stage#> .
|
||||
@@ -65,16 +66,14 @@ inputStage:filterGroup
|
||||
doap:license <https://two-play.com/TooB/licenses/isc> ;
|
||||
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
||||
lv2:minorVersion 0 ;
|
||||
lv2:microVersion 57 ;
|
||||
lv2:microVersion 58 ;
|
||||
|
||||
mod:brand "TooB";
|
||||
mod:label "TooB Input";
|
||||
lv2:requiredFeature urid:map ;
|
||||
lv2:optionalFeature lv2:hardRTCapable;
|
||||
|
||||
patch:writable
|
||||
<http://two-play.com/plugins/toob#frequencyResponseVector>;
|
||||
patch:readable
|
||||
pipedal_patch:readable
|
||||
<http://two-play.com/plugins/toob#frequencyResponseVector>;
|
||||
|
||||
rdfs:comment """
|
||||
@@ -282,8 +281,6 @@ The GateT control provides a noise gate. Set to minimum value to disable.
|
||||
lv2:extensionData uiext:resize ;
|
||||
lv2:extensionData uiext:idleInterface;
|
||||
lv2:requiredFeature uiext:idleInterface ;
|
||||
patch:writable
|
||||
<http://two-play.com/plugins/toob#frequencyResponseVector>;
|
||||
.
|
||||
|
||||
<http://two-play.com/plugins/toob-input_stage>
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
@prefix modgui: <http://moddevices.com/ns/modgui#> .
|
||||
@prefix pstage: <http://two-play.com/plugins/toob-power-stage-2#> .
|
||||
|
||||
@prefix pipedal_patch: <http://github.com/rerdavies/pipedal/patch#> .
|
||||
|
||||
pstage:stage1
|
||||
a param:ControlGroup ,
|
||||
@@ -67,13 +68,13 @@ pstage:stage3
|
||||
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
||||
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
||||
lv2:minorVersion 0 ;
|
||||
lv2:microVersion 57 ;
|
||||
lv2:microVersion 58 ;
|
||||
|
||||
mod:brand "TooB";
|
||||
mod:label "Power Stage";
|
||||
lv2:requiredFeature urid:map ;
|
||||
lv2:optionalFeature lv2:hardRTCapable;
|
||||
patch:readable
|
||||
pipedal_patch:readable
|
||||
<http://two-play.com/plugins/toob-power-stage-2#uiState>;
|
||||
|
||||
rdfs:comment """
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
@prefix mod: <http://moddevices.com/ns/mod#> .
|
||||
@prefix param: <http://lv2plug.in/ns/ext/parameters#> .
|
||||
@prefix work: <http://lv2plug.in/ns/ext/worker#> .
|
||||
@prefix pipedal_patch: <http://github.com/rerdavies/pipedal/patch#> .
|
||||
|
||||
@prefix atom: <http://lv2plug.in/ns/ext/atom#> .
|
||||
@prefix patch: <http://lv2plug.in/ns/ext/patch#> .
|
||||
@@ -49,16 +50,14 @@
|
||||
;
|
||||
|
||||
uiext:ui <http://two-play.com/plugins/toob-spectrum-ui>;
|
||||
patch:writable
|
||||
<http://two-play.com/plugins/toob#spectrumResponseVector>;
|
||||
|
||||
patch:readable
|
||||
pipedal_patch:readable
|
||||
<http://two-play.com/plugins/toob#spectrumResponseVector>;
|
||||
|
||||
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
||||
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
||||
lv2:minorVersion 0 ;
|
||||
lv2:microVersion 57 ;
|
||||
lv2:microVersion 58 ;
|
||||
rdfs:comment "TooB spectrum analyzer" ;
|
||||
|
||||
mod:brand "TooB";
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
||||
|
||||
@prefix pipedal_ui: <http://github.com/rerdavies/pipedal/ui#> .
|
||||
@prefix pipedal_patch: <http://github.com/rerdavies/pipedal/patch#> .
|
||||
|
||||
@prefix toob: <http://two-play.com/plugins/toob#> .
|
||||
|
||||
@prefix tonestack: <two-play.com/plugins/toob-tone-stack#> .
|
||||
@@ -55,7 +57,7 @@ tonestack:eqGroup
|
||||
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
||||
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
||||
lv2:minorVersion 0 ;
|
||||
lv2:microVersion 57 ;
|
||||
lv2:microVersion 58 ;
|
||||
|
||||
uiext:ui <http://two-play.com/plugins/toob-tone-stack-ui>;
|
||||
|
||||
@@ -68,7 +70,7 @@ tone stack used in Polytone and HiWatt amps.
|
||||
mod:label "Tone Stack";
|
||||
lv2:requiredFeature urid:map ;
|
||||
lv2:optionalFeature lv2:hardRTCapable;
|
||||
patch:readable
|
||||
pipedal_patch:readable
|
||||
toob:frequencyResponseVector;
|
||||
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
||||
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
||||
lv2:minorVersion 0 ;
|
||||
lv2:microVersion 57 ;
|
||||
lv2:microVersion 58 ;
|
||||
rdfs:comment """
|
||||
Emulation of a Boss CE-2 Chorus.
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
||||
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
||||
lv2:minorVersion 0 ;
|
||||
lv2:microVersion 57 ;
|
||||
lv2:microVersion 58 ;
|
||||
rdfs:comment """
|
||||
A straightforward no-frills digital delay.
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
||||
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
||||
lv2:minorVersion 0 ;
|
||||
lv2:microVersion 57 ;
|
||||
lv2:microVersion 58 ;
|
||||
rdfs:comment """
|
||||
Emulation of a Boss BF-2 Flanger, based on circuit analysis and simulation of the original.
|
||||
|
||||
@@ -99,6 +99,7 @@ Emulation of a Boss BF-2 Flanger, based on circuit analysis and simulation of th
|
||||
lv2:symbol "lfo" ;
|
||||
lv2:name "LFO";
|
||||
|
||||
lv2:portProperty epp:notOnGUI;
|
||||
lv2:minimum -1.0 ;
|
||||
lv2:maximum 1.0 ;
|
||||
],
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
||||
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
||||
lv2:minorVersion 0 ;
|
||||
lv2:microVersion 57 ;
|
||||
lv2:microVersion 58 ;
|
||||
rdfs:comment """
|
||||
Digital emulation of a Boss BF-2 Flanger.
|
||||
|
||||
@@ -99,6 +99,7 @@ should use the monophonic version of this effect.
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:portProperty epp:notOnGUI;
|
||||
lv2:index 3 ;
|
||||
lv2:symbol "lfo" ;
|
||||
lv2:name "LFO";
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
||||
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
||||
lv2:minorVersion 0 ;
|
||||
lv2:microVersion 57 ;
|
||||
lv2:microVersion 58 ;
|
||||
rdfs:comment """
|
||||
Toob Freeverb is an Lv2 implementation of the famous Freeverb reverb effect. FreeVerb delivers a well-balanced reverb with very little tonal coloration.
|
||||
|
||||
|
||||
@@ -0,0 +1,915 @@
|
||||
@prefix doap: <http://usefulinc.com/ns/doap#> .
|
||||
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
|
||||
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
||||
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
|
||||
@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 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 atom: <http://lv2plug.in/ns/ext/atom#> .
|
||||
@prefix patch: <http://lv2plug.in/ns/ext/patch#> .
|
||||
@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 ui: <http://lv2plug.in/ns/extensions/ui#> .
|
||||
@prefix pprop: <http://lv2plug.in/ns/ext/port-props#> .
|
||||
@prefix pipedal_ui: <http://github.com/rerdavies/pipedal/ui#> .
|
||||
|
||||
|
||||
@prefix looperPrefix: <http://two-play.com/plugins/toob-looper#> .
|
||||
|
||||
@prefix myprefix: <http://two-play.com/plugins/toob-looper-four#> .
|
||||
|
||||
|
||||
myprefix:stereoInGroup
|
||||
a pg:StereoGroup, pg:InputGroup ;
|
||||
rdfs:label "Stereo Input" ;
|
||||
lv2:symbol "in_g" .
|
||||
|
||||
myprefix:steroOutGroup a pg:Group ;
|
||||
a pg:StereoGroup, pg:OuputGroup ;
|
||||
rdfs:label "Stereo Output" ;
|
||||
lv2:symbol "out_g" .
|
||||
|
||||
|
||||
myprefix:syncGroup
|
||||
a pg:ControlGroup ;
|
||||
lv2:name "Clock" ;
|
||||
lv2:symbol "sync_g" .
|
||||
|
||||
|
||||
myprefix:loop_main_group
|
||||
a pg:ControlGroup ;
|
||||
lv2:name "Main Loop" ;
|
||||
lv2:symbol "loop_main_group" .
|
||||
|
||||
myprefix:loop2_group
|
||||
a pg:ControlGroup ;
|
||||
lv2:name "Loop 2" ;
|
||||
lv2:symbol "loop2_group" .
|
||||
|
||||
myprefix:loop3_group
|
||||
a pg:ControlGroup ;
|
||||
lv2:name "Loop 3" ;
|
||||
lv2:symbol "loop3_group" .
|
||||
|
||||
myprefix:loop4_group
|
||||
a pg:ControlGroup ;
|
||||
lv2:name "Loop 4" ;
|
||||
lv2:symbol "loop4_group" .
|
||||
|
||||
myprefix:options_group
|
||||
a pg:ControlGroup ;
|
||||
lv2:name "Record Options" ;
|
||||
lv2:symbol "options_group" .
|
||||
|
||||
myprefix:output_group
|
||||
a pg:ControlGroup ;
|
||||
lv2:name "Output" ;
|
||||
lv2:symbol "output_group" .
|
||||
|
||||
|
||||
|
||||
<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> .
|
||||
|
||||
|
||||
<http://two-play.com/plugins/toob-looper-four>
|
||||
a lv2:Plugin ,
|
||||
lv2:UtilityPlugin ;
|
||||
doap:name "TooB 4Looper (stereo)"
|
||||
;
|
||||
doap:license <https://opensource.org/license/mit/> ;
|
||||
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
||||
lv2:minorVersion 1 ;
|
||||
lv2:microVersion 58 ;
|
||||
|
||||
ui:ui <http://two-play.com/plugins/toob-looper-four-ui>;
|
||||
|
||||
lv2:extensionData state:interface ;
|
||||
|
||||
rdfs:comment """
|
||||
## Toob 4Looper
|
||||
|
||||
A 4-channel looper. If you are using a MIDI foot controller, you may want to consider using Toob One-Control looper, which allows control of
|
||||
looping using a single footswitch. TooB 4Looper does support MIDI control using four footswitches. See the Midi Operation section below for
|
||||
more information.
|
||||
|
||||
### Basic Operation
|
||||
|
||||
You must record a main loop before loops 2 through 4 are available.
|
||||
|
||||
To start recording the main loop, press the Main Loop record button. The red Record LED will light up to indicate that the main loop is recording.
|
||||
You can configure TooB 4Looper to use a variable length main loop, or a fixed length loop. See the documentation on the Bars control for more
|
||||
information on how to use a fixed-length loop. If the Bars control is set to "Free", the length of the main loop will be established when
|
||||
you next press the Record or Play button after the main loop has started recording. Pressing the record button will mark the end of the
|
||||
loop, and continue on in Overdub mode. Pressing the Play button will mark the end of the loop, and start playback.
|
||||
|
||||
Once the main loop has been established, you can toggle back and forth between Overdub and Play modes by pressing the Record and Play buttons
|
||||
resepectively.
|
||||
|
||||
You can also mute the loop by going to Play mode, and pushing the Play button once more. Pushing the Play button while in Mute mode will
|
||||
re-enable audio output from the loop.
|
||||
|
||||
Pressing the Main Loop stop buton will stop playback of of all loops, and return the looper to its initial state.
|
||||
|
||||
To record a secondary loop, press the Record button for the loop you want to record. The Record LED will light up to indicate that the loop
|
||||
is recording. If the Rec Sync option is enabled, the loop will go to Cue Overdub mode, and once the main loop reaches the end of its loop,
|
||||
the loop will switch to Record mode. If the Rec Sync option is disabled, the loop will start recording immediately. The length of secondary
|
||||
loops will always be the same as the length of the main loop. Once the loop has started, pressing the play button will start playback.
|
||||
Pressing the record button will overdub content of the loop. In Play mode, pushing the Play button again will mute the loop. Pressing
|
||||
the Play button when the loop is muted will re-enable audio output from the loop. Pressing the Stop button will stop playback, and erase
|
||||
the contents of the loop. There is no concept of "undoing" individual overdubs in TooB 4Looper. If you're done with a loop, just erase it.
|
||||
|
||||
### Clock Options
|
||||
|
||||
Clock options determine the tempo and number of beats in a bar. They affect the behavior of the looper when the Bars control (see below) is set to
|
||||
a numeric value, and also affect the rate and pattern of the flashing LEDs when counting in.
|
||||
|
||||
### Record Options
|
||||
|
||||
Record Options control the behavior of the looper.
|
||||
|
||||
When Count In is enabled, The looper will Count In before starting the main loop. The Record LED will flash when counting in, and go solid
|
||||
once recording starts. The pattern of blinking lights depends on the TimeSig setting, so for example, if the Time Signature is set to 4/4, the
|
||||
blinking LED will signal a count-in pattern of "1 - 2 - 1 2 3 4".
|
||||
|
||||
When Bars is set to Free (the minimum value), the length of the main loop will be set by a second tap of the
|
||||
Control button after recording of the main loop starts. If Bars is set to a numeric value, the length of the main loop will be determined by the number
|
||||
of bars set in the Bars control, and the current settings of the Clock controls.
|
||||
|
||||
If Dub Sync is off, overdubs will start recording as soon as you tap the Control button. If enabled, the start
|
||||
of the secondary loop will sync with main loop. Tapping the Control button will put the looper in "Cue Overdub" state
|
||||
and the LEDs will flash until the end of the main loop is reached, at which point the new loop will start recording.
|
||||
|
||||
The Loop End option only has effect when the Bars control is set to a numeric value, and does nothing if Bars is set to "Free".
|
||||
When set to REC-PLAY, the main loop will record exactly N bars of audio, and switch to play mode when the end of the loop is reached.
|
||||
When set to REC-DUB, the main loop will record exactly N bars of audio, and then continue on in overdub mode.
|
||||
|
||||
|
||||
### MIDI Operation
|
||||
|
||||
If you want to control your looper with one foot controller switch, please use Toob One-Control Looper instead. Toob 4Looper
|
||||
allows you to control loops with four foot controller switches (one for each loop). In order to do this, TooB 4Looper provides
|
||||
a hidden controls only visible in PiPedal's MIDI Bindings user-interface. The hidden controls are named `Midi CTL`; there's one
|
||||
control for each loop. A single tap of the control will cause the loop to start
|
||||
recording or playing or overdubbing, depending on the state of the loop. Long-pressing the control will erase the loop. Erasing the main loop
|
||||
will stop all playback, erasing all other loops as well, and return the Toob 4Looper to its initial state.
|
||||
|
||||
To use the hidden controls, you must bind each of them to your MIDI controller's footswitches. It is recommended that you configure
|
||||
your MIDI controller to send MIDI Note-on/Note off messages. You can bind the controls to MIDI CC messages as well, but the behavior
|
||||
of your controller may not match what TooB 4Looper expects. If you must use MIDI CC messages, you should configure your MIDI
|
||||
controller to set a CC value of zero when not pressed, and a value of 127 when pressed, and adjust PiPedal's MIDI bindings appropriately.
|
||||
|
||||
The following state table controls how the hidden controls operate. Each loop has an independent state.
|
||||
|
||||
### State Table for Looop Operations
|
||||
|
||||
The following table describes state transitions for each loop. Note that loops 2 to 4 are not available until the main loop has been recorded.
|
||||
|
||||
```
|
||||
+-----------+--------------+----------------------------------+
|
||||
| State | Action | Effect |
|
||||
|-----------|--------------|----------------------------------|
|
||||
| Empty | Record / | Start counting in if COUNT IN is |
|
||||
| | Control Tap | enabled; otherwise start |
|
||||
| | | recording immediately. |
|
||||
|-----------|--------------|----------------------------------|
|
||||
| Count-In | Stop / | Return to empty state |
|
||||
| | Long-press | |
|
||||
| | | |
|
||||
| | Complete | Start recording |
|
||||
|-----------|--------------|----------------------------------|
|
||||
| Recording | Play | Set the loop length (main loop |
|
||||
| | | only_) and go to play state . |
|
||||
| | | |
|
||||
| | Record | Set the loop length (main loop |
|
||||
| | | only_) and go to Overdub state . |
|
||||
| | | |
|
||||
| | Stop/ | Discard the current loop and |
|
||||
| | Long-Press | return to Empty state |
|
||||
| | | |
|
||||
| | Control Tap | Set the loop length (main loop |
|
||||
| | | only_) and go to play or Overdub |
|
||||
| | | state depending on ON REC END. |
|
||||
| | | |
|
||||
| | End of loop | go to play or overdub state |
|
||||
| | | depending on ON REC END |
|
||||
|-----------|--------------|----------------------------------|
|
||||
| Playing | Record / Tap | If DUB SYNC is on, go to |
|
||||
| | | Cue Ovdb state; otherwise |
|
||||
| | | start overdubbing immediately. |
|
||||
| | | |
|
||||
| | Play | Mute the loop, and go to Mute |
|
||||
| | | state. |
|
||||
| | | |
|
||||
| | Stop / | Discard the current loop and go |
|
||||
| | Long-press | to Empty state. |
|
||||
|-----------|--------------|----------------------------------|
|
||||
| Mute | Play / Tap | Unmute the loop and go to Play |
|
||||
| | | state. |
|
||||
| | | |
|
||||
| | Record | Start overdubbing. |
|
||||
| | | |
|
||||
| | Stop / | Discard the current loop and go |
|
||||
| | Long-press | to Empty state. |
|
||||
|-----------|--------------|----------------------------------|
|
||||
| Cue Ovdb | End-of-loop | Start overdubbing. |
|
||||
| | | |
|
||||
| | Tap | Cancel the pending overdub. |
|
||||
| | | |
|
||||
| | Long-press | Discard the current loop and go |
|
||||
| | | to Empty state. |
|
||||
|-----------|--------------|----------------------------------|
|
||||
| Overdub | Play / Tap | Start playing. |
|
||||
| | | |
|
||||
| | End of loop | (If DUB SYNC is on, and |
|
||||
| | | REC->PLAY is selected) Go to |
|
||||
| | | play state, otherwise, continue |
|
||||
| | | in overdub state. |
|
||||
+-----------|--------------|----------------------------------+
|
||||
```
|
||||
|
||||
|
||||
|
||||
""" ;
|
||||
|
||||
mod:brand "TooB";
|
||||
mod:label "4Looper";
|
||||
lv2:optionalFeature lv2:hardRTCapable;
|
||||
|
||||
lv2:port
|
||||
################# MAIN Loop
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 0;
|
||||
lv2:symbol "control1" ;
|
||||
lv2:name "MIDI Ctl";
|
||||
rdfs:comment "Hidden control for MIDI operation. See documentation for details.";
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:integer, lv2:toggled, mod:preferMomentaryOffByDefault, pprop:notOnGUI;
|
||||
|
||||
pg:group myprefix:loop_main_group ;
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 1;
|
||||
lv2:symbol "stop1" ;
|
||||
lv2:name "⏹";
|
||||
rdfs:comment "Reset all loops.";
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:toggled,pprop:trigger;
|
||||
pg:group myprefix:loop_main_group ;
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 2;
|
||||
lv2:symbol "record1" ;
|
||||
lv2:name "⏺";
|
||||
rdfs:comment "Recording/overdub the main loop";
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:toggled,pprop:trigger;
|
||||
pg:group myprefix:loop_main_group ;
|
||||
],
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 3;
|
||||
lv2:symbol "record_led1" ;
|
||||
lv2:name "";
|
||||
lv2:portProperty lv2:toggled ;
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
pipedal_ui:ledColor "red";
|
||||
pg:group myprefix:loop_main_group ;
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 4;
|
||||
lv2:symbol "play1" ;
|
||||
lv2:name "⏵";
|
||||
rdfs:comment "Play Loop 1. Click again to stop.";
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:toggled,pprop:trigger;
|
||||
pg:group myprefix:loop_main_group ;
|
||||
],
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 5;
|
||||
lv2:symbol "play_led1" ;
|
||||
lv2:name "";
|
||||
lv2:portProperty lv2:toggled ;
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
pipedal_ui:ledColor "green";
|
||||
pg:group myprefix:loop_main_group ;
|
||||
],
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 6;
|
||||
lv2:symbol "position1" ;
|
||||
rdfs:comment "Time";
|
||||
lv2:name "\u00A0\u00A0\u00A0\u00A0";
|
||||
units:unit units:pc ;
|
||||
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0 ;
|
||||
lv2:maximum 1.0 ;
|
||||
pg:group myprefix:loop_main_group ;
|
||||
],
|
||||
|
||||
|
||||
################# Loop2
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 7;
|
||||
lv2:symbol "control2" ;
|
||||
lv2:name "MIDI Ctl";
|
||||
rdfs:comment "Hidden control for MIDI operation. See documentation for details.";
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:integer, lv2:toggled, mod:preferMomentaryOffByDefault, pprop:notOnGUI;
|
||||
pg:group myprefix:loop2_group ;
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 8;
|
||||
lv2:symbol "stop2" ;
|
||||
lv2:name "⏹";
|
||||
rdfs:comment "Reset loop 2.";
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:toggled,pprop:trigger;
|
||||
pg:group myprefix:loop2_group ;
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 9;
|
||||
lv2:symbol "record2" ;
|
||||
lv2:name "⏺";
|
||||
rdfs:comment "Record/Overdub loop 2";
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:toggled,pprop:trigger;
|
||||
pg:group myprefix:loop2_group ;
|
||||
],
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 10;
|
||||
lv2:symbol "record_led2" ;
|
||||
lv2:name "";
|
||||
lv2:portProperty lv2:toggled ;
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
pipedal_ui:ledColor "red";
|
||||
pg:group myprefix:loop2_group ;
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 11;
|
||||
lv2:symbol "play2" ;
|
||||
lv2:name "⏵";
|
||||
rdfs:comment "Play Loop 2. Click again to stop.";
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:toggled,pprop:trigger;
|
||||
pg:group myprefix:loop2_group ;
|
||||
],
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 12;
|
||||
lv2:symbol "play_led2" ;
|
||||
lv2:name "";
|
||||
lv2:portProperty lv2:toggled ;
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
pipedal_ui:ledColor "green";
|
||||
pg:group myprefix:loop2_group ;
|
||||
],
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 13;
|
||||
lv2:symbol "position2" ;
|
||||
rdfs:comment "Time";
|
||||
lv2:name "\u00A0\u00A0\u00A0\u00A0";
|
||||
units:unit units:pc ;
|
||||
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0 ;
|
||||
lv2:maximum 1.0 ;
|
||||
pg:group myprefix:loop2_group ;
|
||||
],
|
||||
|
||||
################# Loop3
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 14;
|
||||
lv2:symbol "control3" ;
|
||||
lv2:name "MIDI Ctl";
|
||||
rdfs:comment "Hidden control for MIDI operation. See documentation for details.";
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:integer, lv2:toggled, mod:preferMomentaryOffByDefault, pprop:notOnGUI;
|
||||
pg:group myprefix:loop3_group ;
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 15;
|
||||
lv2:symbol "stop3" ;
|
||||
lv2:name "⏹";
|
||||
rdfs:comment "Reset loop 3.";
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:toggled,pprop:trigger;
|
||||
pg:group myprefix:loop3_group ;
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 16;
|
||||
lv2:symbol "record3" ;
|
||||
lv2:name "⏺";
|
||||
rdfs:comment "Record/Overdub loop 3";
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:toggled,pprop:trigger;
|
||||
pg:group myprefix:loop3_group ;
|
||||
],
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 17;
|
||||
lv2:symbol "record_led3" ;
|
||||
lv2:name "";
|
||||
lv2:portProperty lv2:toggled ;
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
pipedal_ui:ledColor "red";
|
||||
pg:group myprefix:loop3_group ;
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 18;
|
||||
lv2:symbol "play3" ;
|
||||
lv2:name "⏵";
|
||||
rdfs:comment "Play Loop 3. Click again to stop.";
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:toggled,pprop:trigger;
|
||||
pg:group myprefix:loop3_group ;
|
||||
],
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 19;
|
||||
lv2:symbol "play_led3" ;
|
||||
lv2:name "";
|
||||
lv2:portProperty lv2:toggled ;
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
pipedal_ui:ledColor "green";
|
||||
pg:group myprefix:loop3_group ;
|
||||
],
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 20;
|
||||
lv2:symbol "position3" ;
|
||||
rdfs:comment "Time";
|
||||
lv2:name "\u00A0\u00A0\u00A0\u00A0";
|
||||
units:unit units:pc ;
|
||||
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0 ;
|
||||
lv2:maximum 1.0 ;
|
||||
pg:group myprefix:loop3_group ;
|
||||
],
|
||||
|
||||
|
||||
################# Loop4
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 21;
|
||||
lv2:symbol "control4" ;
|
||||
lv2:name "Midi Ctl";
|
||||
rdfs:comment "Hidden control for MIDI operation. See documentation for details.";
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:integer, lv2:toggled, mod:preferMomentaryOffByDefault, pprop:notOnGUI;
|
||||
pg:group myprefix:loop4_group ;
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 22;
|
||||
lv2:symbol "stop4" ;
|
||||
lv2:name "⏹";
|
||||
rdfs:comment "Reset loop 4.";
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:toggled,pprop:trigger;
|
||||
pg:group myprefix:loop4_group ;
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 23;
|
||||
lv2:symbol "record4" ;
|
||||
lv2:name "⏺";
|
||||
rdfs:comment "Record/Overdub loop 4";
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:toggled,pprop:trigger;
|
||||
pg:group myprefix:loop4_group ;
|
||||
],
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 24;
|
||||
lv2:symbol "record_led4" ;
|
||||
lv2:name "";
|
||||
lv2:portProperty lv2:toggled ;
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
pipedal_ui:ledColor "red";
|
||||
pg:group myprefix:loop4_group ;
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 25;
|
||||
lv2:symbol "play4" ;
|
||||
lv2:name "⏵";
|
||||
rdfs:comment "Play Loop 4. Click again to stop.";
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:toggled,pprop:trigger;
|
||||
pg:group myprefix:loop4_group ;
|
||||
],
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 26;
|
||||
lv2:symbol "play_led4" ;
|
||||
lv2:name "";
|
||||
lv2:portProperty lv2:toggled ;
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
pipedal_ui:ledColor "green";
|
||||
pg:group myprefix:loop4_group ;
|
||||
],
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 27;
|
||||
lv2:symbol "position4" ;
|
||||
rdfs:comment "Time";
|
||||
lv2:name "\u00A0\u00A0\u00A0\u00A0";
|
||||
units:unit units:pc ;
|
||||
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0 ;
|
||||
lv2:maximum 1.0 ;
|
||||
pg:group myprefix:loop4_group ;
|
||||
],
|
||||
|
||||
|
||||
###### Sync
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 28;
|
||||
lv2:symbol "bar_led" ;
|
||||
lv2:name "\u00A0\u00A0Bar\u00A0\u00A0";
|
||||
lv2:portProperty lv2:toggled ;
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
pipedal_ui:ledColor "red";
|
||||
pg:group myprefix:syncGroup ;
|
||||
],
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 29;
|
||||
lv2:symbol "beat_led" ;
|
||||
lv2:name "\u00A0Beat\u00A0";
|
||||
lv2:portProperty lv2:toggled ;
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
pipedal_ui:ledColor "red";
|
||||
pg:group myprefix:syncGroup ;
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 30;
|
||||
lv2:symbol "tempo" ;
|
||||
lv2:name "Tempo";
|
||||
lv2:default 120.0 ;
|
||||
lv2:minimum 40.0;
|
||||
lv2:maximum 240.0;
|
||||
units:unit units:bpm;
|
||||
rdfs:comment "Tempo in quarter-notes per minute"
|
||||
; pg:group myprefix:syncGroup
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 31 ;
|
||||
lv2:symbol "timesig" ;
|
||||
rdfs:comment "Time Signature";
|
||||
lv2:name "TimeSig";
|
||||
lv2:default 2 ;
|
||||
lv2:minimum 0;
|
||||
lv2:maximum 5;
|
||||
lv2:portProperty lv2:enumeration ;
|
||||
|
||||
lv2:scalePoint [
|
||||
rdfs:label "2/2" ;
|
||||
rdf:value 0
|
||||
] , [
|
||||
rdfs:label "3/4" ;
|
||||
rdf:value 1
|
||||
] , [
|
||||
rdfs:label "4/4" ;
|
||||
rdf:value 2
|
||||
] ,
|
||||
[
|
||||
rdfs:label "5/4" ;
|
||||
rdf:value 3
|
||||
] ,
|
||||
[
|
||||
rdfs:label "6/8" ;
|
||||
rdf:value 4
|
||||
] ,
|
||||
[
|
||||
rdfs:label "7/4" ;
|
||||
rdf:value 5
|
||||
];
|
||||
pg:group myprefix:syncGroup
|
||||
],
|
||||
|
||||
########## Options
|
||||
|
||||
[
|
||||
lv2:name "Count In" ;
|
||||
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 32;
|
||||
lv2:symbol "rec_count_in" ;
|
||||
lv2:default 1.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:toggled;
|
||||
rdfs:comment "Whether to count in when starting the main loop.";
|
||||
|
||||
pg:group myprefix:options_group ;
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 33 ;
|
||||
lv2:symbol "bars" ;
|
||||
lv2:name "Bars";
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0;
|
||||
lv2:maximum 32;
|
||||
units:unit units:bar ;
|
||||
lv2:portProperty lv2:integer;
|
||||
rdfs:comment "Loop length in bars. Set to minimum for arbitrary length loops.";
|
||||
pg:group myprefix:options_group ;
|
||||
lv2:scalePoint [
|
||||
rdfs:label "Free" ;
|
||||
rdf:value 0.0
|
||||
]
|
||||
],
|
||||
[
|
||||
lv2:name "Rec Sync" ;
|
||||
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 34;
|
||||
lv2:symbol "rec_sync_option" ;
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:toggled;
|
||||
rdfs:comment "Whether to sync the start of the loop with the main loop when recording secondary loops.";
|
||||
|
||||
pg:group myprefix:options_group ;
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 35;
|
||||
lv2:symbol "loop_end_option" ;
|
||||
lv2:name "On Rec End";
|
||||
lv2:default 1.0 ;
|
||||
lv2:minimum 1.0;
|
||||
lv2:maximum 2.0;
|
||||
lv2:portProperty lv2:enumeration;
|
||||
rdfs:comment "(One-control MIDI operation only) Whether to go to OVERDUB or PLAY state when recording of the main loop ends.";
|
||||
|
||||
lv2:scalePoint [
|
||||
rdfs:label "REC->PLAY" ;
|
||||
rdf:value 1.0
|
||||
] , [
|
||||
rdfs:label "REC->DUB" ;
|
||||
rdf:value 2.0
|
||||
] ;
|
||||
|
||||
pg:group myprefix:options_group ;
|
||||
],
|
||||
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 36;
|
||||
lv2:symbol "level" ;
|
||||
lv2:name "Level";
|
||||
lv2:name "Level";
|
||||
pg:group myprefix:output_group ;
|
||||
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum -60.0;
|
||||
lv2:maximum 30.0;
|
||||
lv2:scalePoint [
|
||||
rdfs:label "-INF" ;
|
||||
rdf:value -60.0
|
||||
];
|
||||
units:unit units:db
|
||||
],
|
||||
|
||||
################# Audio/Control Busses
|
||||
|
||||
[
|
||||
a lv2:AudioPort ,
|
||||
lv2:InputPort ;
|
||||
lv2:index 37 ;
|
||||
lv2:symbol "in" ;
|
||||
lv2:name "In";
|
||||
pg:group myprefix:stereoInGroup ;
|
||||
lv2:designation pg:left
|
||||
|
||||
],
|
||||
[
|
||||
a lv2:AudioPort ,
|
||||
lv2:OutputPort ;
|
||||
lv2:index 38 ;
|
||||
lv2:symbol "out" ;
|
||||
lv2:name "Out" ;
|
||||
pg:group myprefix:stereoOutGroup ;
|
||||
lv2:designation pg:left
|
||||
],
|
||||
|
||||
[
|
||||
a atom:AtomPort ,
|
||||
lv2:InputPort ;
|
||||
lv2:index 39 ;
|
||||
atom:bufferType atom:Sequence ;
|
||||
atom:supports patch:Message;
|
||||
|
||||
lv2:symbol "controlIn" ;
|
||||
lv2:name "ControlIn"
|
||||
],
|
||||
[
|
||||
a atom:AtomPort ,
|
||||
lv2:OutputPort ;
|
||||
lv2:index 40 ;
|
||||
atom:bufferType atom:Sequence ;
|
||||
atom:supports patch:Message;
|
||||
lv2:symbol "controlOut" ;
|
||||
lv2:name "ControlOut"
|
||||
],
|
||||
[
|
||||
a lv2:AudioPort ,
|
||||
lv2:InputPort ;
|
||||
lv2:index 41;
|
||||
lv2:symbol "inR" ;
|
||||
lv2:name "InR" ;
|
||||
pg:group myprefix:stereoInGroup ;
|
||||
lv2:designation pg:right
|
||||
|
||||
],
|
||||
[
|
||||
a lv2:AudioPort ,
|
||||
lv2:OutputPort ;
|
||||
lv2:index 42 ;
|
||||
lv2:symbol "outR" ;
|
||||
lv2:name "OutR" ;
|
||||
pg:group myprefix:stereoOutGroup ;
|
||||
lv2:designation pg:right
|
||||
]
|
||||
|
||||
|
||||
;
|
||||
|
||||
.
|
||||
|
||||
|
||||
|
||||
<http://two-play.com/plugins/toob-looper-four-ui>
|
||||
a ui:X11UI ;
|
||||
lv2:binary <ToobAmpUI.so>;
|
||||
|
||||
lv2:extensionData ui:resize ;
|
||||
lv2:extensionData ui:idleInterface ;
|
||||
lv2:requiredFeature ui:idleInterface ;
|
||||
.
|
||||
|
||||
|
||||
@@ -0,0 +1,606 @@
|
||||
@prefix doap: <http://usefulinc.com/ns/doap#> .
|
||||
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
|
||||
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
||||
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
|
||||
@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 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 atom: <http://lv2plug.in/ns/ext/atom#> .
|
||||
@prefix patch: <http://lv2plug.in/ns/ext/patch#> .
|
||||
@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 ui: <http://lv2plug.in/ns/extensions/ui#> .
|
||||
@prefix uiext: <http://lv2plug.in/ns/extensions/ui#> .
|
||||
@prefix pprop: <http://lv2plug.in/ns/ext/port-props#> .
|
||||
@prefix pipedal_ui: <http://github.com/rerdavies/pipedal/ui#> .
|
||||
|
||||
@prefix myprefix: <http://two-play.com/plugins/toob-looper-one#> .
|
||||
|
||||
|
||||
myprefix:stereoInGroup
|
||||
a pg:StereoGroup, pg:InputGroup ;
|
||||
rdfs:label "Stereo Input" ;
|
||||
lv2:symbol "in_g" .
|
||||
|
||||
myprefix:steroOutGroup a pg:Group ;
|
||||
a pg:StereoGroup, pg:OuputGroup ;
|
||||
rdfs:label "Stereo Output" ;
|
||||
lv2:symbol "out_g" .
|
||||
|
||||
|
||||
myprefix:syncGroup
|
||||
a pg:ControlGroup ;
|
||||
lv2:name "Clock" ;
|
||||
lv2:symbol "sync_g" .
|
||||
|
||||
|
||||
myprefix:loop_main_group
|
||||
a pg:ControlGroup ;
|
||||
lv2:name "Control" ;
|
||||
lv2:symbol "loop_main_group" .
|
||||
|
||||
|
||||
myprefix:options_group
|
||||
a pg:ControlGroup ;
|
||||
lv2:name "Record Options" ;
|
||||
lv2:symbol "options_group" .
|
||||
|
||||
myprefix:output_group
|
||||
a pg:ControlGroup ;
|
||||
lv2:name "Output" ;
|
||||
lv2:symbol "output_group" .
|
||||
|
||||
|
||||
|
||||
<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> .
|
||||
|
||||
|
||||
<http://two-play.com/plugins/toob-looper-one>
|
||||
a lv2:Plugin ,
|
||||
lv2:UtilityPlugin ;
|
||||
doap:name "TooB One-Button Looper (stereo)"
|
||||
;
|
||||
|
||||
|
||||
doap:license <https://opensource.org/license/mit/> ;
|
||||
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
||||
lv2:minorVersion 1 ;
|
||||
lv2:microVersion 58 ;
|
||||
|
||||
ui:ui <http://two-play.com/plugins/toob-looper-one-ui>;
|
||||
|
||||
|
||||
lv2:extensionData state:interface ;
|
||||
|
||||
rdfs:comment """
|
||||
## TooB One-Button Looper.
|
||||
|
||||
TooB One-Button Looper is designed to be controlled by a single MIDI foot controller. If you will be controlling your looper from a screen user-interface, use Toob 4Looper instead.
|
||||
|
||||
### Basic Operation
|
||||
|
||||
To use the One-Button Looper with PiPedal, bind a MIDI foot switch to the control port using the PiPedal MIDI Bindings user-interface. It's easiest to configure
|
||||
the MIDI foot controller to send Note-On/Note-Off midi messages, since the control values that a MIDI foot controller sends may not be consistent with what the
|
||||
One-Button Looper expects. However, if you must use a MIDI foot controller that sends Control Change messages, then you must configure the MIDI foot controller
|
||||
to send a CC value of zero when not pressed, and a non-zero value when pressed.
|
||||
|
||||
|
||||
Loop overdubs are stored in a stack, so that they can be erased one at a time. To erase the most recent overdub, and return to the previous state of the loop,
|
||||
long-press the MIDI controller (or the Control button if you are using the PiPedal user interface). A long-press is a press of at least 1/2 second, but
|
||||
less than two seconds. The current loop will be undone when you release the control. To stop looping altogether, press the MIDI foot controller (or the Control button) for at least two seconds. The looper will stop when you
|
||||
release the control.
|
||||
|
||||
### Clock Options
|
||||
|
||||
Clock options determine the tempo and number of beats in a bar. They affect the behavior of the looper when the Bars control (see below) is set to
|
||||
a numeric value, and also affect the rate of the flashing LEDs when counting in.
|
||||
|
||||
### Record Options
|
||||
|
||||
Record Options control the behavior of the looper.
|
||||
|
||||
When Count In is enabled, The looper will Count In before starting the main loop. The Record LED will flash when counting in, and go solid
|
||||
once recording starts. The pattern of blinking lights depends on the TimeSig setting, so for example, if the Time Signature is set to 4/4, the
|
||||
blinking LED will signal a count-in pattern of "1 - 2 - 1 2 3 4".
|
||||
|
||||
When Bars is set to Free (the minimum value), the length of the main loop will be set by the second tap of the
|
||||
Control button after recording of the main loop starts. If Bars is set to a numeric value, the length of the main loop will be determined by the number
|
||||
of bars set in the Bars control, and the current settings of the Clock controls.
|
||||
|
||||
If Dub Sync is off, overdubs will start recording as soon as you tap the Control button. If enabled, the start
|
||||
of the secondary loop will sync with main loop. Tapping the Control button will put the looper in "Cue Overdub" state
|
||||
and the LEDs will flash until the end of the main loop is reached, at which point the new loop will start recording.
|
||||
|
||||
The Loop End option only has effect when the Bars control is set to a numeric value, and does nothing if Bars is set to "Free".
|
||||
When set to REC-PLAY, the main loop will record exactly N bars of audio, and switch to play mode when the end of the loop is reached.
|
||||
When set to REC-DUB, the main loop will record exactly N bars of audio, and then continue on in overdub mode.
|
||||
|
||||
### Looper State Table
|
||||
|
||||
```
|
||||
+-----------+--------------+----------------------------------+
|
||||
| State | Action | Effect |
|
||||
|-----------|--------------|----------------------------------|
|
||||
| Empty | Tap | Start counting in if COUNT IN is |
|
||||
| | | enabled; otherwise start |
|
||||
| | | recording immediately. |
|
||||
|-----------|--------------|----------------------------------|
|
||||
| Count-In | Tap/ | Return to empty state |
|
||||
| | Long-press | |
|
||||
| | | |
|
||||
| | Complete | Start recording |
|
||||
|-----------|--------------|----------------------------------|
|
||||
| Recording | Tap | Set the loop length and go to |
|
||||
| | | play state. |
|
||||
| | | |
|
||||
| | Long-press | Discard the current loop and |
|
||||
| | | return to Empty state |
|
||||
| | | |
|
||||
| | End of loop | go to play or overdub state |
|
||||
| | | depending on ON REC END |
|
||||
|-----------|--------------|----------------------------------|
|
||||
| Playing | Tap | If DUB SYNC is on, go to |
|
||||
| | | Cue Ovdb state; otherwise |
|
||||
| | | start overdubbing immediately. |
|
||||
| | | |
|
||||
| | Long-press | Undo the most recent |
|
||||
| | | overdub and go to play |
|
||||
| | | state. |
|
||||
|-----------|--------------|----------------------------------|
|
||||
| Cue Ovdb | End-of-loop | Start overdubbing. |
|
||||
| | | |
|
||||
| | Tap | Cancel the pending overdub. |
|
||||
| | | |
|
||||
| | Long-press | Cancel the pending overdub. |
|
||||
|-----------|--------------|----------------------------------|
|
||||
| Overdub | Tap | Start playing. |
|
||||
| | | |
|
||||
| | End of loop | (If DUB SYNC is on, and |
|
||||
| | | REC->PLAY is selected) Go to |
|
||||
| | | play state, otherwise, continue |
|
||||
| | | in overdub state. |
|
||||
+-----------|--------------|----------------------------------+
|
||||
```
|
||||
|
||||
""" ;
|
||||
|
||||
mod:brand "TooB";
|
||||
mod:label "One-Looper";
|
||||
lv2:optionalFeature lv2:hardRTCapable;
|
||||
|
||||
lv2:port
|
||||
################# MAIN Loop
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 0;
|
||||
lv2:symbol "control" ;
|
||||
lv2:name "〇";
|
||||
rdfs:comment "Looper control. See the plugin documentation for details.";
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:integer, lv2:toggled, mod:preferMomentaryOffByDefault;
|
||||
pg:group myprefix:loop_main_group ;
|
||||
],
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 1;
|
||||
lv2:symbol "record_led" ;
|
||||
lv2:name "";
|
||||
lv2:portProperty lv2:toggled ;
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
pipedal_ui:ledColor "red";
|
||||
pg:group myprefix:loop_main_group ;
|
||||
],
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 2 ;
|
||||
lv2:symbol "play_led" ;
|
||||
lv2:name "";
|
||||
lv2:portProperty lv2:toggled ;
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
pg:group myprefix:loop_main_group ;
|
||||
pipedal_ui:ledColor "green";
|
||||
],
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 3;
|
||||
lv2:symbol "position" ;
|
||||
rdfs:comment "Loop position";
|
||||
lv2:name "\u00A0\u00A0\u00A0\u00A0";
|
||||
units:unit units:pc ;
|
||||
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0 ;
|
||||
lv2:maximum 1.0 ;
|
||||
pg:group myprefix:loop_main_group ;
|
||||
],
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 4;
|
||||
lv2:symbol "loop_level" ;
|
||||
rdfs:comment "Loop Level";
|
||||
lv2:name "\u00A0\u00A0\u00A0\u00A0";
|
||||
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0 ;
|
||||
lv2:maximum 21.0 ;
|
||||
pg:group myprefix:loop_main_group ;
|
||||
lv2:portProperty lv2:enumeration ;
|
||||
|
||||
lv2:scalePoint [
|
||||
rdfs:label "-" ;
|
||||
rdf:value 0.0
|
||||
] ,
|
||||
[
|
||||
rdfs:label "1" ;
|
||||
rdf:value 1.0
|
||||
],
|
||||
[
|
||||
rdfs:label "2" ;
|
||||
rdf:value 2.0
|
||||
],
|
||||
[
|
||||
rdfs:label "3" ;
|
||||
rdf:value 3.0
|
||||
],
|
||||
[
|
||||
rdfs:label "4" ;
|
||||
rdf:value 4.0
|
||||
],
|
||||
[
|
||||
rdfs:label "5" ;
|
||||
rdf:value 5.0
|
||||
],
|
||||
[
|
||||
rdfs:label "6" ;
|
||||
rdf:value 6.0
|
||||
],
|
||||
[
|
||||
rdfs:label "7" ;
|
||||
rdf:value 7.0
|
||||
],
|
||||
[
|
||||
rdfs:label "8" ;
|
||||
rdf:value 8.0
|
||||
],
|
||||
[
|
||||
rdfs:label "9" ;
|
||||
rdf:value 9.0
|
||||
],
|
||||
[
|
||||
rdfs:label "10" ;
|
||||
rdf:value 10.0
|
||||
],
|
||||
[
|
||||
rdfs:label "11" ;
|
||||
rdf:value 11.0
|
||||
],
|
||||
[
|
||||
rdfs:label "12" ;
|
||||
rdf:value 12.0
|
||||
],
|
||||
[
|
||||
rdfs:label "13" ;
|
||||
rdf:value 13.0
|
||||
],
|
||||
[
|
||||
rdfs:label "14" ;
|
||||
rdf:value 14.0
|
||||
],
|
||||
[
|
||||
rdfs:label "15" ;
|
||||
rdf:value 15.0
|
||||
],
|
||||
[
|
||||
rdfs:label "16" ;
|
||||
rdf:value 16.0
|
||||
],
|
||||
[
|
||||
rdfs:label "17" ;
|
||||
rdf:value 17.0
|
||||
],
|
||||
[
|
||||
rdfs:label "18" ;
|
||||
rdf:value 18.0
|
||||
],
|
||||
[
|
||||
rdfs:label "19" ;
|
||||
rdf:value 19.0
|
||||
],
|
||||
[
|
||||
rdfs:label "20" ;
|
||||
rdf:value 20.0
|
||||
],
|
||||
[
|
||||
rdfs:label "+" ;
|
||||
rdf:value 21.0
|
||||
]
|
||||
;
|
||||
|
||||
],
|
||||
|
||||
|
||||
###### Sync
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 5;
|
||||
lv2:symbol "bar_led" ;
|
||||
lv2:name "\u00A0\u00A0Bar\u00A0\u00A0";
|
||||
lv2:portProperty lv2:toggled ;
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
pipedal_ui:ledColor "red";
|
||||
pg:group myprefix:syncGroup ;
|
||||
],
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 6;
|
||||
lv2:symbol "beat_led" ;
|
||||
lv2:name "\u00A0Beat\u00A0";
|
||||
lv2:portProperty lv2:toggled ;
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
pipedal_ui:ledColor "red";
|
||||
pg:group myprefix:syncGroup ;
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 7;
|
||||
lv2:symbol "tempo" ;
|
||||
lv2:name "Tempo";
|
||||
lv2:default 120.0 ;
|
||||
lv2:minimum 40.0;
|
||||
lv2:maximum 240.0;
|
||||
units:unit units:bpm;
|
||||
rdfs:comment "Tempo in quarter-notes per minute"
|
||||
; pg:group myprefix:syncGroup
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 8;
|
||||
lv2:symbol "timesig" ;
|
||||
rdfs:comment "Time Signature";
|
||||
lv2:name "TimeSig";
|
||||
lv2:default 2 ;
|
||||
lv2:minimum 0;
|
||||
lv2:maximum 5;
|
||||
lv2:portProperty lv2:enumeration ;
|
||||
|
||||
lv2:scalePoint [
|
||||
rdfs:label "2/2" ;
|
||||
rdf:value 0
|
||||
] , [
|
||||
rdfs:label "3/4" ;
|
||||
rdf:value 1
|
||||
] , [
|
||||
rdfs:label "4/4" ;
|
||||
rdf:value 2
|
||||
] ,
|
||||
[
|
||||
rdfs:label "5/4" ;
|
||||
rdf:value 3
|
||||
] ,
|
||||
[
|
||||
rdfs:label "6/8" ;
|
||||
rdf:value 4
|
||||
] ,
|
||||
[
|
||||
rdfs:label "7/4" ;
|
||||
rdf:value 5
|
||||
];
|
||||
pg:group myprefix:syncGroup
|
||||
],
|
||||
|
||||
########## Options
|
||||
|
||||
[
|
||||
lv2:name "Count In" ;
|
||||
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 9;
|
||||
lv2:symbol "rec_count_in" ;
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:toggled;
|
||||
rdfs:comment "Whether to count in when starting the main loop.";
|
||||
|
||||
pg:group myprefix:options_group ;
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 10;
|
||||
lv2:symbol "bars" ;
|
||||
lv2:name "Bars";
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0 ;
|
||||
lv2:maximum 32.0 ;
|
||||
units:unit units:bar ;
|
||||
lv2:portProperty lv2:integer;
|
||||
rdfs:comment "Loop length in bars. Set to minimum for arbitrary length loops.";
|
||||
pg:group myprefix:options_group ;
|
||||
lv2:scalePoint [
|
||||
rdfs:label "Free" ;
|
||||
rdf:value 0.0 ;
|
||||
] ;
|
||||
],
|
||||
[
|
||||
lv2:name "Dub Sync" ;
|
||||
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 11;
|
||||
lv2:symbol "rec_sync_option" ;
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:toggled;
|
||||
rdfs:comment "Whether to sync the start of the loop with the main loop when recording secondary loops.";
|
||||
|
||||
pg:group myprefix:options_group ;
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 12;
|
||||
lv2:symbol "loop_end_option" ;
|
||||
lv2:name "On Rec End";
|
||||
lv2:default 1.0 ;
|
||||
lv2:minimum 1.0;
|
||||
lv2:maximum 2.0;
|
||||
lv2:portProperty lv2:enumeration;
|
||||
rdfs:comment "Whether to go to OVERDUB or PLAY state a loop ends.";
|
||||
|
||||
lv2:scalePoint [
|
||||
rdfs:label "REC->PLAY" ;
|
||||
rdf:value 1.0
|
||||
] , [
|
||||
rdfs:label "REC->DUB" ;
|
||||
rdf:value 2.0
|
||||
] ;
|
||||
|
||||
pg:group myprefix:options_group ;
|
||||
],
|
||||
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 13;
|
||||
lv2:symbol "level" ;
|
||||
lv2:name "Level";
|
||||
lv2:name "Level";
|
||||
pg:group myprefix:output_group ;
|
||||
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum -60.0;
|
||||
lv2:maximum 30.0;
|
||||
lv2:scalePoint [
|
||||
rdfs:label "-INF" ;
|
||||
rdf:value -60.0
|
||||
];
|
||||
units:unit units:db
|
||||
],
|
||||
|
||||
################# Audio/Control Busses
|
||||
|
||||
[
|
||||
a lv2:AudioPort ,
|
||||
lv2:InputPort ;
|
||||
lv2:index 14 ;
|
||||
lv2:symbol "in" ;
|
||||
lv2:name "In";
|
||||
pg:group myprefix:stereoInGroup ;
|
||||
lv2:designation pg:left
|
||||
|
||||
],
|
||||
[
|
||||
a lv2:AudioPort ,
|
||||
lv2:OutputPort ;
|
||||
lv2:index 15 ;
|
||||
lv2:symbol "out" ;
|
||||
lv2:name "Out" ;
|
||||
pg:group myprefix:stereoOutGroup ;
|
||||
lv2:designation pg:left
|
||||
],
|
||||
|
||||
[
|
||||
a atom:AtomPort ,
|
||||
lv2:InputPort ;
|
||||
atom:bufferType atom:Sequence ;
|
||||
atom:supports patch:Message;
|
||||
|
||||
lv2:index 16 ;
|
||||
lv2:symbol "controlIn" ;
|
||||
lv2:name "ControlIn"
|
||||
],
|
||||
[
|
||||
a atom:AtomPort ,
|
||||
lv2:OutputPort ;
|
||||
atom:bufferType atom:Sequence ;
|
||||
atom:supports patch:Message;
|
||||
lv2:index 17 ;
|
||||
lv2:symbol "controlOut" ;
|
||||
lv2:name "ControlOut"
|
||||
],
|
||||
[
|
||||
a lv2:AudioPort ,
|
||||
lv2:InputPort ;
|
||||
lv2:index 18;
|
||||
lv2:symbol "inR" ;
|
||||
lv2:name "InR" ;
|
||||
pg:group myprefix:stereoInGroup ;
|
||||
lv2:designation pg:right
|
||||
|
||||
],
|
||||
[
|
||||
a lv2:AudioPort ,
|
||||
lv2:OutputPort ;
|
||||
lv2:index 19 ;
|
||||
lv2:symbol "outR" ;
|
||||
lv2:name "OutR" ;
|
||||
pg:group myprefix:stereoOutGroup ;
|
||||
lv2:designation pg:right
|
||||
]
|
||||
|
||||
|
||||
;
|
||||
|
||||
.
|
||||
|
||||
|
||||
|
||||
<http://two-play.com/plugins/toob-looper-one-ui>
|
||||
a ui:X11UI ;
|
||||
lv2:binary <ToobAmpUI.so>;
|
||||
|
||||
|
||||
lv2:extensionData ui:resize ;
|
||||
lv2:extensionData ui:idleInterface ;
|
||||
lv2:requiredFeature ui:idleInterface ;
|
||||
.
|
||||
|
||||
@@ -0,0 +1,726 @@
|
||||
@prefix doap: <http://usefulinc.com/ns/doap#> .
|
||||
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
|
||||
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
||||
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
|
||||
@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 atom: <http://lv2plug.in/ns/ext/atom#> .
|
||||
@prefix patch: <http://lv2plug.in/ns/ext/patch#> .
|
||||
@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 ui: <http://lv2plug.in/ns/extensions/ui#> .
|
||||
@prefix pprop: <http://lv2plug.in/ns/ext/port-props#> .
|
||||
@prefix pipedal_ui: <http://github.com/rerdavies/pipedal/ui#> .
|
||||
|
||||
|
||||
@prefix looperPrefix: <http://two-play.com/plugins/toob-looper#> .
|
||||
|
||||
@prefix myprefix: <http://two-play.com/plugins/toob-looper-stereo#> .
|
||||
|
||||
|
||||
myprefix:stereoInGroup
|
||||
a pg:StereoGroup, pg:InputGroup ;
|
||||
rdfs:label "Stereo Input" ;
|
||||
lv2:symbol "in_g" .
|
||||
|
||||
myprefix:steroOutGroup a pg:Group ;
|
||||
a pg:StereoGroup, pg:OuputGroup ;
|
||||
rdfs:label "Stereo Output" ;
|
||||
lv2:symbol "out_g" .
|
||||
|
||||
|
||||
myprefix:syncGroup
|
||||
a pg:ControlGroup ;
|
||||
lv2:name "Clock" ;
|
||||
lv2:symbol "sync_g" .
|
||||
|
||||
|
||||
myprefix:loop_main_group
|
||||
a pg:ControlGroup ;
|
||||
lv2:name "Main Loop" ;
|
||||
lv2:symbol "loop_main_group" .
|
||||
|
||||
myprefix:loop2_group
|
||||
a pg:ControlGroup ;
|
||||
lv2:name "Loop 2" ;
|
||||
lv2:symbol "loop2_group" .
|
||||
|
||||
myprefix:loop3_group
|
||||
a pg:ControlGroup ;
|
||||
lv2:name "Loop 3" ;
|
||||
lv2:symbol "loop3_group" .
|
||||
|
||||
myprefix:loop4_group
|
||||
a pg:ControlGroup ;
|
||||
lv2:name "Loop 4" ;
|
||||
lv2:symbol "loop4_group" .
|
||||
|
||||
myprefix:options_group
|
||||
a pg:ControlGroup ;
|
||||
lv2:name "Options" ;
|
||||
lv2:symbol "options_group" .
|
||||
|
||||
myprefix:output_group
|
||||
a pg:ControlGroup ;
|
||||
lv2:name "Output" ;
|
||||
lv2:symbol "output_group" .
|
||||
|
||||
|
||||
|
||||
<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> .
|
||||
|
||||
|
||||
<http://two-play.com/plugins/toob-looper-stereo>
|
||||
a lv2:Plugin ,
|
||||
lv2:UtilityPlugin ;
|
||||
doap:name "TooB 4Looper (stereo)"
|
||||
;
|
||||
doap:license <https://opensource.org/license/mit/> ;
|
||||
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
||||
lv2:minorVersion 1 ;
|
||||
lv2:microVersion 57 ;
|
||||
|
||||
ui:ui <http://two-play.com/plugins/toob-looper-stereo-ui>;
|
||||
|
||||
patch:readable
|
||||
looperPrefix:audioFile;
|
||||
patch:writable
|
||||
looperPrefix:audioFile;
|
||||
|
||||
lv2:extensionData state:interface ;
|
||||
|
||||
rdfs:comment """
|
||||
A Stereo Looper.
|
||||
|
||||
- A single tap on the bound midi controller will start recording.
|
||||
- A second tap with mark the end of the loop, and start playback.
|
||||
- Subsequent taps will toggle overdub mode. When overdubbing, new audio input will be blended with the existing loop.
|
||||
- A touble tap will stop playback.
|
||||
- To erase an overdub, long press the MIDI controller. The loop will return to the state that it was in before the overdub was made.
|
||||
|
||||
|
||||
|
||||
""" ;
|
||||
|
||||
mod:brand "TooB";
|
||||
mod:label "4Looper";
|
||||
lv2:optionalFeature lv2:hardRTCapable;
|
||||
|
||||
lv2:port
|
||||
################# MAIN Loop
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 0;
|
||||
lv2:symbol "stop1" ;
|
||||
lv2:name "⏹";
|
||||
rdfs:comment "Reset loop 1.";
|
||||
lv2:default 0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:toggled,pprop:trigger;
|
||||
pg:group myprefix:loop_main_group ;
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 1;
|
||||
lv2:symbol "record1" ;
|
||||
lv2:name "⏺";
|
||||
rdfs:comment "Record/Overdub loop 1";
|
||||
lv2:default 0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:toggled,pprop:trigger;
|
||||
pg:group myprefix:loop_main_group ;
|
||||
],
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 2;
|
||||
lv2:symbol "record_led1" ;
|
||||
lv2:name "";
|
||||
lv2:portProperty lv2:toggled ;
|
||||
lv2:default 0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
pipedal_ui:ledColor "red";
|
||||
pg:group myprefix:loop_main_group ;
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 3;
|
||||
lv2:symbol "play1" ;
|
||||
lv2:name "⏵";
|
||||
rdfs:comment "Play Loop 1. Click again to stop.";
|
||||
lv2:default 0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:toggled,pprop:trigger;
|
||||
pg:group myprefix:loop_main_group ;
|
||||
],
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 4;
|
||||
lv2:symbol "play_led1" ;
|
||||
lv2:name "";
|
||||
lv2:portProperty lv2:toggled ;
|
||||
lv2:default 0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
pipedal_ui:ledColor "green";
|
||||
pg:group myprefix:loop_main_group ;
|
||||
],
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 5;
|
||||
lv2:symbol "position1" ;
|
||||
rdfs:comment "Time";
|
||||
lv2:name "\u00A0\u00A0\u00A0\u00A0";
|
||||
units:unit units:pc ;
|
||||
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0 ;
|
||||
lv2:maximum 100.0 ;
|
||||
pg:group myprefix:loop_main_group ;
|
||||
],
|
||||
|
||||
|
||||
################# Loop2
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 6;
|
||||
lv2:symbol "stop2" ;
|
||||
lv2:name "⏹";
|
||||
rdfs:comment "Reset loop 2.";
|
||||
lv2:default 0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:toggled,pprop:trigger;
|
||||
pg:group myprefix:loop2_group ;
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 7;
|
||||
lv2:symbol "record2" ;
|
||||
lv2:name "⏺";
|
||||
rdfs:comment "Record/Overdub loop 2";
|
||||
lv2:default 0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:toggled,pprop:trigger;
|
||||
pg:group myprefix:loop2_group ;
|
||||
],
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 8;
|
||||
lv2:symbol "record_led2" ;
|
||||
lv2:name "";
|
||||
lv2:portProperty lv2:toggled ;
|
||||
lv2:default 0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
pipedal_ui:ledColor "red";
|
||||
pg:group myprefix:loop2_group ;
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 9;
|
||||
lv2:symbol "play2" ;
|
||||
lv2:name "⏵";
|
||||
rdfs:comment "Play Loop 2. Click again to stop.";
|
||||
lv2:default 0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:toggled,pprop:trigger;
|
||||
pg:group myprefix:loop2_group ;
|
||||
],
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 10;
|
||||
lv2:symbol "play_led2" ;
|
||||
lv2:name "";
|
||||
lv2:portProperty lv2:toggled ;
|
||||
lv2:default 0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
pipedal_ui:ledColor "green";
|
||||
pg:group myprefix:loop2_group ;
|
||||
],
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 11;
|
||||
lv2:symbol "position2" ;
|
||||
rdfs:comment "Time";
|
||||
lv2:name "\u00A0\u00A0\u00A0\u00A0";
|
||||
units:unit units:pc ;
|
||||
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0 ;
|
||||
lv2:maximum 100.0 ;
|
||||
pg:group myprefix:loop2_group ;
|
||||
],
|
||||
|
||||
################# Loop3
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 12;
|
||||
lv2:symbol "stop3" ;
|
||||
lv2:name "⏹";
|
||||
rdfs:comment "Reset loop 3.";
|
||||
lv2:default 0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:toggled,pprop:trigger;
|
||||
pg:group myprefix:loop3_group ;
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 13;
|
||||
lv2:symbol "record3" ;
|
||||
lv2:name "⏺";
|
||||
rdfs:comment "Record/Overdub loop 3";
|
||||
lv2:default 0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:toggled,pprop:trigger;
|
||||
pg:group myprefix:loop3_group ;
|
||||
],
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 14;
|
||||
lv2:symbol "record_led3" ;
|
||||
lv2:name "";
|
||||
lv2:portProperty lv2:toggled ;
|
||||
lv2:default 0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
pipedal_ui:ledColor "red";
|
||||
pg:group myprefix:loop3_group ;
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 15;
|
||||
lv2:symbol "play3" ;
|
||||
lv2:name "⏵";
|
||||
rdfs:comment "Play Loop 3. Click again to stop.";
|
||||
lv2:default 0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:toggled,pprop:trigger;
|
||||
pg:group myprefix:loop3_group ;
|
||||
],
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 16;
|
||||
lv2:symbol "play_led3" ;
|
||||
lv2:name "";
|
||||
lv2:portProperty lv2:toggled ;
|
||||
lv2:default 0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
pipedal_ui:ledColor "green";
|
||||
pg:group myprefix:loop3_group ;
|
||||
],
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 17;
|
||||
lv2:symbol "position3" ;
|
||||
rdfs:comment "Time";
|
||||
lv2:name "\u00A0\u00A0\u00A0\u00A0";
|
||||
units:unit units:pc ;
|
||||
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0 ;
|
||||
lv2:maximum 100.0 ;
|
||||
pg:group myprefix:loop3_group ;
|
||||
],
|
||||
|
||||
|
||||
################# Loop4
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 18;
|
||||
lv2:symbol "stop4" ;
|
||||
lv2:name "⏹";
|
||||
rdfs:comment "Reset loop 4.";
|
||||
lv2:default 0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:toggled,pprop:trigger;
|
||||
pg:group myprefix:loop4_group ;
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 19;
|
||||
lv2:symbol "record4" ;
|
||||
lv2:name "⏺";
|
||||
rdfs:comment "Record/Overdub loop 4";
|
||||
lv2:default 0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:toggled,pprop:trigger;
|
||||
pg:group myprefix:loop4_group ;
|
||||
],
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 20;
|
||||
lv2:symbol "record_led4" ;
|
||||
lv2:name "";
|
||||
lv2:portProperty lv2:toggled ;
|
||||
lv2:default 0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
pipedal_ui:ledColor "red";
|
||||
pg:group myprefix:loop4_group ;
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 21;
|
||||
lv2:symbol "play4" ;
|
||||
lv2:name "⏵";
|
||||
rdfs:comment "Play Loop 4. Click again to stop.";
|
||||
lv2:default 0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:toggled,pprop:trigger;
|
||||
pg:group myprefix:loop4_group ;
|
||||
],
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 22;
|
||||
lv2:symbol "play_led4" ;
|
||||
lv2:name "";
|
||||
lv2:portProperty lv2:toggled ;
|
||||
lv2:default 0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
pipedal_ui:ledColor "green";
|
||||
pg:group myprefix:loop4_group ;
|
||||
],
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 23;
|
||||
lv2:symbol "position4" ;
|
||||
rdfs:comment "Time";
|
||||
lv2:name "\u00A0\u00A0\u00A0\u00A0";
|
||||
units:unit units:pc ;
|
||||
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0 ;
|
||||
lv2:maximum 100.0 ;
|
||||
pg:group myprefix:loop4_group ;
|
||||
],
|
||||
|
||||
|
||||
###### Sync
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 24;
|
||||
lv2:symbol "bar_led" ;
|
||||
lv2:name "\u00A0\u00A0Bar\u00A0\u00A0";
|
||||
lv2:portProperty lv2:toggled ;
|
||||
lv2:default 0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
pipedal_ui:ledColor "red";
|
||||
pg:group myprefix:syncGroup ;
|
||||
],
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 25;
|
||||
lv2:symbol "beat_led" ;
|
||||
lv2:name "\u00A0Beat\u00A0";
|
||||
lv2:portProperty lv2:toggled ;
|
||||
lv2:default 0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
pipedal_ui:ledColor "red";
|
||||
pg:group myprefix:syncGroup ;
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 26;
|
||||
lv2:symbol "tempo" ;
|
||||
lv2:name "Tempo";
|
||||
lv2:default 120.0 ;
|
||||
lv2:minimum 40.0;
|
||||
lv2:maximum 240.0;
|
||||
units:unit units:bpm;
|
||||
rdfs:comment "Tempo in quarter-notes per minute"
|
||||
; pg:group myprefix:syncGroup
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 27;
|
||||
lv2:symbol "timesig" ;
|
||||
rdfs:comment "Time Signature";
|
||||
lv2:name "TimeSig";
|
||||
lv2:default 2 ;
|
||||
lv2:minimum 0;
|
||||
lv2:maximum 5;
|
||||
lv2:portProperty lv2:enumeration ;
|
||||
|
||||
lv2:scalePoint [
|
||||
rdfs:label "2/2" ;
|
||||
rdf:value 0
|
||||
] , [
|
||||
rdfs:label "3/4" ;
|
||||
rdf:value 1
|
||||
] , [
|
||||
rdfs:label "4/4" ;
|
||||
rdf:value 2
|
||||
] ,
|
||||
[
|
||||
rdfs:label "5/4" ;
|
||||
rdf:value 3
|
||||
] ,
|
||||
[
|
||||
rdfs:label "6/8" ;
|
||||
rdf:value 4
|
||||
] ,
|
||||
[
|
||||
rdfs:label "7/4" ;
|
||||
rdf:value 5
|
||||
];
|
||||
pg:group myprefix:syncGroup
|
||||
],
|
||||
|
||||
########## Options
|
||||
|
||||
[
|
||||
lv2:name "Count In" ;
|
||||
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 28;
|
||||
lv2:symbol "rec_count_in" ;
|
||||
lv2:default 1.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:toggled;
|
||||
rdfs:comment "Whether to count in when starting the main loop.";
|
||||
|
||||
pg:group myprefix:options_group ;
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 29;
|
||||
lv2:symbol "bars" ;
|
||||
lv2:name "Bars";
|
||||
lv2:default 0 ;
|
||||
lv2:minimum 0;
|
||||
lv2:maximum 32;
|
||||
units:unit units:bar ;
|
||||
lv2:portProperty lv2:integer;
|
||||
rdfs:comment "Loop length in bars. Set to minimum for arbitrary length loops.";
|
||||
pg:group myprefix:options_group ;
|
||||
lv2:scalePoint [
|
||||
rdfs:label "Free" ;
|
||||
rdf:value 0.0
|
||||
]
|
||||
],
|
||||
[
|
||||
lv2:name "Rec Sync" ;
|
||||
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 30;
|
||||
lv2:symbol "rec_sync_option" ;
|
||||
lv2:default 1.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:toggled;
|
||||
rdfs:comment "Whether to sync the start of the loop with the main loop when recording secondary loops.";
|
||||
|
||||
pg:group myprefix:options_group ;
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 31;
|
||||
lv2:symbol "loop_end_option" ;
|
||||
lv2:name "On Rec End";
|
||||
lv2:default 1.0 ;
|
||||
lv2:minimum 1.0;
|
||||
lv2:maximum 2.0;
|
||||
lv2:portProperty lv2:enumeration;
|
||||
rdfs:comment "(One-control MIDI operation only) Whether to go to OVERDUB or PLAY state when recording of the main loop ends.";
|
||||
|
||||
lv2:scalePoint [
|
||||
rdfs:label "REC->PLAY" ;
|
||||
rdf:value 1.0
|
||||
] , [
|
||||
rdfs:label "REC->DUB" ;
|
||||
rdf:value 2.0
|
||||
] ;
|
||||
|
||||
pg:group myprefix:options_group ;
|
||||
],
|
||||
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 32;
|
||||
lv2:symbol "level" ;
|
||||
lv2:name "Level";
|
||||
lv2:name "Level";
|
||||
pg:group myprefix:output_group ;
|
||||
|
||||
lv2:default 0 ;
|
||||
lv2:minimum -60.0;
|
||||
lv2:maximum 30.0;
|
||||
lv2:scalePoint [
|
||||
rdfs:label "-INF" ;
|
||||
rdf:value -60.0
|
||||
];
|
||||
units:unit units:db
|
||||
],
|
||||
|
||||
################# Audio/Control Busses
|
||||
|
||||
[
|
||||
a lv2:AudioPort ,
|
||||
lv2:InputPort ;
|
||||
lv2:index 33 ;
|
||||
lv2:symbol "in" ;
|
||||
lv2:name "In";
|
||||
pg:group myprefix:stereoInGroup ;
|
||||
lv2:designation pg:left
|
||||
|
||||
],
|
||||
[
|
||||
a lv2:AudioPort ,
|
||||
lv2:OutputPort ;
|
||||
lv2:index 34 ;
|
||||
lv2:symbol "out" ;
|
||||
lv2:name "Out" ;
|
||||
pg:group myprefix:stereoOutGroup ;
|
||||
lv2:designation pg:left
|
||||
],
|
||||
|
||||
[
|
||||
a atom:AtomPort ,
|
||||
lv2:InputPort ;
|
||||
lv2:index 35 ;
|
||||
lv2:symbol "controlIn" ;
|
||||
lv2:name "ControlIn"
|
||||
],
|
||||
[
|
||||
a atom:AtomPort ,
|
||||
lv2:OutputPort ;
|
||||
lv2:index 36 ;
|
||||
lv2:symbol "controlOut" ;
|
||||
lv2:name "ControlOut"
|
||||
],
|
||||
[
|
||||
a lv2:AudioPort ,
|
||||
lv2:InputPort ;
|
||||
lv2:index 37;
|
||||
lv2:symbol "inR" ;
|
||||
lv2:name "InR" ;
|
||||
pg:group myprefix:stereoInGroup ;
|
||||
lv2:designation pg:right
|
||||
|
||||
],
|
||||
[
|
||||
a lv2:AudioPort ,
|
||||
lv2:OutputPort ;
|
||||
lv2:index 38 ;
|
||||
lv2:symbol "outR" ;
|
||||
lv2:name "OutR" ;
|
||||
pg:group myprefix:stereoOutGroup ;
|
||||
lv2:designation pg:right
|
||||
]
|
||||
|
||||
|
||||
;
|
||||
|
||||
.
|
||||
|
||||
|
||||
|
||||
<http://two-play.com/plugins/toob-record-stereo-ui>
|
||||
a ui:X11UI ;
|
||||
lv2:binary <.so>;
|
||||
|
||||
lv2:extensionData ui:resize ;
|
||||
lv2:extensionData ui:idleInterface ;
|
||||
lv2:requiredFeature ui:idleInterface ;
|
||||
.
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
@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 pipedal_patch: <http://github.com/rerdavies/pipedal/patch#> .
|
||||
|
||||
@prefix toob: <http://two-play.com/plugins/toob#> .
|
||||
|
||||
@prefix atom: <http://lv2plug.in/ns/ext/atom#> .
|
||||
@@ -65,7 +67,7 @@ toobml:sagGroup
|
||||
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
||||
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
||||
lv2:minorVersion 0 ;
|
||||
lv2:microVersion 57 ;
|
||||
lv2:microVersion 58 ;
|
||||
rdfs:comment """
|
||||
The TooB ML Amplifier plugin provides emulation of a variety of amplifiers and overdrive pedals that are implemented
|
||||
using neural-network-based machine learning models of real amplifiers.
|
||||
@@ -127,7 +129,7 @@ and uses model files from the GuitarML Neural Pi project (https://github.com/Gui
|
||||
patch:writable
|
||||
toobml:modelFile;
|
||||
|
||||
patch:readable
|
||||
pipedal_patch:readable
|
||||
<http://two-play.com/plugins/toob#frequencyResponseVector>
|
||||
;
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ toobNam:eqGroup
|
||||
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
||||
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
||||
lv2:minorVersion 0 ;
|
||||
lv2:microVersion 57 ;
|
||||
lv2:microVersion 58 ;
|
||||
rdfs:comment """
|
||||
A port of Steven Atkinson's Neural Amp Modeler to LV2.
|
||||
|
||||
|
||||
@@ -0,0 +1,266 @@
|
||||
@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 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 ui: <http://lv2plug.in/ns/extensions/ui#> .
|
||||
@prefix pprop: <http://lv2plug.in/ns/ext/port-props#> .
|
||||
@prefix pipedal_ui: <http://github.com/rerdavies/pipedal/ui#> .
|
||||
|
||||
|
||||
@prefix recordPrefix: <http://two-play.com/plugins/toob-record#> .
|
||||
|
||||
@prefix myprefix: <http://two-play.com/plugins/toob-record-mono#> .
|
||||
|
||||
|
||||
<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> .
|
||||
|
||||
recordPrefix:audioFile
|
||||
a lv2:Parameter;
|
||||
rdfs:label "File";
|
||||
mod:fileTypes "audiorecording,audio";
|
||||
rdfs:range atom:Path;
|
||||
lv2:index 6
|
||||
.
|
||||
|
||||
<http://two-play.com/plugins/toob-record-mono>
|
||||
a lv2:Plugin ,
|
||||
lv2:UtilityPlugin ;
|
||||
doap:name "TooB Record Input (mono)"
|
||||
;
|
||||
doap:license <https://opensource.org/license/mit/> ;
|
||||
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
||||
lv2:minorVersion 1 ;
|
||||
lv2:microVersion 58 ;
|
||||
|
||||
ui:ui <http://two-play.com/plugins/toob-record-mono-ui>;
|
||||
|
||||
patch:readable
|
||||
recordPrefix:audioFile;
|
||||
patch:writable
|
||||
recordPrefix:audioFile;
|
||||
|
||||
lv2:extensionData state:interface ;
|
||||
|
||||
rdfs:comment """
|
||||
Record the plugin's audio input signal to a monophonic file. See also: TooB Record Input (stereo), which records a stereo file.
|
||||
""" ;
|
||||
|
||||
mod:brand "TooB";
|
||||
mod:label "Record Input";
|
||||
lv2:optionalFeature lv2:hardRTCapable;
|
||||
|
||||
lv2:port
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 0;
|
||||
lv2:symbol "stop" ;
|
||||
lv2:name "⏹";
|
||||
rdfs:comment "Stop.";
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:toggled,pprop:trigger;
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 1;
|
||||
lv2:symbol "record" ;
|
||||
lv2:name "⏺";
|
||||
rdfs:comment "Start recording. Click again to stop.";
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:toggled,pprop:trigger;
|
||||
],
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 2;
|
||||
lv2:symbol "record_led" ;
|
||||
lv2:name "";
|
||||
lv2:portProperty lv2:toggled ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
pipedal_ui:ledColor "red";
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 3;
|
||||
lv2:symbol "play" ;
|
||||
lv2:name "⏵";
|
||||
rdfs:comment "Preview recorded file. Click again to stop.";
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:toggled,pprop:trigger;
|
||||
],
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 4;
|
||||
lv2:symbol "play_led" ;
|
||||
lv2:name "";
|
||||
lv2:portProperty lv2:toggled ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
pipedal_ui:ledColor "green";
|
||||
],
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 5;
|
||||
lv2:symbol "record_time" ;
|
||||
rdfs:comment "Time";
|
||||
lv2:name "";
|
||||
units:unit units:s ;
|
||||
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1000000.0;
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 6;
|
||||
lv2:symbol "fformat" ;
|
||||
lv2:name "Format";
|
||||
rdfs:comment "Recording File Format";
|
||||
|
||||
lv2:portProperty lv2:integer, lv2:enumeration ;
|
||||
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0 ;
|
||||
lv2:maximum 3 ;
|
||||
lv2:scalePoint [
|
||||
rdfs:label "WAV" ;
|
||||
rdf:value 0
|
||||
],
|
||||
[
|
||||
rdfs:label "WAV (float32)" ;
|
||||
rdf:value 1
|
||||
],
|
||||
[
|
||||
rdfs:label "FLAC" ;
|
||||
rdf:value 2;
|
||||
],
|
||||
[
|
||||
rdfs:label "MP3" ;
|
||||
rdf:value 3
|
||||
]
|
||||
;
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 7;
|
||||
lv2:symbol "level" ;
|
||||
lv2:name "Level";
|
||||
rdfs:comment "Input trim level for recording";
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum -60.0;
|
||||
lv2:maximum 30.0;
|
||||
lv2:scalePoint [
|
||||
rdfs:label "-INF" ;
|
||||
rdf:value -60.0
|
||||
];
|
||||
units:unit units:db
|
||||
|
||||
],
|
||||
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 8 ;
|
||||
lv2:symbol "level_vu" ;
|
||||
lv2:name "";
|
||||
rdfs:comment "Recording level";
|
||||
|
||||
lv2:default -60 ;
|
||||
lv2:minimum -60 ;
|
||||
lv2:maximum 20 ;
|
||||
units:unit units:db
|
||||
],
|
||||
[
|
||||
a lv2:AudioPort ,
|
||||
lv2:InputPort ;
|
||||
lv2:index 9 ;
|
||||
lv2:symbol "in" ;
|
||||
lv2:name "In"
|
||||
],
|
||||
[
|
||||
a lv2:AudioPort ,
|
||||
lv2:OutputPort ;
|
||||
lv2:index 10 ;
|
||||
lv2:symbol "out" ;
|
||||
lv2:name "Out"
|
||||
],
|
||||
|
||||
[
|
||||
a atom:AtomPort ,
|
||||
lv2:InputPort ;
|
||||
lv2:index 11 ;
|
||||
atom:bufferType atom:Sequence ;
|
||||
atom:supports patch:Message;
|
||||
lv2:designation lv2:control ;
|
||||
lv2:symbol "controlIn" ;
|
||||
lv2:name "ControlIn"
|
||||
],
|
||||
[
|
||||
a atom:AtomPort ,
|
||||
lv2:OutputPort ;
|
||||
lv2:index 12 ;
|
||||
atom:bufferType atom:Sequence ;
|
||||
atom:supports patch:Message;
|
||||
lv2:designation lv2:control ;
|
||||
|
||||
lv2:symbol "controlOut" ;
|
||||
lv2:name "ControlOut"
|
||||
]
|
||||
.
|
||||
|
||||
<http://two-play.com/plugins/toob-record-mono-ui>
|
||||
a ui:X11UI ;
|
||||
lv2:binary <ToobAmpUI.so>;
|
||||
lv2:extensionData ui:resize ;
|
||||
lv2:extensionData ui:idleInterface ;
|
||||
lv2:requiredFeature ui:idleInterface ;
|
||||
ui:portNotification [
|
||||
ui:plugin <http://two-play.com/plugins/toob-record-mono> ;
|
||||
lv2:symbol "controlOut" ;
|
||||
];
|
||||
.
|
||||
|
||||
|
||||
@@ -0,0 +1,325 @@
|
||||
@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 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 ui: <http://lv2plug.in/ns/extensions/ui#> .
|
||||
@prefix pprop: <http://lv2plug.in/ns/ext/port-props#> .
|
||||
@prefix pipedal_ui: <http://github.com/rerdavies/pipedal/ui#> .
|
||||
|
||||
@prefix recordPrefix: <http://two-play.com/plugins/toob-record#> .
|
||||
@prefix myprefix: <http://two-play.com/plugins/toob-record-stereo#> .
|
||||
|
||||
|
||||
<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> .
|
||||
|
||||
recordPrefix:audioFile
|
||||
a lv2:Parameter;
|
||||
rdfs:label "File";
|
||||
mod:fileTypes "audiorecording,audio";
|
||||
rdfs:range atom:Path;
|
||||
lv2:index 6
|
||||
.
|
||||
|
||||
myprefix:stereoInGroup
|
||||
a pg:StereoGroup, pg:InputGroup ;
|
||||
rdfs:label "Stereo Input" ;
|
||||
lv2:symbol "in_g" .
|
||||
|
||||
myprefix:steroOutGroup a pg:Group ;
|
||||
a pg:StereoGroup, pg:OuputGroup ;
|
||||
rdfs:label "Stereo Output" ;
|
||||
lv2:symbol "out_g" .
|
||||
|
||||
|
||||
myprefix:loop0_group
|
||||
a param:ControlGroup ,
|
||||
pg:InputGroup ;
|
||||
lv2:name "Master" ;
|
||||
lv2:symbol "loop0_group" .
|
||||
|
||||
myprefix:loop1_group
|
||||
a param:ControlGroup ,
|
||||
pg:InputGroup ;
|
||||
lv2:name "1" ;
|
||||
lv2:symbol "loop1_group" .
|
||||
|
||||
myprefix:loop2_group
|
||||
a param:ControlGroup ,
|
||||
pg:InputGroup ;
|
||||
lv2:name "2" ;
|
||||
lv2:symbol "loop2_group" .
|
||||
|
||||
myprefix:loop3_group
|
||||
a param:ControlGroup ,
|
||||
pg:InputGroup ;
|
||||
lv2:name "3" ;
|
||||
lv2:symbol "loop3_group" .
|
||||
|
||||
|
||||
|
||||
|
||||
<http://two-play.com/plugins/toob-record-stereo>
|
||||
a lv2:Plugin ,
|
||||
lv2:UtilityPlugin ;
|
||||
doap:name "TooB Record Input (stereo)"
|
||||
;
|
||||
doap:license <https://opensource.org/license/mit/> ;
|
||||
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
||||
lv2:minorVersion 1 ;
|
||||
lv2:microVersion 58 ;
|
||||
|
||||
ui:ui <http://two-play.com/plugins/toob-record-stereo-ui>;
|
||||
|
||||
patch:readable
|
||||
recordPrefix:audioFile;
|
||||
patch:writable
|
||||
recordPrefix:audioFile;
|
||||
|
||||
lv2:extensionData state:interface ;
|
||||
|
||||
|
||||
rdfs:comment """
|
||||
Record the plugin's audio input signal to a stereophonic file. See also: TooB Record Input (mono), which records a monophonic file.
|
||||
""" ;
|
||||
|
||||
mod:brand "TooB";
|
||||
mod:label "Record Input";
|
||||
lv2:optionalFeature lv2:hardRTCapable;
|
||||
|
||||
lv2:port
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 0;
|
||||
lv2:symbol "stop" ;
|
||||
lv2:name "⏹";
|
||||
rdfs:comment "Stop.";
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:toggled,pprop:trigger;
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 1;
|
||||
lv2:symbol "record" ;
|
||||
lv2:name "⏺";
|
||||
rdfs:comment "Start recording. Click again to stop.";
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:toggled,pprop:trigger;
|
||||
],
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 2;
|
||||
lv2:symbol "record_led" ;
|
||||
lv2:name "";
|
||||
lv2:portProperty lv2:toggled ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
pipedal_ui:ledColor "red";
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 3;
|
||||
lv2:symbol "play" ;
|
||||
lv2:name "⏵";
|
||||
rdfs:comment "Preview the recorded file. Click again to stop.";
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
lv2:portProperty lv2:toggled,pprop:trigger;
|
||||
],
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 4;
|
||||
lv2:symbol "play_led" ;
|
||||
lv2:name "";
|
||||
lv2:portProperty lv2:toggled ;
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1.0;
|
||||
pipedal_ui:ledColor "green";
|
||||
],
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 5;
|
||||
lv2:symbol "record_time" ;
|
||||
rdfs:comment "Time";
|
||||
lv2:name "";
|
||||
units:unit units:s ;
|
||||
|
||||
lv2:minimum 0.0;
|
||||
lv2:maximum 1000000.0;
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 6;
|
||||
lv2:symbol "fformat" ;
|
||||
lv2:name "Format";
|
||||
rdfs:comment "Recording File Format";
|
||||
|
||||
lv2:portProperty lv2:integer, lv2:enumeration ;
|
||||
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum 0 ;
|
||||
lv2:maximum 3 ;
|
||||
lv2:scalePoint [
|
||||
rdfs:label "WAV" ;
|
||||
rdf:value 0
|
||||
],
|
||||
[
|
||||
rdfs:label "WAV (float32)" ;
|
||||
rdf:value 1
|
||||
],
|
||||
[
|
||||
rdfs:label "FLAC" ;
|
||||
rdf:value 2;
|
||||
],
|
||||
[
|
||||
rdfs:label "MP3" ;
|
||||
rdf:value 3
|
||||
]
|
||||
;
|
||||
],
|
||||
[
|
||||
a lv2:InputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 7;
|
||||
lv2:symbol "level" ;
|
||||
lv2:name "Level";
|
||||
lv2:name "Input trim level for recording";
|
||||
lv2:default 0.0 ;
|
||||
lv2:minimum -60.0;
|
||||
lv2:maximum 30.0;
|
||||
lv2:scalePoint [
|
||||
rdfs:label "-INF" ;
|
||||
rdf:value -60.0
|
||||
];
|
||||
units:unit units:db
|
||||
|
||||
|
||||
|
||||
],
|
||||
|
||||
[
|
||||
a lv2:OutputPort ,
|
||||
lv2:ControlPort ;
|
||||
|
||||
lv2:index 8 ;
|
||||
lv2:symbol "level_vu" ;
|
||||
lv2:name "";
|
||||
rdfs:comment "Recording level";
|
||||
|
||||
lv2:default -60 ;
|
||||
lv2:minimum -60 ;
|
||||
lv2:maximum 20 ;
|
||||
units:unit units:db
|
||||
],
|
||||
[
|
||||
a lv2:AudioPort ,
|
||||
lv2:InputPort ;
|
||||
lv2:index 9 ;
|
||||
lv2:symbol "in" ;
|
||||
lv2:name "In";
|
||||
pg:group myprefix:stereoInGroup ;
|
||||
lv2:designation pg:left
|
||||
|
||||
],
|
||||
[
|
||||
a lv2:AudioPort ,
|
||||
lv2:OutputPort ;
|
||||
lv2:index 10 ;
|
||||
lv2:symbol "out" ;
|
||||
lv2:name "Out";
|
||||
pg:group myprefix:stereoOutGroup ;
|
||||
lv2:designation pg:left
|
||||
],
|
||||
|
||||
[
|
||||
a atom:AtomPort ,
|
||||
lv2:InputPort ;
|
||||
lv2:index 11 ;
|
||||
atom:bufferType atom:Sequence ;
|
||||
atom:supports patch:Message;
|
||||
|
||||
lv2:symbol "controlIn" ;
|
||||
lv2:name "ControlIn"
|
||||
],
|
||||
[
|
||||
a atom:AtomPort ,
|
||||
lv2:OutputPort ;
|
||||
lv2:index 12 ;
|
||||
atom:bufferType atom:Sequence ;
|
||||
atom:supports patch:Message;
|
||||
|
||||
lv2:symbol "controlOut" ;
|
||||
lv2:name "ControlOut"
|
||||
],
|
||||
[
|
||||
a lv2:AudioPort ,
|
||||
lv2:InputPort ;
|
||||
lv2:index 13 ;
|
||||
lv2:symbol "inR" ;
|
||||
lv2:name "InR" ;
|
||||
pg:group myprefix:stereoInGroup ;
|
||||
lv2:designation pg:right
|
||||
],
|
||||
[
|
||||
a lv2:AudioPort ,
|
||||
lv2:OutputPort ;
|
||||
lv2:index 14 ;
|
||||
lv2:symbol "outR" ;
|
||||
lv2:name "OutR" ;
|
||||
pg:group myprefix:stereoOutGroup ;
|
||||
lv2:designation pg:right
|
||||
|
||||
]
|
||||
.
|
||||
|
||||
|
||||
<http://two-play.com/plugins/toob-record-stereo-ui>
|
||||
a ui:X11UI ;
|
||||
lv2:binary <ToobAmpUI.so>;
|
||||
lv2:extensionData ui:resize ;
|
||||
lv2:extensionData ui:idleInterface ;
|
||||
lv2:requiredFeature ui:idleInterface ;
|
||||
.
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
doap:license <https://rerdavies.github.io/pipedal/LicenseToobAmp> ;
|
||||
doap:maintainer <http://two-play.com/rerdavies#me> ;
|
||||
lv2:minorVersion 0 ;
|
||||
lv2:microVersion 57 ;
|
||||
lv2:microVersion 58 ;
|
||||
rdfs:comment """
|
||||
TooB Tuner is a chromatic guitar tuner.
|
||||
""" ;
|
||||
|
||||
@@ -71,6 +71,25 @@
|
||||
lv2:binary <ToobAmp.so> ;
|
||||
rdfs:seeAlso <ToobFlangerStereo.ttl> .
|
||||
|
||||
<http://two-play.com/plugins/toob-record-mono> a lv2:Plugin ;
|
||||
lv2:binary <ToobAmp.so> ;
|
||||
rdfs:seeAlso <ToobRecordMono.ttl> .
|
||||
|
||||
|
||||
<http://two-play.com/plugins/toob-record-stereo> a lv2:Plugin ;
|
||||
lv2:binary <ToobAmp.so> ;
|
||||
rdfs:seeAlso <ToobRecordStereo.ttl> .
|
||||
|
||||
<http://two-play.com/plugins/toob-looper-four> a lv2:Plugin ;
|
||||
lv2:binary <ToobAmp.so> ;
|
||||
rdfs:seeAlso <ToobLooperFour.ttl> .
|
||||
|
||||
<http://two-play.com/plugins/toob-looper-one> a lv2:Plugin ;
|
||||
lv2:binary <ToobAmp.so> ;
|
||||
rdfs:seeAlso <ToobLooperOne.ttl> .
|
||||
|
||||
|
||||
|
||||
|
||||
tpset:toob-flanger-preset-0
|
||||
a pset:Preset ;
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="256"
|
||||
height="36"
|
||||
viewBox="0 0 67.73333 9.525"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
inkscape:version="1.2.2 (732a01da63, 2022-12-09, custom)"
|
||||
sodipodi:docname="ToobCabSimLogo_master.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview7"
|
||||
pagecolor="#2e2e2e"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.414909"
|
||||
inkscape:cx="195.77231"
|
||||
inkscape:cy="90.465182"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1008"
|
||||
inkscape:window-x="1440"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1" />
|
||||
<defs
|
||||
id="defs2" />
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<g
|
||||
aria-label="TooB 4Looper"
|
||||
id="text236"
|
||||
style="font-style:italic;font-weight:bold;font-size:5.64444px;line-height:0;font-family:Timana;-inkscape-font-specification:'Timana Bold Italic';fill:#686868;stroke:#7f7f7f;stroke-width:0.285001;stop-color:#000000">
|
||||
<path
|
||||
d="m 10.655146,7.1034565 0.654755,-3.1383087 h -0.874888 l 0.191911,-0.8918216 h 2.833509 L 13.262878,3.9651478 H 12.38799 l -0.654756,3.1383087 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path631" />
|
||||
<path
|
||||
d="m 14.160346,7.1599009 q -0.575733,0 -0.891822,-0.3104442 Q 12.95808,6.533368 12.95808,5.9576351 q 0,-0.4007552 0.112889,-0.7619994 0.112889,-0.3668886 0.333022,-0.6491106 0.220133,-0.2878665 0.54751,-0.4515552 0.333022,-0.1693332 0.767644,-0.1693332 0.575733,0 0.886177,0.3160886 0.316089,0.3104442 0.316089,0.8861771 0,0.4007553 -0.112889,0.7676439 -0.112889,0.3612442 -0.333022,0.6491106 -0.220133,0.282222 -0.553155,0.4515552 -0.327377,0.1636888 -0.761999,0.1636888 z m 0.118533,-0.8015105 q 0.158044,0 0.282222,-0.1862665 0.124178,-0.191911 0.197555,-0.4797774 0.07338,-0.2935109 0.07338,-0.5983107 0,-0.3668886 -0.237066,-0.3668886 -0.158045,0 -0.282222,0.1919109 -0.124178,0.1862666 -0.197556,0.474133 -0.06773,0.2878665 -0.06773,0.5983107 0,0.3668886 0.231422,0.3668886 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path633" />
|
||||
<path
|
||||
d="m 17.586523,7.1599009 q -0.575733,0 -0.891822,-0.3104442 -0.310444,-0.3160887 -0.310444,-0.8918216 0,-0.4007552 0.112889,-0.7619994 0.112889,-0.3668886 0.333022,-0.6491106 0.220133,-0.2878665 0.54751,-0.4515552 0.333022,-0.1693332 0.767644,-0.1693332 0.575733,0 0.886177,0.3160886 0.316089,0.3104442 0.316089,0.8861771 0,0.4007553 -0.112889,0.7676439 -0.112889,0.3612442 -0.333022,0.6491106 -0.220133,0.282222 -0.553155,0.4515552 -0.327377,0.1636888 -0.761999,0.1636888 z m 0.118533,-0.8015105 q 0.158044,0 0.282222,-0.1862665 0.124178,-0.191911 0.197555,-0.4797774 0.07338,-0.2935109 0.07338,-0.5983107 0,-0.3668886 -0.237066,-0.3668886 -0.158045,0 -0.282222,0.1919109 -0.124178,0.1862666 -0.197556,0.474133 -0.06773,0.2878665 -0.06773,0.5983107 0,0.3668886 0.231422,0.3668886 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path635" />
|
||||
<path
|
||||
d="m 19.669324,7.1034565 0.85231,-4.0301303 h 1.343377 q 0.649111,0 0.931333,0.2483554 0.282222,0.2483553 0.282222,0.6321773 0,0.4120441 -0.214489,0.6660439 -0.208844,0.2539998 -0.603955,0.3725331 v 0.022578 q 0.242711,0.079022 0.383822,0.282222 0.146755,0.1975554 0.146755,0.4854219 0,0.4684885 -0.220133,0.7619994 -0.214489,0.2935109 -0.581377,0.4289775 -0.361244,0.1298221 -0.8128,0.1298221 z M 21.4699,4.6199028 q 0.282222,0 0.383822,-0.1241777 0.107245,-0.1241776 0.107245,-0.3160886 0,-0.282222 -0.349956,-0.282222 h -0.174977 l -0.163689,0.7224883 z m -0.316088,1.6425321 q 0.248355,0 0.400755,-0.1354666 0.1524,-0.141111 0.1524,-0.3330219 0,-0.191911 -0.09031,-0.282222 -0.09031,-0.095956 -0.321733,-0.095956 h -0.186267 l -0.180622,0.846666 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path637" />
|
||||
<path
|
||||
d="m 25.945947,7.1034565 0.163689,-0.7789327 h -1.51271 L 24.738037,5.6189687 26.837768,3.0733262 H 27.83119 L 27.317546,5.5117244 H 27.72959 L 27.560257,6.3245238 H 27.148213 L 26.984524,7.1034565 Z M 25.703236,5.5117244 h 0.575733 l 0.135466,-0.5362218 q 0.02822,-0.095956 0.06209,-0.2144888 0.03387,-0.1241777 0.06209,-0.2257776 0.02822,-0.1072443 0.03951,-0.141111 h -0.02258 q -0.0508,0.090311 -0.141111,0.2370665 -0.09031,0.141111 -0.174977,0.2370665 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path639" />
|
||||
<path
|
||||
d="m 27.989234,7.1034565 0.85231,-4.0301303 h 1.078089 l -0.666044,3.1495976 h 1.315154 l -0.186266,0.8805327 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path641" />
|
||||
<path
|
||||
d="m 32.307233,7.1599009 q -0.575732,0 -0.891821,-0.3104442 -0.310444,-0.3160887 -0.310444,-0.8918216 0,-0.4007552 0.112888,-0.7619994 0.112889,-0.3668886 0.333022,-0.6491106 0.220134,-0.2878665 0.547511,-0.4515552 0.333022,-0.1693332 0.767644,-0.1693332 0.575733,0 0.886177,0.3160886 0.316089,0.3104442 0.316089,0.8861771 0,0.4007553 -0.112889,0.7676439 -0.112889,0.3612442 -0.333022,0.6491106 -0.220133,0.282222 -0.553155,0.4515552 -0.327378,0.1636888 -0.762,0.1636888 z m 0.118534,-0.8015105 q 0.158044,0 0.282222,-0.1862665 0.124177,-0.191911 0.197555,-0.4797774 0.07338,-0.2935109 0.07338,-0.5983107 0,-0.3668886 -0.237067,-0.3668886 -0.158044,0 -0.282222,0.1919109 -0.124177,0.1862666 -0.197555,0.474133 -0.06773,0.2878665 -0.06773,0.5983107 0,0.3668886 0.231422,0.3668886 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path643" />
|
||||
<path
|
||||
d="m 35.73341,7.1599009 q -0.575733,0 -0.891822,-0.3104442 -0.310444,-0.3160887 -0.310444,-0.8918216 0,-0.4007552 0.112889,-0.7619994 0.112888,-0.3668886 0.333022,-0.6491106 0.220133,-0.2878665 0.54751,-0.4515552 0.333022,-0.1693332 0.767644,-0.1693332 0.575733,0 0.886177,0.3160886 0.316089,0.3104442 0.316089,0.8861771 0,0.4007553 -0.112889,0.7676439 -0.112889,0.3612442 -0.333022,0.6491106 -0.220133,0.282222 -0.553155,0.4515552 -0.327378,0.1636888 -0.761999,0.1636888 z m 0.118533,-0.8015105 q 0.158044,0 0.282222,-0.1862665 0.124177,-0.191911 0.197555,-0.4797774 0.07338,-0.2935109 0.07338,-0.5983107 0,-0.3668886 -0.237067,-0.3668886 -0.158044,0 -0.282222,0.1919109 -0.124177,0.1862666 -0.197555,0.474133 -0.06773,0.2878665 -0.06773,0.5983107 0,0.3668886 0.231422,0.3668886 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path645" />
|
||||
<path
|
||||
d="m 37.500122,8.4581221 0.948266,-4.476041 h 0.852311 l -0.03387,0.3499553 h 0.02258 q 0.129822,-0.1975554 0.299155,-0.2991554 0.174978,-0.1072443 0.412044,-0.1072443 0.417689,0 0.666044,0.2991553 0.254,0.2991553 0.254,0.8523105 0,0.3894663 -0.1016,0.7619994 -0.09596,0.3668886 -0.276578,0.6660439 -0.180622,0.2991554 -0.440266,0.4797775 -0.259644,0.1749776 -0.581377,0.1749776 -0.208845,0 -0.366889,-0.1072444 Q 38.995899,6.9397677 38.88301,6.7591456 H 38.86043 Q 38.8435,6.9792788 38.81527,7.1937675 38.78705,7.4139007 38.708025,7.7807893 L 38.566921,8.4581221 Z M 39.306343,6.301946 q 0.146755,0 0.265289,-0.1693332 0.118533,-0.1693332 0.186266,-0.4289775 0.07338,-0.2596442 0.07338,-0.5249329 0,-0.3951108 -0.237067,-0.3951108 -0.124177,0 -0.220133,0.1072443 -0.09596,0.1072444 -0.169333,0.2765776 -0.06773,0.1693332 -0.107244,0.3668886 -0.03387,0.191911 -0.03387,0.3725331 0,0.1749776 0.06209,0.2878664 0.06773,0.1072444 0.180622,0.1072444 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path647" />
|
||||
<path
|
||||
d="m 42.619632,7.1599009 q -0.592666,0 -0.914399,-0.3273775 Q 41.3835,6.4995014 41.3835,5.9237685 q 0,-0.3838219 0.107244,-0.7394217 0.112889,-0.3612441 0.333022,-0.6434661 0.220133,-0.2822221 0.553155,-0.4459108 0.338667,-0.1693332 0.795866,-0.1693332 0.524933,0 0.824089,0.2370665 0.299155,0.2370665 0.299155,0.6321773 0,0.513644 -0.400755,0.8297327 -0.400756,0.3160886 -1.275644,0.3160886 h -0.163689 v 0.045155 q 0,0.4063997 0.451556,0.4063997 0.237066,0 0.44591,-0.073378 0.214489,-0.073378 0.4572,-0.1975554 v 0.756355 q -0.248355,0.1241777 -0.519288,0.2031998 -0.265289,0.079022 -0.671689,0.079022 z m 0.02258,-1.885243 q 0.361244,0 0.502355,-0.1354666 0.141111,-0.141111 0.141111,-0.282222 0,-0.090311 -0.05644,-0.1467554 -0.05645,-0.062089 -0.174978,-0.062089 -0.124178,0 -0.231422,0.095955 -0.1016,0.095955 -0.169333,0.2427109 -0.06773,0.141111 -0.09031,0.2878665 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path649" />
|
||||
<path
|
||||
d="m 44.482298,7.1034565 0.660399,-3.1213754 h 0.852311 l -0.0508,0.5192885 h 0.02258 q 0.197555,-0.333022 0.406399,-0.4515552 0.214489,-0.1241777 0.530578,-0.1241777 0.06209,0 0.129822,0.00564 0.06773,0.00564 0.09031,0.016933 l -0.231422,1.0555104 q -0.05644,-0.028222 -0.146756,-0.045156 -0.09031,-0.016933 -0.191911,-0.016933 -0.248355,0 -0.434622,0.1693332 -0.180622,0.1693332 -0.276577,0.6208884 l -0.293511,1.371599 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path651" />
|
||||
</g>
|
||||
<path
|
||||
id="path1348"
|
||||
style="color:#000000;fill:#e0e0e0;fill-opacity:0.752941;stroke-width:0.714406;-inkscape-stroke:none"
|
||||
d="M 5.4193109,1.6360535 C 4.0746261,1.6465667 2.9804856,2.7485866 2.9805103,4.0933129 v 1.5080987 0.00443 0.00406 0.00702 c 0.00324,0.6351315 0.1709081,1.2397841 0.5330952,1.705241 0.091293,0.1173226 0.1960748,0.2241342 0.3126952,0.3186015 V 5.3666133 h 0.00259 V 4.0933129 C 3.8288705,3.2043172 4.5362516,2.4899017 5.4252198,2.4829515 6.3176074,2.4761075 7.0387059,3.1839609 7.0477631,4.0763306 v 0.016982 1.6742295 c 0,0.3851813 -0.1170262,0.6035969 -0.3182329,0.7675243 C 6.5283236,6.6989941 6.2034026,6.8056753 5.769664,6.8056753 H 5.437754 V 8.3957797 H 6.193851 V 7.5229912 C 6.5799202,7.4642455 6.9804539,7.4245038 7.2655789,7.1922063 7.6635843,6.8679419 7.8946602,6.354867 7.8946602,5.7675423 V 4.0933128 4.0693159 4.0682086 C 7.8809586,2.7185401 6.7690097,1.6257071 5.4193109,1.6360535 Z"
|
||||
sodipodi:nodetypes="ccccccscccccccsssccccsscccc" />
|
||||
<g
|
||||
aria-label="B"
|
||||
id="text1054"
|
||||
style="font-style:italic;font-weight:900;font-size:6.35px;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke-width:0.285001;stop-color:#000000"
|
||||
transform="matrix(0.71440613,0,0,0.71440613,-2.144828,0.00813001)">
|
||||
<path
|
||||
id="path1085"
|
||||
style="font-style:normal;-inkscape-font-specification:'Roboto, Heavy';stroke-width:0.285"
|
||||
d="M 8.865092,5.8580404 V 8.9958333 11.74073 H 9.9533976 V 8.9958333 h 0.7441404 c 0.549837,-0.00413 0.964283,-0.116789 1.243335,-0.3379638 0.281119,-0.223242 0.42168,-0.5560389 0.42168,-0.9983887 0,-0.2439125 -0.06305,-0.4506186 -0.189136,-0.6201172 -0.12609,-0.1694982 -0.306958,-0.2852537 -0.542602,-0.3472656 0.208772,-0.078548 0.366902,-0.2005048 0.474389,-0.3658692 0.107487,-0.1653644 0.161231,-0.3648358 0.161231,-0.598413 0,-0.4051429 -0.151929,-0.7141686 -0.455786,-0.9270752 C 11.508859,4.5878339 11.18123,4.4813802 10.486698,4.4813802 H 9.9533976 c -1.0883054,0 -1.0883056,1.029605 -1.0883056,1.3766602 z m 1.0883056,-0.022757 c 0,-0.3308701 0.1341694,-0.4768142 0.3334184,-0.4952 l 0.199882,-0.018444 c 0.203885,-0.018814 0.420647,0.042375 0.530201,0.127124 0.109553,0.082682 0.164331,0.2191083 0.164331,0.4092774 0,0.1653644 -0.05064,0.2904216 -0.151929,0.3751709 -0.101285,0.08475 -0.270784,0.1281579 -0.508496,0.1302246 H 9.9533976 Z m 0,1.2412875 h 0.7627444 c 0.374137,0.00207 0.561206,0.1912032 0.561206,0.5674073 0,0.1632973 -0.05271,0.2904217 -0.15813,0.381372 -0.105419,0.088883 -0.256315,0.1333252 -0.452686,0.1333252 H 9.9533976 Z"
|
||||
sodipodi:nodetypes="cccccccsscssczccssscssccsccscscc" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 13 KiB |
@@ -0,0 +1,144 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="306"
|
||||
height="36"
|
||||
viewBox="0 0 80.962496 9.525"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
inkscape:version="1.2.2 (732a01da63, 2022-12-09, custom)"
|
||||
sodipodi:docname="ToobCabSimLogo_master.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview7"
|
||||
pagecolor="#2e2e2e"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.414909"
|
||||
inkscape:cx="195.77231"
|
||||
inkscape:cy="90.465182"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1008"
|
||||
inkscape:window-x="1440"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1" />
|
||||
<defs
|
||||
id="defs2" />
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<g
|
||||
aria-label="TooB One-Button Looper"
|
||||
id="text236"
|
||||
style="font-style:italic;font-weight:bold;font-size:5.64444px;line-height:0;font-family:Timana;-inkscape-font-specification:'Timana Bold Italic';fill:#686868;stroke:#7f7f7f;stroke-width:0.285001;stop-color:#000000">
|
||||
<path
|
||||
d="m 10.655146,7.1034565 0.654755,-3.1383087 h -0.874888 l 0.191911,-0.8918216 h 2.833509 L 13.262878,3.9651478 H 12.38799 l -0.654756,3.1383087 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path460" />
|
||||
<path
|
||||
d="m 14.160346,7.1599009 q -0.575733,0 -0.891822,-0.3104442 Q 12.95808,6.533368 12.95808,5.9576351 q 0,-0.4007552 0.112889,-0.7619994 0.112889,-0.3668886 0.333022,-0.6491106 0.220133,-0.2878665 0.54751,-0.4515552 0.333022,-0.1693332 0.767644,-0.1693332 0.575733,0 0.886177,0.3160886 0.316089,0.3104442 0.316089,0.8861771 0,0.4007553 -0.112889,0.7676439 -0.112889,0.3612442 -0.333022,0.6491106 -0.220133,0.282222 -0.553155,0.4515552 -0.327377,0.1636888 -0.761999,0.1636888 z m 0.118533,-0.8015105 q 0.158044,0 0.282222,-0.1862665 0.124178,-0.191911 0.197555,-0.4797774 0.07338,-0.2935109 0.07338,-0.5983107 0,-0.3668886 -0.237066,-0.3668886 -0.158045,0 -0.282222,0.1919109 -0.124178,0.1862666 -0.197556,0.474133 -0.06773,0.2878665 -0.06773,0.5983107 0,0.3668886 0.231422,0.3668886 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path462" />
|
||||
<path
|
||||
d="m 17.586523,7.1599009 q -0.575733,0 -0.891822,-0.3104442 -0.310444,-0.3160887 -0.310444,-0.8918216 0,-0.4007552 0.112889,-0.7619994 0.112889,-0.3668886 0.333022,-0.6491106 0.220133,-0.2878665 0.54751,-0.4515552 0.333022,-0.1693332 0.767644,-0.1693332 0.575733,0 0.886177,0.3160886 0.316089,0.3104442 0.316089,0.8861771 0,0.4007553 -0.112889,0.7676439 -0.112889,0.3612442 -0.333022,0.6491106 -0.220133,0.282222 -0.553155,0.4515552 -0.327377,0.1636888 -0.761999,0.1636888 z m 0.118533,-0.8015105 q 0.158044,0 0.282222,-0.1862665 0.124178,-0.191911 0.197555,-0.4797774 0.07338,-0.2935109 0.07338,-0.5983107 0,-0.3668886 -0.237066,-0.3668886 -0.158045,0 -0.282222,0.1919109 -0.124178,0.1862666 -0.197556,0.474133 -0.06773,0.2878665 -0.06773,0.5983107 0,0.3668886 0.231422,0.3668886 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path464" />
|
||||
<path
|
||||
d="m 19.669324,7.1034565 0.85231,-4.0301303 h 1.343377 q 0.649111,0 0.931333,0.2483554 0.282222,0.2483553 0.282222,0.6321773 0,0.4120441 -0.214489,0.6660439 -0.208844,0.2539998 -0.603955,0.3725331 v 0.022578 q 0.242711,0.079022 0.383822,0.282222 0.146755,0.1975554 0.146755,0.4854219 0,0.4684885 -0.220133,0.7619994 -0.214489,0.2935109 -0.581377,0.4289775 -0.361244,0.1298221 -0.8128,0.1298221 z M 21.4699,4.6199028 q 0.282222,0 0.383822,-0.1241777 0.107245,-0.1241776 0.107245,-0.3160886 0,-0.282222 -0.349956,-0.282222 h -0.174977 l -0.163689,0.7224883 z m -0.316088,1.6425321 q 0.248355,0 0.400755,-0.1354666 0.1524,-0.141111 0.1524,-0.3330219 0,-0.191911 -0.09031,-0.282222 -0.09031,-0.095956 -0.321733,-0.095956 h -0.186267 l -0.180622,0.846666 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path466" />
|
||||
<path
|
||||
d="m 26.459591,7.1599009 q -0.767644,0 -1.15711,-0.423333 -0.389467,-0.4289775 -0.389467,-1.128888 0,-0.4684886 0.129822,-0.9256882 0.135467,-0.4628441 0.400756,-0.8410216 0.270933,-0.3781775 0.682977,-0.6039551 0.412044,-0.2257776 0.970844,-0.2257776 0.745066,0 1.128888,0.423333 0.383822,0.423333 0.383822,1.128888 0,0.4684886 -0.129823,0.9313326 -0.124177,0.4571997 -0.389466,0.8353772 -0.265289,0.3781775 -0.671688,0.6039551 -0.400756,0.2257776 -0.959555,0.2257776 z m 0.09596,-0.8918215 q 0.270933,0 0.491067,-0.2314221 0.220133,-0.231422 0.344311,-0.615244 0.129822,-0.3838219 0.129822,-0.846666 0,-0.3160887 -0.135467,-0.4910663 -0.129822,-0.1806221 -0.378177,-0.1806221 -0.225778,0 -0.412045,0.1523999 -0.186266,0.1467554 -0.321733,0.3951108 -0.129822,0.2427109 -0.203199,0.5475107 -0.06773,0.2991553 -0.06773,0.6039551 0,0.666044 0.553155,0.666044 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path468" />
|
||||
<path
|
||||
d="m 28.847187,7.1034565 0.660399,-3.1213754 h 0.852311 L 30.32603,4.416703 h 0.02258 q 0.1524,-0.2652887 0.3556,-0.3781775 0.208844,-0.1128888 0.502355,-0.1128888 0.293511,0 0.474133,0.1241777 0.180622,0.1185332 0.265289,0.3217331 0.08467,0.1975554 0.08467,0.4402663 0,0.1580443 -0.02258,0.3217331 -0.01693,0.1636887 -0.04516,0.3104442 l -0.349955,1.6594654 h -1.0668 l 0.3556,-1.7046209 q 0.01693,-0.073378 0.03387,-0.1806221 0.01693,-0.1128888 0.01693,-0.2088443 0,-0.1185333 -0.06209,-0.1749777 -0.06209,-0.062089 -0.146755,-0.062089 -0.158045,0 -0.293511,0.1975554 -0.129822,0.191911 -0.214489,0.6095996 l -0.321733,1.5239988 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path470" />
|
||||
<path
|
||||
d="m 33.763492,7.1599009 q -0.592666,0 -0.914399,-0.3273775 -0.321733,-0.333022 -0.321733,-0.9087549 0,-0.3838219 0.107244,-0.7394217 0.112889,-0.3612441 0.333022,-0.6434661 0.220133,-0.2822221 0.553155,-0.4459108 0.338666,-0.1693332 0.795866,-0.1693332 0.524933,0 0.824088,0.2370665 0.299156,0.2370665 0.299156,0.6321773 0,0.513644 -0.400756,0.8297327 -0.400755,0.3160886 -1.275643,0.3160886 h -0.163689 v 0.045155 q 0,0.4063997 0.451555,0.4063997 0.237067,0 0.445911,-0.073378 0.214489,-0.073378 0.4572,-0.1975554 v 0.756355 q -0.248356,0.1241777 -0.519289,0.2031998 -0.265288,0.079022 -0.671688,0.079022 z m 0.02258,-1.885243 q 0.361244,0 0.502355,-0.1354666 0.141111,-0.141111 0.141111,-0.282222 0,-0.090311 -0.05644,-0.1467554 -0.05644,-0.062089 -0.174978,-0.062089 -0.124178,0 -0.231422,0.095955 -0.1016,0.095955 -0.169333,0.2427109 -0.06773,0.141111 -0.09031,0.2878665 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path472" />
|
||||
<path
|
||||
d="m 35.62616,6.019724 0.174977,-0.8579549 h 1.523999 L 37.150158,6.019724 Z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path474" />
|
||||
<path
|
||||
d="m 37.511405,7.1034565 0.85231,-4.0301303 h 1.343377 q 0.649111,0 0.931333,0.2483554 0.282222,0.2483553 0.282222,0.6321773 0,0.4120441 -0.214489,0.6660439 -0.208844,0.2539998 -0.603955,0.3725331 v 0.022578 q 0.242711,0.079022 0.383822,0.282222 0.146755,0.1975554 0.146755,0.4854219 0,0.4684885 -0.220133,0.7619994 -0.214488,0.2935109 -0.581377,0.4289775 -0.361244,0.1298221 -0.812799,0.1298221 z m 1.800576,-2.4835537 q 0.282222,0 0.383822,-0.1241777 0.107245,-0.1241776 0.107245,-0.3160886 0,-0.282222 -0.349956,-0.282222 h -0.174977 l -0.163689,0.7224883 z m -0.316088,1.6425321 q 0.248355,0 0.400755,-0.1354666 0.1524,-0.141111 0.1524,-0.3330219 0,-0.191911 -0.09031,-0.282222 -0.09031,-0.095956 -0.321733,-0.095956 h -0.186267 l -0.180622,0.846666 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path476" />
|
||||
<path
|
||||
d="m 42.089052,7.1599009 q -0.287867,0 -0.474133,-0.1185332 Q 41.434297,6.91719 41.34963,6.7139901 41.26496,6.5107903 41.26496,6.2737238 q 0,-0.1580443 0.01693,-0.3217331 0.02258,-0.1636888 0.0508,-0.3104442 l 0.349955,-1.6594654 h 1.066799 l -0.355599,1.6989765 q -0.01693,0.073378 -0.03387,0.1862665 -0.01693,0.1072444 -0.01693,0.2031998 0,0.1185333 0.06209,0.1806221 0.06209,0.056444 0.146756,0.056444 0.141111,0 0.276577,-0.1919109 0.141111,-0.1975554 0.231422,-0.615244 l 0.321734,-1.5183544 h 1.066799 l -0.6604,3.1213754 h -0.85231 l 0.03387,-0.4346219 h -0.02258 q -0.1524,0.2596443 -0.3556,0.3781775 -0.2032,0.1128888 -0.502355,0.1128888 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path478" />
|
||||
<path
|
||||
d="m 45.639402,7.1599009 q -0.406399,0 -0.620888,-0.1749776 -0.208844,-0.1806221 -0.208844,-0.5757329 0,-0.1128888 0.02258,-0.2596443 0.02258,-0.1467554 0.04516,-0.2596442 l 0.231422,-1.1063103 h -0.423333 l 0.112889,-0.524933 0.59831,-0.2427109 0.378178,-0.6603995 h 0.711199 l -0.135466,0.6265329 h 0.795866 L 46.97149,4.7835916 h -0.795866 l -0.231422,1.0555103 q -0.01693,0.079022 -0.03387,0.1636888 -0.01129,0.079022 -0.01129,0.1241776 0,0.090311 0.0508,0.1354666 0.0508,0.039511 0.124177,0.039511 0.107245,0 0.237067,-0.033867 0.129822,-0.039511 0.265288,-0.095956 v 0.8015105 q -0.174977,0.084667 -0.406399,0.1354665 -0.225778,0.0508 -0.530578,0.0508 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path480" />
|
||||
<path
|
||||
d="m 48.218916,7.1599009 q -0.4064,0 -0.620889,-0.1749776 -0.208844,-0.1806221 -0.208844,-0.5757329 0,-0.1128888 0.02258,-0.2596443 0.02258,-0.1467554 0.04516,-0.2596442 l 0.231422,-1.1063103 h -0.423333 l 0.112889,-0.524933 0.598311,-0.2427109 0.378177,-0.6603995 h 0.7112 l -0.135467,0.6265329 h 0.795866 l -0.174977,0.8015105 h -0.795866 l -0.231422,1.0555103 q -0.01693,0.079022 -0.03387,0.1636888 -0.01129,0.079022 -0.01129,0.1241776 0,0.090311 0.0508,0.1354666 0.0508,0.039511 0.124178,0.039511 0.107244,0 0.237066,-0.033867 0.129822,-0.039511 0.265289,-0.095956 v 0.8015105 q -0.174978,0.084667 -0.4064,0.1354665 -0.225777,0.0508 -0.530577,0.0508 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path482" />
|
||||
<path
|
||||
d="m 51.103229,7.1599009 q -0.575733,0 -0.891821,-0.3104442 -0.310445,-0.3160887 -0.310445,-0.8918216 0,-0.4007552 0.112889,-0.7619994 0.112889,-0.3668886 0.333022,-0.6491106 0.220133,-0.2878665 0.547511,-0.4515552 0.333022,-0.1693332 0.767644,-0.1693332 0.575733,0 0.886177,0.3160886 0.316088,0.3104442 0.316088,0.8861771 0,0.4007553 -0.112888,0.7676439 -0.112889,0.3612442 -0.333022,0.6491106 -0.220133,0.282222 -0.553155,0.4515552 -0.327378,0.1636888 -0.762,0.1636888 z m 0.118533,-0.8015105 q 0.158045,0 0.282222,-0.1862665 0.124178,-0.191911 0.197556,-0.4797774 0.07338,-0.2935109 0.07338,-0.5983107 0,-0.3668886 -0.237067,-0.3668886 -0.158044,0 -0.282222,0.1919109 -0.124178,0.1862666 -0.197555,0.474133 -0.06773,0.2878665 -0.06773,0.5983107 0,0.3668886 0.231422,0.3668886 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path484" />
|
||||
<path
|
||||
d="m 53.157808,7.1034565 0.6604,-3.1213754 h 0.85231 l -0.03387,0.4346219 h 0.02258 q 0.1524,-0.2652887 0.3556,-0.3781775 0.208844,-0.1128888 0.502355,-0.1128888 0.293511,0 0.474133,0.1241777 0.180622,0.1185332 0.265289,0.3217331 0.08467,0.1975554 0.08467,0.4402663 0,0.1580443 -0.02258,0.3217331 -0.01693,0.1636887 -0.04516,0.3104442 L 55.92358,7.1034565 H 54.856781 L 55.21238,5.3988356 q 0.01693,-0.073378 0.03387,-0.1806221 0.01693,-0.1128888 0.01693,-0.2088443 0,-0.1185333 -0.06209,-0.1749777 -0.06209,-0.062089 -0.146756,-0.062089 -0.158044,0 -0.293511,0.1975554 -0.129822,0.191911 -0.214489,0.6095996 l -0.321733,1.5239988 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path486" />
|
||||
<path
|
||||
d="m 58.164424,7.1034565 0.85231,-4.0301303 h 1.078088 l -0.666043,3.1495976 h 1.315154 l -0.186266,0.8805327 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path488" />
|
||||
<path
|
||||
d="m 62.482425,7.1599009 q -0.575733,0 -0.891821,-0.3104442 Q 61.28016,6.533368 61.28016,5.9576351 q 0,-0.4007552 0.112888,-0.7619994 0.112889,-0.3668886 0.333022,-0.6491106 0.220134,-0.2878665 0.547511,-0.4515552 0.333022,-0.1693332 0.767644,-0.1693332 0.575733,0 0.886177,0.3160886 0.316089,0.3104442 0.316089,0.8861771 0,0.4007553 -0.112889,0.7676439 -0.112889,0.3612442 -0.333022,0.6491106 -0.220133,0.282222 -0.553155,0.4515552 -0.327378,0.1636888 -0.762,0.1636888 z m 0.118534,-0.8015105 q 0.158044,0 0.282222,-0.1862665 0.124177,-0.191911 0.197555,-0.4797774 0.07338,-0.2935109 0.07338,-0.5983107 0,-0.3668886 -0.237067,-0.3668886 -0.158044,0 -0.282222,0.1919109 -0.124177,0.1862666 -0.197555,0.474133 -0.06773,0.2878665 -0.06773,0.5983107 0,0.3668886 0.231422,0.3668886 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path490" />
|
||||
<path
|
||||
d="m 65.908603,7.1599009 q -0.575733,0 -0.891821,-0.3104442 -0.310444,-0.3160887 -0.310444,-0.8918216 0,-0.4007552 0.112888,-0.7619994 0.112889,-0.3668886 0.333022,-0.6491106 0.220133,-0.2878665 0.547511,-0.4515552 0.333022,-0.1693332 0.767644,-0.1693332 0.575733,0 0.886177,0.3160886 0.316089,0.3104442 0.316089,0.8861771 0,0.4007553 -0.112889,0.7676439 -0.112889,0.3612442 -0.333022,0.6491106 -0.220133,0.282222 -0.553155,0.4515552 -0.327378,0.1636888 -0.762,0.1636888 z m 0.118534,-0.8015105 q 0.158044,0 0.282222,-0.1862665 0.124177,-0.191911 0.197555,-0.4797774 0.07338,-0.2935109 0.07338,-0.5983107 0,-0.3668886 -0.237067,-0.3668886 -0.158044,0 -0.282222,0.1919109 -0.124177,0.1862666 -0.197555,0.474133 -0.06773,0.2878665 -0.06773,0.5983107 0,0.3668886 0.231422,0.3668886 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path492" />
|
||||
<path
|
||||
d="m 67.675316,8.4581221 0.948266,-4.476041 h 0.85231 l -0.03387,0.3499553 h 0.02258 q 0.129823,-0.1975554 0.299156,-0.2991554 0.174977,-0.1072443 0.412044,-0.1072443 0.417688,0 0.666044,0.2991553 0.254,0.2991553 0.254,0.8523105 0,0.3894663 -0.1016,0.7619994 -0.09596,0.3668886 -0.276578,0.6660439 -0.180622,0.2991554 -0.440266,0.4797775 -0.259644,0.1749776 -0.581378,0.1749776 -0.208844,0 -0.366888,-0.1072444 -0.158044,-0.1128888 -0.270933,-0.2935109 h -0.02258 q -0.01693,0.2201332 -0.04516,0.4346219 -0.02822,0.2201332 -0.107244,0.5870218 L 68.742115,8.4581221 Z M 69.481537,6.301946 q 0.146755,0 0.265288,-0.1693332 0.118534,-0.1693332 0.186267,-0.4289775 0.07338,-0.2596442 0.07338,-0.5249329 0,-0.3951108 -0.237067,-0.3951108 -0.124178,0 -0.220133,0.1072443 -0.09596,0.1072444 -0.169333,0.2765776 -0.06773,0.1693332 -0.107245,0.3668886 -0.03387,0.191911 -0.03387,0.3725331 0,0.1749776 0.06209,0.2878664 0.06773,0.1072444 0.180623,0.1072444 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path494" />
|
||||
<path
|
||||
d="m 72.794822,7.1599009 q -0.592666,0 -0.914399,-0.3273775 -0.321733,-0.333022 -0.321733,-0.9087549 0,-0.3838219 0.107244,-0.7394217 0.112889,-0.3612441 0.333022,-0.6434661 0.220133,-0.2822221 0.553155,-0.4459108 0.338667,-0.1693332 0.795866,-0.1693332 0.524933,0 0.824088,0.2370665 0.299156,0.2370665 0.299156,0.6321773 0,0.513644 -0.400755,0.8297327 -0.400756,0.3160886 -1.275644,0.3160886 h -0.163689 v 0.045155 q 0,0.4063997 0.451556,0.4063997 0.237066,0 0.44591,-0.073378 0.214489,-0.073378 0.4572,-0.1975554 v 0.756355 q -0.248355,0.1241777 -0.519289,0.2031998 -0.265288,0.079022 -0.671688,0.079022 z m 0.02258,-1.885243 q 0.361244,0 0.502355,-0.1354666 0.141111,-0.141111 0.141111,-0.282222 0,-0.090311 -0.05644,-0.1467554 -0.05644,-0.062089 -0.174978,-0.062089 -0.124178,0 -0.231422,0.095955 -0.1016,0.095955 -0.169333,0.2427109 -0.06773,0.141111 -0.09031,0.2878665 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path496" />
|
||||
<path
|
||||
d="m 74.657495,7.1034565 0.6604,-3.1213754 h 0.85231 l -0.0508,0.5192885 h 0.02258 q 0.197556,-0.333022 0.4064,-0.4515552 0.214489,-0.1241777 0.530577,-0.1241777 0.06209,0 0.129822,0.00564 0.06773,0.00564 0.09031,0.016933 l -0.231422,1.0555104 q -0.05644,-0.028222 -0.146755,-0.045156 -0.09031,-0.016933 -0.191911,-0.016933 -0.248355,0 -0.434622,0.1693332 -0.180622,0.1693332 -0.276578,0.6208884 l -0.29351,1.371599 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path498" />
|
||||
</g>
|
||||
<path
|
||||
id="path1348"
|
||||
style="color:#000000;fill:#e0e0e0;fill-opacity:0.752941;stroke-width:0.714406;-inkscape-stroke:none"
|
||||
d="M 5.4193109,1.6360535 C 4.0746261,1.6465667 2.9804856,2.7485866 2.9805103,4.0933129 v 1.5080987 0.00443 0.00406 0.00702 c 0.00324,0.6351315 0.1709081,1.2397841 0.5330952,1.705241 0.091293,0.1173226 0.1960748,0.2241342 0.3126952,0.3186015 V 5.3666133 h 0.00259 V 4.0933129 C 3.8288705,3.2043172 4.5362516,2.4899017 5.4252198,2.4829515 6.3176074,2.4761075 7.0387059,3.1839609 7.0477631,4.0763306 v 0.016982 1.6742295 c 0,0.3851813 -0.1170262,0.6035969 -0.3182329,0.7675243 C 6.5283236,6.6989941 6.2034026,6.8056753 5.769664,6.8056753 H 5.437754 V 8.3957797 H 6.193851 V 7.5229912 C 6.5799202,7.4642455 6.9804539,7.4245038 7.2655789,7.1922063 7.6635843,6.8679419 7.8946602,6.354867 7.8946602,5.7675423 V 4.0933128 4.0693159 4.0682086 C 7.8809586,2.7185401 6.7690097,1.6257071 5.4193109,1.6360535 Z"
|
||||
sodipodi:nodetypes="ccccccscccccccsssccccsscccc" />
|
||||
<g
|
||||
aria-label="B"
|
||||
id="text1054"
|
||||
style="font-style:italic;font-weight:900;font-size:6.35px;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke-width:0.285001;stop-color:#000000"
|
||||
transform="matrix(0.71440613,0,0,0.71440613,-2.144828,0.00813001)">
|
||||
<path
|
||||
id="path1085"
|
||||
style="font-style:normal;-inkscape-font-specification:'Roboto, Heavy';stroke-width:0.285"
|
||||
d="M 8.865092,5.8580404 V 8.9958333 11.74073 H 9.9533976 V 8.9958333 h 0.7441404 c 0.549837,-0.00413 0.964283,-0.116789 1.243335,-0.3379638 0.281119,-0.223242 0.42168,-0.5560389 0.42168,-0.9983887 0,-0.2439125 -0.06305,-0.4506186 -0.189136,-0.6201172 -0.12609,-0.1694982 -0.306958,-0.2852537 -0.542602,-0.3472656 0.208772,-0.078548 0.366902,-0.2005048 0.474389,-0.3658692 0.107487,-0.1653644 0.161231,-0.3648358 0.161231,-0.598413 0,-0.4051429 -0.151929,-0.7141686 -0.455786,-0.9270752 C 11.508859,4.5878339 11.18123,4.4813802 10.486698,4.4813802 H 9.9533976 c -1.0883054,0 -1.0883056,1.029605 -1.0883056,1.3766602 z m 1.0883056,-0.022757 c 0,-0.3308701 0.1341694,-0.4768142 0.3334184,-0.4952 l 0.199882,-0.018444 c 0.203885,-0.018814 0.420647,0.042375 0.530201,0.127124 0.109553,0.082682 0.164331,0.2191083 0.164331,0.4092774 0,0.1653644 -0.05064,0.2904216 -0.151929,0.3751709 -0.101285,0.08475 -0.270784,0.1281579 -0.508496,0.1302246 H 9.9533976 Z m 0,1.2412875 h 0.7627444 c 0.374137,0.00207 0.561206,0.1912032 0.561206,0.5674073 0,0.1632973 -0.05271,0.2904217 -0.15813,0.381372 -0.105419,0.088883 -0.256315,0.1333252 -0.452686,0.1333252 H 9.9533976 Z"
|
||||
sodipodi:nodetypes="cccccccsscssczccssscssccsccscscc" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 21 KiB |
@@ -0,0 +1,148 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="350"
|
||||
height="36"
|
||||
viewBox="0 0 92.604162 9.525"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
inkscape:version="1.2.2 (732a01da63, 2022-12-09, custom)"
|
||||
sodipodi:docname="ToobCabSimLogo_master.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview7"
|
||||
pagecolor="#2e2e2e"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.414909"
|
||||
inkscape:cx="195.77231"
|
||||
inkscape:cy="90.465182"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1008"
|
||||
inkscape:window-x="1440"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1" />
|
||||
<defs
|
||||
id="defs2" />
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<g
|
||||
aria-label="TooB Record Input (mono)"
|
||||
id="text236"
|
||||
style="font-style:italic;font-weight:bold;font-size:5.64444px;line-height:0;font-family:Timana;-inkscape-font-specification:'Timana Bold Italic';fill:#686868;stroke:#7f7f7f;stroke-width:0.285001;stop-color:#000000">
|
||||
<path
|
||||
d="m 10.655146,7.1034565 0.654755,-3.1383087 h -0.874888 l 0.191911,-0.8918216 h 2.833509 L 13.262878,3.9651478 H 12.38799 l -0.654756,3.1383087 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path737" />
|
||||
<path
|
||||
d="m 14.160346,7.1599009 q -0.575733,0 -0.891822,-0.3104442 Q 12.95808,6.533368 12.95808,5.9576351 q 0,-0.4007552 0.112889,-0.7619994 0.112889,-0.3668886 0.333022,-0.6491106 0.220133,-0.2878665 0.54751,-0.4515552 0.333022,-0.1693332 0.767644,-0.1693332 0.575733,0 0.886177,0.3160886 0.316089,0.3104442 0.316089,0.8861771 0,0.4007553 -0.112889,0.7676439 -0.112889,0.3612442 -0.333022,0.6491106 -0.220133,0.282222 -0.553155,0.4515552 -0.327377,0.1636888 -0.761999,0.1636888 z m 0.118533,-0.8015105 q 0.158044,0 0.282222,-0.1862665 0.124178,-0.191911 0.197555,-0.4797774 0.07338,-0.2935109 0.07338,-0.5983107 0,-0.3668886 -0.237066,-0.3668886 -0.158045,0 -0.282222,0.1919109 -0.124178,0.1862666 -0.197556,0.474133 -0.06773,0.2878665 -0.06773,0.5983107 0,0.3668886 0.231422,0.3668886 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path739" />
|
||||
<path
|
||||
d="m 17.586523,7.1599009 q -0.575733,0 -0.891822,-0.3104442 -0.310444,-0.3160887 -0.310444,-0.8918216 0,-0.4007552 0.112889,-0.7619994 0.112889,-0.3668886 0.333022,-0.6491106 0.220133,-0.2878665 0.54751,-0.4515552 0.333022,-0.1693332 0.767644,-0.1693332 0.575733,0 0.886177,0.3160886 0.316089,0.3104442 0.316089,0.8861771 0,0.4007553 -0.112889,0.7676439 -0.112889,0.3612442 -0.333022,0.6491106 -0.220133,0.282222 -0.553155,0.4515552 -0.327377,0.1636888 -0.761999,0.1636888 z m 0.118533,-0.8015105 q 0.158044,0 0.282222,-0.1862665 0.124178,-0.191911 0.197555,-0.4797774 0.07338,-0.2935109 0.07338,-0.5983107 0,-0.3668886 -0.237066,-0.3668886 -0.158045,0 -0.282222,0.1919109 -0.124178,0.1862666 -0.197556,0.474133 -0.06773,0.2878665 -0.06773,0.5983107 0,0.3668886 0.231422,0.3668886 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path741" />
|
||||
<path
|
||||
d="m 19.669324,7.1034565 0.85231,-4.0301303 h 1.343377 q 0.649111,0 0.931333,0.2483554 0.282222,0.2483553 0.282222,0.6321773 0,0.4120441 -0.214489,0.6660439 -0.208844,0.2539998 -0.603955,0.3725331 v 0.022578 q 0.242711,0.079022 0.383822,0.282222 0.146755,0.1975554 0.146755,0.4854219 0,0.4684885 -0.220133,0.7619994 -0.214489,0.2935109 -0.581377,0.4289775 -0.361244,0.1298221 -0.8128,0.1298221 z M 21.4699,4.6199028 q 0.282222,0 0.383822,-0.1241777 0.107245,-0.1241776 0.107245,-0.3160886 0,-0.282222 -0.349956,-0.282222 h -0.174977 l -0.163689,0.7224883 z m -0.316088,1.6425321 q 0.248355,0 0.400755,-0.1354666 0.1524,-0.141111 0.1524,-0.3330219 0,-0.191911 -0.09031,-0.282222 -0.09031,-0.095956 -0.321733,-0.095956 h -0.186267 l -0.180622,0.846666 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path743" />
|
||||
<path
|
||||
d="m 24.715459,7.1034565 0.85231,-4.0301303 h 1.0668 q 0.694266,0 1.061154,0.2765776 0.372533,0.2765775 0.372533,0.8297327 0,0.3668886 -0.124177,0.615244 -0.118534,0.2483553 -0.299156,0.3951108 -0.180622,0.1467554 -0.355599,0.2257776 l 0.728132,1.6876876 H 26.843413 L 26.307191,5.6359021 h -0.2032 L 25.793547,7.1034565 Z M 26.42008,4.8174582 q 0.214489,0 0.389466,-0.1298221 0.180622,-0.1298221 0.180622,-0.4402663 0,-0.1467555 -0.08467,-0.2483554 -0.07902,-0.1015999 -0.287867,-0.1015999 H 26.47088 l -0.191911,0.9200437 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path745" />
|
||||
<path
|
||||
d="m 29.761587,7.1599009 q -0.592667,0 -0.9144,-0.3273775 -0.321733,-0.333022 -0.321733,-0.9087549 0,-0.3838219 0.107245,-0.7394217 0.112888,-0.3612441 0.333021,-0.6434661 0.220134,-0.2822221 0.553156,-0.4459108 0.338666,-0.1693332 0.795866,-0.1693332 0.524933,0 0.824088,0.2370665 0.299155,0.2370665 0.299155,0.6321773 0,0.513644 -0.400755,0.8297327 -0.400755,0.3160886 -1.275643,0.3160886 h -0.163689 v 0.045155 q 0,0.4063997 0.451555,0.4063997 0.237066,0 0.445911,-0.073378 0.214488,-0.073378 0.457199,-0.1975554 v 0.756355 q -0.248355,0.1241777 -0.519288,0.2031998 -0.265289,0.079022 -0.671688,0.079022 z m 0.02258,-1.885243 q 0.361244,0 0.502355,-0.1354666 0.141111,-0.141111 0.141111,-0.282222 0,-0.090311 -0.05644,-0.1467554 -0.05644,-0.062089 -0.174978,-0.062089 -0.124177,0 -0.231422,0.095955 -0.1016,0.095955 -0.169333,0.2427109 -0.06773,0.141111 -0.09031,0.2878665 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path747" />
|
||||
<path
|
||||
d="m 32.956342,7.1599009 q -0.316089,0 -0.581377,-0.1298221 -0.265289,-0.1298221 -0.423333,-0.4120442 -0.158045,-0.282222 -0.158045,-0.7337772 0,-0.5531551 0.2032,-0.9934215 0.208844,-0.4459107 0.581377,-0.705555 0.378178,-0.2596442 0.886178,-0.2596442 0.29351,0 0.530577,0.056444 0.242711,0.0508 0.479777,0.1636887 L 34.13603,4.9359915 q -0.141111,-0.062089 -0.3048,-0.1128888 -0.163689,-0.0508 -0.316088,-0.0508 -0.163689,0 -0.287867,0.1072444 -0.124178,0.1015999 -0.2032,0.2652887 -0.07902,0.1580443 -0.118533,0.3386664 -0.03951,0.1806221 -0.03951,0.3330219 0,0.2765776 0.09031,0.383822 0.09596,0.1015999 0.254,0.1015999 0.197555,0 0.383822,-0.062089 0.186266,-0.067733 0.395111,-0.1749777 v 0.846666 q -0.220134,0.1185333 -0.462845,0.1862666 -0.24271,0.062089 -0.570088,0.062089 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path749" />
|
||||
<path
|
||||
d="m 35.840648,7.1599009 q -0.575733,0 -0.891821,-0.3104442 -0.310444,-0.3160887 -0.310444,-0.8918216 0,-0.4007552 0.112888,-0.7619994 0.112889,-0.3668886 0.333022,-0.6491106 0.220133,-0.2878665 0.547511,-0.4515552 0.333022,-0.1693332 0.767644,-0.1693332 0.575733,0 0.886177,0.3160886 0.316089,0.3104442 0.316089,0.8861771 0,0.4007553 -0.112889,0.7676439 -0.112889,0.3612442 -0.333022,0.6491106 -0.220133,0.282222 -0.553155,0.4515552 -0.327378,0.1636888 -0.762,0.1636888 z m 0.118534,-0.8015105 q 0.158044,0 0.282222,-0.1862665 0.124177,-0.191911 0.197555,-0.4797774 0.07338,-0.2935109 0.07338,-0.5983107 0,-0.3668886 -0.237067,-0.3668886 -0.158044,0 -0.282222,0.1919109 -0.124178,0.1862666 -0.197555,0.474133 -0.06773,0.2878665 -0.06773,0.5983107 0,0.3668886 0.231423,0.3668886 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path751" />
|
||||
<path
|
||||
d="m 37.895227,7.1034565 0.6604,-3.1213754 h 0.85231 l -0.0508,0.5192885 h 0.02258 q 0.197555,-0.333022 0.4064,-0.4515552 0.214488,-0.1241777 0.530577,-0.1241777 0.06209,0 0.129822,0.00564 0.06773,0.00564 0.09031,0.016933 l -0.231422,1.0555104 q -0.05644,-0.028222 -0.146755,-0.045156 -0.09031,-0.016933 -0.191911,-0.016933 -0.248356,0 -0.434622,0.1693332 -0.180622,0.1693332 -0.276578,0.6208884 l -0.29351,1.371599 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path753" />
|
||||
<path
|
||||
d="m 41.304469,7.1599009 q -0.237067,0 -0.440267,-0.1128888 Q 40.661003,6.9341233 40.536825,6.674479 40.418292,6.4148348 40.418292,5.968924 q 0,-0.2257776 0.0508,-0.5023552 0.05644,-0.2765775 0.163688,-0.5475107 0.107245,-0.2709331 0.270934,-0.4967107 0.163688,-0.2257776 0.389466,-0.3612442 0.225778,-0.1354665 0.508,-0.1354665 0.253999,0 0.389466,0.1128888 0.141111,0.1128888 0.265289,0.3047998 h 0.02258 q 0,-0.033867 0.0056,-0.1523999 0.0056,-0.1185333 0.02258,-0.2652887 0.01693,-0.1523999 0.04516,-0.282222 L 42.721223,2.813682 h 1.078088 l -0.908755,4.2897745 h -0.85231 l 0.02822,-0.3386664 H 42.04389 Q 41.931002,6.9228344 41.767313,7.0413677 41.603624,7.1599009 41.304469,7.1599009 Z M 41.744735,6.301946 q 0.124178,0 0.220133,-0.1072444 0.1016,-0.1128888 0.169333,-0.282222 0.07338,-0.1749776 0.107245,-0.3668886 0.03951,-0.1975554 0.03951,-0.3668886 0,-0.1806221 -0.05644,-0.2878665 -0.0508,-0.1072443 -0.163689,-0.1072443 -0.146756,0 -0.276578,0.1693332 -0.124177,0.1693332 -0.2032,0.4289774 -0.07338,0.2539999 -0.07338,0.524933 0,0.3951108 0.237066,0.3951108 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path755" />
|
||||
<path
|
||||
d="m 44.860468,7.1034565 0.129823,-0.615244 0.530577,-0.2201331 0.496711,-2.3367983 -0.440267,-0.2370665 0.129822,-0.6208884 h 2.07151 l -0.129822,0.6208884 -0.553155,0.2370665 -0.496711,2.3367983 0.445911,0.2201331 -0.129822,0.615244 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path757" />
|
||||
<path
|
||||
d="m 47.53029,7.1034565 0.6604,-3.1213754 H 49.043 L 49.00913,4.416703 h 0.02258 q 0.152399,-0.2652887 0.355599,-0.3781775 0.208845,-0.1128888 0.502355,-0.1128888 0.293511,0 0.474133,0.1241777 0.180623,0.1185332 0.265289,0.3217331 0.08467,0.1975554 0.08467,0.4402663 0,0.1580443 -0.02258,0.3217331 -0.01693,0.1636887 -0.04516,0.3104442 l -0.349955,1.6594654 h -1.066799 l 0.3556,-1.7046209 q 0.01693,-0.073378 0.03387,-0.1806221 0.01693,-0.1128888 0.01693,-0.2088443 0,-0.1185333 -0.06209,-0.1749777 -0.06209,-0.062089 -0.146756,-0.062089 -0.158044,0 -0.293511,0.1975554 -0.129822,0.191911 -0.214488,0.6095996 l -0.321727,1.523999 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path759" />
|
||||
<path
|
||||
d="m 50.753265,8.4581221 0.948266,-4.476041 h 0.852311 l -0.03387,0.3499553 h 0.02258 q 0.129822,-0.1975554 0.299155,-0.2991554 0.174978,-0.1072443 0.412044,-0.1072443 0.417689,0 0.666044,0.2991553 0.254,0.2991553 0.254,0.8523105 0,0.3894663 -0.1016,0.7619994 -0.09595,0.3668886 -0.276577,0.6660439 -0.180622,0.2991554 -0.440267,0.4797775 -0.259644,0.1749776 -0.581377,0.1749776 -0.208844,0 -0.366889,-0.1072444 -0.158044,-0.1128888 -0.270933,-0.2935109 h -0.02258 q -0.01693,0.2201332 -0.04515,0.4346219 -0.02822,0.2201332 -0.107244,0.5870218 L 51.820065,8.4581221 Z M 52.559486,6.301946 q 0.146756,0 0.265289,-0.1693332 0.118533,-0.1693332 0.186266,-0.4289775 0.07338,-0.2596442 0.07338,-0.5249329 0,-0.3951108 -0.237066,-0.3951108 -0.124178,0 -0.220133,0.1072443 -0.09596,0.1072444 -0.169334,0.2765776 -0.06773,0.1693332 -0.107244,0.3668886 -0.03387,0.191911 -0.03387,0.3725331 0,0.1749776 0.06209,0.2878664 0.06773,0.1072444 0.180622,0.1072444 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path761" />
|
||||
<path
|
||||
d="m 55.494598,7.1599009 q -0.287867,0 -0.474133,-0.1185332 Q 54.839843,6.91719 54.755176,6.7139901 54.67051,6.5107903 54.67051,6.2737238 q 0,-0.1580443 0.01693,-0.3217331 0.02258,-0.1636888 0.0508,-0.3104442 l 0.349955,-1.6594654 h 1.066799 l -0.355599,1.6989765 q -0.01693,0.073378 -0.03387,0.1862665 -0.01693,0.1072444 -0.01693,0.2031998 0,0.1185333 0.06209,0.1806221 0.06209,0.056444 0.146755,0.056444 0.141111,0 0.276578,-0.1919109 0.141111,-0.1975554 0.231422,-0.615244 l 0.321733,-1.5183544 h 1.066799 l -0.6604,3.1213754 h -0.85231 l 0.03387,-0.4346219 h -0.02258 q -0.1524,0.2596443 -0.3556,0.3781775 -0.2032,0.1128888 -0.502355,0.1128888 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path763" />
|
||||
<path
|
||||
d="m 59.044947,7.1599009 q -0.4064,0 -0.620889,-0.1749776 -0.208844,-0.1806221 -0.208844,-0.5757329 0,-0.1128888 0.02258,-0.2596443 0.02258,-0.1467554 0.04516,-0.2596442 l 0.231422,-1.1063103 h -0.423333 l 0.112889,-0.524933 0.598311,-0.2427109 0.378177,-0.6603995 h 0.7112 l -0.135467,0.6265329 h 0.795866 l -0.174978,0.8015105 h -0.795866 l -0.231422,1.0555103 q -0.01693,0.079022 -0.03387,0.1636888 -0.01129,0.079022 -0.01129,0.1241776 0,0.090311 0.0508,0.1354666 0.0508,0.039511 0.124177,0.039511 0.107245,0 0.237067,-0.033867 0.129822,-0.039511 0.265289,-0.095956 v 0.8015105 q -0.174978,0.084667 -0.4064,0.1354665 -0.225778,0.0508 -0.530577,0.0508 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path765" />
|
||||
<path
|
||||
d="M 62.567083,7.995278 Q 62.437261,7.763856 62.341306,7.4534118 62.24535,7.148612 62.19455,6.8268789 62.14939,6.4995014 62.14939,6.2059905 q 0,-0.9595548 0.361244,-1.7497764 0.366888,-0.7902217 1.049866,-1.4957767 h 0.891821 Q 64.051566,3.3950593 63.735477,3.8974145 63.419389,4.3941252 63.233122,4.981147 63.0525,5.5625243 63.0525,6.251146 q 0,0.2596443 0.03951,0.5700885 0.03951,0.3047998 0.107244,0.6095995 0.07338,0.3047998 0.174978,0.564444 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path767" />
|
||||
<path
|
||||
d="m 64.13624,7.1034565 0.660399,-3.1213754 h 0.852311 l -0.04516,0.513644 h 0.02258 q 0.163689,-0.3104442 0.372533,-0.4402663 0.208844,-0.1298221 0.530578,-0.1298221 0.321733,0 0.49671,0.1467554 0.174978,0.1467555 0.248356,0.423333 h 0.02258 q 0.344311,-0.5700884 0.948266,-0.5700884 0.383822,0 0.587022,0.2370665 0.2032,0.231422 0.2032,0.6829772 0,0.2539998 -0.06209,0.564444 l -0.344311,1.6933321 h -1.066799 l 0.3556,-1.7384876 q 0.01129,-0.056444 0.02258,-0.1523999 0.01693,-0.095955 0.01693,-0.2144887 0,-0.2257776 -0.191911,-0.2257776 -0.2032,0 -0.333022,0.2088443 -0.124178,0.2088443 -0.208844,0.6265329 l -0.3048,1.4957766 H 65.85215 l 0.361244,-1.7384876 q 0.01129,-0.062089 0.02258,-0.1636887 0.01693,-0.1016 0.01693,-0.1693332 0,-0.1411111 -0.05644,-0.1975555 -0.05644,-0.062089 -0.141111,-0.062089 -0.158045,0 -0.287867,0.1636888 Q 65.637664,5.09968 65.53042,5.5851019 l -0.327378,1.5183544 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path769" />
|
||||
<path
|
||||
d="m 70.734596,7.1599009 q -0.575733,0 -0.891822,-0.3104442 Q 69.53233,6.533368 69.53233,5.9576351 q 0,-0.4007552 0.112889,-0.7619994 0.112889,-0.3668886 0.333022,-0.6491106 0.220133,-0.2878665 0.547511,-0.4515552 0.333022,-0.1693332 0.767643,-0.1693332 0.575733,0 0.886178,0.3160886 0.316088,0.3104442 0.316088,0.8861771 0,0.4007553 -0.112889,0.7676439 -0.112888,0.3612442 -0.333022,0.6491106 -0.220133,0.282222 -0.553155,0.4515552 -0.327377,0.1636888 -0.761999,0.1636888 z m 0.118533,-0.8015105 q 0.158044,0 0.282222,-0.1862665 0.124178,-0.191911 0.197556,-0.4797774 0.07338,-0.2935109 0.07338,-0.5983107 0,-0.3668886 -0.237066,-0.3668886 -0.158045,0 -0.282222,0.1919109 -0.124178,0.1862666 -0.197556,0.474133 -0.06773,0.2878665 -0.06773,0.5983107 0,0.3668886 0.231422,0.3668886 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path771" />
|
||||
<path
|
||||
d="m 72.789175,7.1034565 0.660399,-3.1213754 h 0.852311 l -0.03387,0.4346219 h 0.02258 q 0.1524,-0.2652887 0.3556,-0.3781775 0.208844,-0.1128888 0.502355,-0.1128888 0.293511,0 0.474133,0.1241777 0.180622,0.1185332 0.265289,0.3217331 0.08467,0.1975554 0.08467,0.4402663 0,0.1580443 -0.02258,0.3217331 -0.01693,0.1636887 -0.04516,0.3104442 l -0.349955,1.6594654 h -1.0668 l 0.3556,-1.7046209 q 0.01693,-0.073378 0.03387,-0.1806221 0.01693,-0.1128888 0.01693,-0.2088443 0,-0.1185333 -0.06209,-0.1749777 -0.06209,-0.062089 -0.146755,-0.062089 -0.158045,0 -0.293511,0.1975554 -0.129822,0.191911 -0.214489,0.6095996 l -0.321733,1.5239988 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path773" />
|
||||
<path
|
||||
d="m 77.671611,7.1599009 q -0.575732,0 -0.891821,-0.3104442 -0.310444,-0.3160887 -0.310444,-0.8918216 0,-0.4007552 0.112888,-0.7619994 0.112889,-0.3668886 0.333022,-0.6491106 0.220134,-0.2878665 0.547511,-0.4515552 0.333022,-0.1693332 0.767644,-0.1693332 0.575733,0 0.886177,0.3160886 0.316089,0.3104442 0.316089,0.8861771 0,0.4007553 -0.112889,0.7676439 -0.112889,0.3612442 -0.333022,0.6491106 -0.220133,0.282222 -0.553155,0.4515552 -0.327378,0.1636888 -0.762,0.1636888 z m 0.118534,-0.8015105 q 0.158044,0 0.282222,-0.1862665 0.124177,-0.191911 0.197555,-0.4797774 0.07338,-0.2935109 0.07338,-0.5983107 0,-0.3668886 -0.237067,-0.3668886 -0.158044,0 -0.282222,0.1919109 -0.124177,0.1862666 -0.197555,0.474133 -0.06773,0.2878665 -0.06773,0.5983107 0,0.3668886 0.231422,0.3668886 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path775" />
|
||||
<path
|
||||
d="m 79.297213,7.995278 q 0.400755,-0.4346218 0.711199,-0.9313326 0.310445,-0.5023552 0.485422,-1.0893769 0.180622,-0.5870218 0.180622,-1.2699991 0,-0.2652887 -0.03951,-0.5700884 -0.03951,-0.3047998 -0.112888,-0.6095996 -0.07338,-0.3047997 -0.174978,-0.564444 h 0.812799 q 0.146756,0.2483554 0.237067,0.5531551 0.09031,0.3047998 0.135466,0.6265329 0.04516,0.3160887 0.04516,0.6095995 0,0.9595549 -0.349955,1.7497765 -0.344311,0.7902216 -1.032933,1.4957766 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path777" />
|
||||
</g>
|
||||
<path
|
||||
id="path1348"
|
||||
style="color:#000000;fill:#e0e0e0;fill-opacity:0.752941;stroke-width:0.714406;-inkscape-stroke:none"
|
||||
d="M 5.4193109,1.6360535 C 4.0746261,1.6465667 2.9804856,2.7485866 2.9805103,4.0933129 v 1.5080987 0.00443 0.00406 0.00702 c 0.00324,0.6351315 0.1709081,1.2397841 0.5330952,1.705241 0.091293,0.1173226 0.1960748,0.2241342 0.3126952,0.3186015 V 5.3666133 h 0.00259 V 4.0933129 C 3.8288705,3.2043172 4.5362516,2.4899017 5.4252198,2.4829515 6.3176074,2.4761075 7.0387059,3.1839609 7.0477631,4.0763306 v 0.016982 1.6742295 c 0,0.3851813 -0.1170262,0.6035969 -0.3182329,0.7675243 C 6.5283236,6.6989941 6.2034026,6.8056753 5.769664,6.8056753 H 5.437754 V 8.3957797 H 6.193851 V 7.5229912 C 6.5799202,7.4642455 6.9804539,7.4245038 7.2655789,7.1922063 7.6635843,6.8679419 7.8946602,6.354867 7.8946602,5.7675423 V 4.0933128 4.0693159 4.0682086 C 7.8809586,2.7185401 6.7690097,1.6257071 5.4193109,1.6360535 Z"
|
||||
sodipodi:nodetypes="ccccccscccccccsssccccsscccc" />
|
||||
<g
|
||||
aria-label="B"
|
||||
id="text1054"
|
||||
style="font-style:italic;font-weight:900;font-size:6.35px;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke-width:0.285001;stop-color:#000000"
|
||||
transform="matrix(0.71440613,0,0,0.71440613,-2.144828,0.00813001)">
|
||||
<path
|
||||
id="path1085"
|
||||
style="font-style:normal;-inkscape-font-specification:'Roboto, Heavy';stroke-width:0.285"
|
||||
d="M 8.865092,5.8580404 V 8.9958333 11.74073 H 9.9533976 V 8.9958333 h 0.7441404 c 0.549837,-0.00413 0.964283,-0.116789 1.243335,-0.3379638 0.281119,-0.223242 0.42168,-0.5560389 0.42168,-0.9983887 0,-0.2439125 -0.06305,-0.4506186 -0.189136,-0.6201172 -0.12609,-0.1694982 -0.306958,-0.2852537 -0.542602,-0.3472656 0.208772,-0.078548 0.366902,-0.2005048 0.474389,-0.3658692 0.107487,-0.1653644 0.161231,-0.3648358 0.161231,-0.598413 0,-0.4051429 -0.151929,-0.7141686 -0.455786,-0.9270752 C 11.508859,4.5878339 11.18123,4.4813802 10.486698,4.4813802 H 9.9533976 c -1.0883054,0 -1.0883056,1.029605 -1.0883056,1.3766602 z m 1.0883056,-0.022757 c 0,-0.3308701 0.1341694,-0.4768142 0.3334184,-0.4952 l 0.199882,-0.018444 c 0.203885,-0.018814 0.420647,0.042375 0.530201,0.127124 0.109553,0.082682 0.164331,0.2191083 0.164331,0.4092774 0,0.1653644 -0.05064,0.2904216 -0.151929,0.3751709 -0.101285,0.08475 -0.270784,0.1281579 -0.508496,0.1302246 H 9.9533976 Z m 0,1.2412875 h 0.7627444 c 0.374137,0.00207 0.561206,0.1912032 0.561206,0.5674073 0,0.1632973 -0.05271,0.2904217 -0.15813,0.381372 -0.105419,0.088883 -0.256315,0.1333252 -0.452686,0.1333252 H 9.9533976 Z"
|
||||
sodipodi:nodetypes="cccccccsscssczccssscssccsccscscc" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 22 KiB |
@@ -0,0 +1,156 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="350"
|
||||
height="36"
|
||||
viewBox="0 0 92.604162 9.525"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
inkscape:version="1.2.2 (732a01da63, 2022-12-09, custom)"
|
||||
sodipodi:docname="ToobCabSimLogo_master.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview7"
|
||||
pagecolor="#2e2e2e"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.414909"
|
||||
inkscape:cx="195.77231"
|
||||
inkscape:cy="90.465182"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1008"
|
||||
inkscape:window-x="1440"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1" />
|
||||
<defs
|
||||
id="defs2" />
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<g
|
||||
aria-label="TooB Record Input (stereo)"
|
||||
id="text236"
|
||||
style="font-style:italic;font-weight:bold;font-size:5.64444px;line-height:0;font-family:Timana;-inkscape-font-specification:'Timana Bold Italic';fill:#686868;stroke:#7f7f7f;stroke-width:0.285001;stop-color:#000000">
|
||||
<path
|
||||
d="m 10.655146,7.1034565 0.654755,-3.1383087 h -0.874888 l 0.191911,-0.8918216 h 2.833509 L 13.262878,3.9651478 H 12.38799 l -0.654756,3.1383087 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path893" />
|
||||
<path
|
||||
d="m 14.160346,7.1599009 q -0.575733,0 -0.891822,-0.3104442 Q 12.95808,6.533368 12.95808,5.9576351 q 0,-0.4007552 0.112889,-0.7619994 0.112889,-0.3668886 0.333022,-0.6491106 0.220133,-0.2878665 0.54751,-0.4515552 0.333022,-0.1693332 0.767644,-0.1693332 0.575733,0 0.886177,0.3160886 0.316089,0.3104442 0.316089,0.8861771 0,0.4007553 -0.112889,0.7676439 -0.112889,0.3612442 -0.333022,0.6491106 -0.220133,0.282222 -0.553155,0.4515552 -0.327377,0.1636888 -0.761999,0.1636888 z m 0.118533,-0.8015105 q 0.158044,0 0.282222,-0.1862665 0.124178,-0.191911 0.197555,-0.4797774 0.07338,-0.2935109 0.07338,-0.5983107 0,-0.3668886 -0.237066,-0.3668886 -0.158045,0 -0.282222,0.1919109 -0.124178,0.1862666 -0.197556,0.474133 -0.06773,0.2878665 -0.06773,0.5983107 0,0.3668886 0.231422,0.3668886 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path895" />
|
||||
<path
|
||||
d="m 17.586523,7.1599009 q -0.575733,0 -0.891822,-0.3104442 -0.310444,-0.3160887 -0.310444,-0.8918216 0,-0.4007552 0.112889,-0.7619994 0.112889,-0.3668886 0.333022,-0.6491106 0.220133,-0.2878665 0.54751,-0.4515552 0.333022,-0.1693332 0.767644,-0.1693332 0.575733,0 0.886177,0.3160886 0.316089,0.3104442 0.316089,0.8861771 0,0.4007553 -0.112889,0.7676439 -0.112889,0.3612442 -0.333022,0.6491106 -0.220133,0.282222 -0.553155,0.4515552 -0.327377,0.1636888 -0.761999,0.1636888 z m 0.118533,-0.8015105 q 0.158044,0 0.282222,-0.1862665 0.124178,-0.191911 0.197555,-0.4797774 0.07338,-0.2935109 0.07338,-0.5983107 0,-0.3668886 -0.237066,-0.3668886 -0.158045,0 -0.282222,0.1919109 -0.124178,0.1862666 -0.197556,0.474133 -0.06773,0.2878665 -0.06773,0.5983107 0,0.3668886 0.231422,0.3668886 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path897" />
|
||||
<path
|
||||
d="m 19.669324,7.1034565 0.85231,-4.0301303 h 1.343377 q 0.649111,0 0.931333,0.2483554 0.282222,0.2483553 0.282222,0.6321773 0,0.4120441 -0.214489,0.6660439 -0.208844,0.2539998 -0.603955,0.3725331 v 0.022578 q 0.242711,0.079022 0.383822,0.282222 0.146755,0.1975554 0.146755,0.4854219 0,0.4684885 -0.220133,0.7619994 -0.214489,0.2935109 -0.581377,0.4289775 -0.361244,0.1298221 -0.8128,0.1298221 z M 21.4699,4.6199028 q 0.282222,0 0.383822,-0.1241777 0.107245,-0.1241776 0.107245,-0.3160886 0,-0.282222 -0.349956,-0.282222 h -0.174977 l -0.163689,0.7224883 z m -0.316088,1.6425321 q 0.248355,0 0.400755,-0.1354666 0.1524,-0.141111 0.1524,-0.3330219 0,-0.191911 -0.09031,-0.282222 -0.09031,-0.095956 -0.321733,-0.095956 h -0.186267 l -0.180622,0.846666 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path899" />
|
||||
<path
|
||||
d="m 24.715459,7.1034565 0.85231,-4.0301303 h 1.0668 q 0.694266,0 1.061154,0.2765776 0.372533,0.2765775 0.372533,0.8297327 0,0.3668886 -0.124177,0.615244 -0.118534,0.2483553 -0.299156,0.3951108 -0.180622,0.1467554 -0.355599,0.2257776 l 0.728132,1.6876876 H 26.843413 L 26.307191,5.6359021 h -0.2032 L 25.793547,7.1034565 Z M 26.42008,4.8174582 q 0.214489,0 0.389466,-0.1298221 0.180622,-0.1298221 0.180622,-0.4402663 0,-0.1467555 -0.08467,-0.2483554 -0.07902,-0.1015999 -0.287867,-0.1015999 H 26.47088 l -0.191911,0.9200437 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path901" />
|
||||
<path
|
||||
d="m 29.761587,7.1599009 q -0.592667,0 -0.9144,-0.3273775 -0.321733,-0.333022 -0.321733,-0.9087549 0,-0.3838219 0.107245,-0.7394217 0.112888,-0.3612441 0.333021,-0.6434661 0.220134,-0.2822221 0.553156,-0.4459108 0.338666,-0.1693332 0.795866,-0.1693332 0.524933,0 0.824088,0.2370665 0.299155,0.2370665 0.299155,0.6321773 0,0.513644 -0.400755,0.8297327 -0.400755,0.3160886 -1.275643,0.3160886 h -0.163689 v 0.045155 q 0,0.4063997 0.451555,0.4063997 0.237066,0 0.445911,-0.073378 0.214488,-0.073378 0.457199,-0.1975554 v 0.756355 q -0.248355,0.1241777 -0.519288,0.2031998 -0.265289,0.079022 -0.671688,0.079022 z m 0.02258,-1.885243 q 0.361244,0 0.502355,-0.1354666 0.141111,-0.141111 0.141111,-0.282222 0,-0.090311 -0.05644,-0.1467554 -0.05644,-0.062089 -0.174978,-0.062089 -0.124177,0 -0.231422,0.095955 -0.1016,0.095955 -0.169333,0.2427109 -0.06773,0.141111 -0.09031,0.2878665 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path903" />
|
||||
<path
|
||||
d="m 32.956342,7.1599009 q -0.316089,0 -0.581377,-0.1298221 -0.265289,-0.1298221 -0.423333,-0.4120442 -0.158045,-0.282222 -0.158045,-0.7337772 0,-0.5531551 0.2032,-0.9934215 0.208844,-0.4459107 0.581377,-0.705555 0.378178,-0.2596442 0.886178,-0.2596442 0.29351,0 0.530577,0.056444 0.242711,0.0508 0.479777,0.1636887 L 34.13603,4.9359915 q -0.141111,-0.062089 -0.3048,-0.1128888 -0.163689,-0.0508 -0.316088,-0.0508 -0.163689,0 -0.287867,0.1072444 -0.124178,0.1015999 -0.2032,0.2652887 -0.07902,0.1580443 -0.118533,0.3386664 -0.03951,0.1806221 -0.03951,0.3330219 0,0.2765776 0.09031,0.383822 0.09596,0.1015999 0.254,0.1015999 0.197555,0 0.383822,-0.062089 0.186266,-0.067733 0.395111,-0.1749777 v 0.846666 q -0.220134,0.1185333 -0.462845,0.1862666 -0.24271,0.062089 -0.570088,0.062089 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path905" />
|
||||
<path
|
||||
d="m 35.840648,7.1599009 q -0.575733,0 -0.891821,-0.3104442 -0.310444,-0.3160887 -0.310444,-0.8918216 0,-0.4007552 0.112888,-0.7619994 0.112889,-0.3668886 0.333022,-0.6491106 0.220133,-0.2878665 0.547511,-0.4515552 0.333022,-0.1693332 0.767644,-0.1693332 0.575733,0 0.886177,0.3160886 0.316089,0.3104442 0.316089,0.8861771 0,0.4007553 -0.112889,0.7676439 -0.112889,0.3612442 -0.333022,0.6491106 -0.220133,0.282222 -0.553155,0.4515552 -0.327378,0.1636888 -0.762,0.1636888 z m 0.118534,-0.8015105 q 0.158044,0 0.282222,-0.1862665 0.124177,-0.191911 0.197555,-0.4797774 0.07338,-0.2935109 0.07338,-0.5983107 0,-0.3668886 -0.237067,-0.3668886 -0.158044,0 -0.282222,0.1919109 -0.124178,0.1862666 -0.197555,0.474133 -0.06773,0.2878665 -0.06773,0.5983107 0,0.3668886 0.231423,0.3668886 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path907" />
|
||||
<path
|
||||
d="m 37.895227,7.1034565 0.6604,-3.1213754 h 0.85231 l -0.0508,0.5192885 h 0.02258 q 0.197555,-0.333022 0.4064,-0.4515552 0.214488,-0.1241777 0.530577,-0.1241777 0.06209,0 0.129822,0.00564 0.06773,0.00564 0.09031,0.016933 l -0.231422,1.0555104 q -0.05644,-0.028222 -0.146755,-0.045156 -0.09031,-0.016933 -0.191911,-0.016933 -0.248356,0 -0.434622,0.1693332 -0.180622,0.1693332 -0.276578,0.6208884 l -0.29351,1.371599 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path909" />
|
||||
<path
|
||||
d="m 41.304469,7.1599009 q -0.237067,0 -0.440267,-0.1128888 Q 40.661003,6.9341233 40.536825,6.674479 40.418292,6.4148348 40.418292,5.968924 q 0,-0.2257776 0.0508,-0.5023552 0.05644,-0.2765775 0.163688,-0.5475107 0.107245,-0.2709331 0.270934,-0.4967107 0.163688,-0.2257776 0.389466,-0.3612442 0.225778,-0.1354665 0.508,-0.1354665 0.253999,0 0.389466,0.1128888 0.141111,0.1128888 0.265289,0.3047998 h 0.02258 q 0,-0.033867 0.0056,-0.1523999 0.0056,-0.1185333 0.02258,-0.2652887 0.01693,-0.1523999 0.04516,-0.282222 L 42.721223,2.813682 h 1.078088 l -0.908755,4.2897745 h -0.85231 l 0.02822,-0.3386664 H 42.04389 Q 41.931002,6.9228344 41.767313,7.0413677 41.603624,7.1599009 41.304469,7.1599009 Z M 41.744735,6.301946 q 0.124178,0 0.220133,-0.1072444 0.1016,-0.1128888 0.169333,-0.282222 0.07338,-0.1749776 0.107245,-0.3668886 0.03951,-0.1975554 0.03951,-0.3668886 0,-0.1806221 -0.05644,-0.2878665 -0.0508,-0.1072443 -0.163689,-0.1072443 -0.146756,0 -0.276578,0.1693332 -0.124177,0.1693332 -0.2032,0.4289774 -0.07338,0.2539999 -0.07338,0.524933 0,0.3951108 0.237066,0.3951108 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path911" />
|
||||
<path
|
||||
d="m 44.860468,7.1034565 0.129823,-0.615244 0.530577,-0.2201331 0.496711,-2.3367983 -0.440267,-0.2370665 0.129822,-0.6208884 h 2.07151 l -0.129822,0.6208884 -0.553155,0.2370665 -0.496711,2.3367983 0.445911,0.2201331 -0.129822,0.615244 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path913" />
|
||||
<path
|
||||
d="m 47.53029,7.1034565 0.6604,-3.1213754 H 49.043 L 49.00913,4.416703 h 0.02258 q 0.152399,-0.2652887 0.355599,-0.3781775 0.208845,-0.1128888 0.502355,-0.1128888 0.293511,0 0.474133,0.1241777 0.180623,0.1185332 0.265289,0.3217331 0.08467,0.1975554 0.08467,0.4402663 0,0.1580443 -0.02258,0.3217331 -0.01693,0.1636887 -0.04516,0.3104442 l -0.349955,1.6594654 h -1.066799 l 0.3556,-1.7046209 q 0.01693,-0.073378 0.03387,-0.1806221 0.01693,-0.1128888 0.01693,-0.2088443 0,-0.1185333 -0.06209,-0.1749777 -0.06209,-0.062089 -0.146756,-0.062089 -0.158044,0 -0.293511,0.1975554 -0.129822,0.191911 -0.214488,0.6095996 l -0.321727,1.523999 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path915" />
|
||||
<path
|
||||
d="m 50.753265,8.4581221 0.948266,-4.476041 h 0.852311 l -0.03387,0.3499553 h 0.02258 q 0.129822,-0.1975554 0.299155,-0.2991554 0.174978,-0.1072443 0.412044,-0.1072443 0.417689,0 0.666044,0.2991553 0.254,0.2991553 0.254,0.8523105 0,0.3894663 -0.1016,0.7619994 -0.09595,0.3668886 -0.276577,0.6660439 -0.180622,0.2991554 -0.440267,0.4797775 -0.259644,0.1749776 -0.581377,0.1749776 -0.208844,0 -0.366889,-0.1072444 -0.158044,-0.1128888 -0.270933,-0.2935109 h -0.02258 q -0.01693,0.2201332 -0.04515,0.4346219 -0.02822,0.2201332 -0.107244,0.5870218 L 51.820065,8.4581221 Z M 52.559486,6.301946 q 0.146756,0 0.265289,-0.1693332 0.118533,-0.1693332 0.186266,-0.4289775 0.07338,-0.2596442 0.07338,-0.5249329 0,-0.3951108 -0.237066,-0.3951108 -0.124178,0 -0.220133,0.1072443 -0.09596,0.1072444 -0.169334,0.2765776 -0.06773,0.1693332 -0.107244,0.3668886 -0.03387,0.191911 -0.03387,0.3725331 0,0.1749776 0.06209,0.2878664 0.06773,0.1072444 0.180622,0.1072444 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path917" />
|
||||
<path
|
||||
d="m 55.494598,7.1599009 q -0.287867,0 -0.474133,-0.1185332 Q 54.839843,6.91719 54.755176,6.7139901 54.67051,6.5107903 54.67051,6.2737238 q 0,-0.1580443 0.01693,-0.3217331 0.02258,-0.1636888 0.0508,-0.3104442 l 0.349955,-1.6594654 h 1.066799 l -0.355599,1.6989765 q -0.01693,0.073378 -0.03387,0.1862665 -0.01693,0.1072444 -0.01693,0.2031998 0,0.1185333 0.06209,0.1806221 0.06209,0.056444 0.146755,0.056444 0.141111,0 0.276578,-0.1919109 0.141111,-0.1975554 0.231422,-0.615244 l 0.321733,-1.5183544 h 1.066799 l -0.6604,3.1213754 h -0.85231 l 0.03387,-0.4346219 h -0.02258 q -0.1524,0.2596443 -0.3556,0.3781775 -0.2032,0.1128888 -0.502355,0.1128888 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path919" />
|
||||
<path
|
||||
d="m 59.044947,7.1599009 q -0.4064,0 -0.620889,-0.1749776 -0.208844,-0.1806221 -0.208844,-0.5757329 0,-0.1128888 0.02258,-0.2596443 0.02258,-0.1467554 0.04516,-0.2596442 l 0.231422,-1.1063103 h -0.423333 l 0.112889,-0.524933 0.598311,-0.2427109 0.378177,-0.6603995 h 0.7112 l -0.135467,0.6265329 h 0.795866 l -0.174978,0.8015105 h -0.795866 l -0.231422,1.0555103 q -0.01693,0.079022 -0.03387,0.1636888 -0.01129,0.079022 -0.01129,0.1241776 0,0.090311 0.0508,0.1354666 0.0508,0.039511 0.124177,0.039511 0.107245,0 0.237067,-0.033867 0.129822,-0.039511 0.265289,-0.095956 v 0.8015105 q -0.174978,0.084667 -0.4064,0.1354665 -0.225778,0.0508 -0.530577,0.0508 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path921" />
|
||||
<path
|
||||
d="M 62.567083,7.995278 Q 62.437261,7.763856 62.341306,7.4534118 62.24535,7.148612 62.19455,6.8268789 62.14939,6.4995014 62.14939,6.2059905 q 0,-0.9595548 0.361244,-1.7497764 0.366888,-0.7902217 1.049866,-1.4957767 h 0.891821 Q 64.051566,3.3950593 63.735477,3.8974145 63.419389,4.3941252 63.233122,4.981147 63.0525,5.5625243 63.0525,6.251146 q 0,0.2596443 0.03951,0.5700885 0.03951,0.3047998 0.107244,0.6095995 0.07338,0.3047998 0.174978,0.564444 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path923" />
|
||||
<path
|
||||
d="m 65.14095,7.1599009 q -0.310444,0 -0.558799,-0.045155 -0.242711,-0.045155 -0.423333,-0.1298221 v -0.857955 q 0.253999,0.1411111 0.468488,0.1975555 0.220133,0.0508 0.445911,0.0508 0.06773,0 0.1524,-0.011289 0.09031,-0.016933 0.1524,-0.056444 0.06773,-0.039511 0.06773,-0.1241777 0,-0.062089 -0.02822,-0.1128888 -0.02822,-0.0508 -0.118533,-0.1185332 -0.09031,-0.067733 -0.282222,-0.1693332 -0.293511,-0.1636888 -0.428978,-0.3668886 -0.129822,-0.2088443 -0.129822,-0.5023552 0,-0.4402663 0.310444,-0.7111995 0.316089,-0.2765775 0.970844,-0.2765775 0.3048,0 0.558799,0.073378 0.259645,0.073378 0.496711,0.2201332 L 66.461749,4.9134137 Q 66.303705,4.8118138 66.10615,4.7327916 q -0.191911,-0.079022 -0.3556,-0.079022 -0.208845,0 -0.208845,0.1862665 0,0.079022 0.08467,0.141111 0.09031,0.062089 0.282222,0.1580443 0.620889,0.3047998 0.620889,0.8805327 0,0.5813773 -0.378178,0.8635993 -0.372533,0.2765776 -1.010355,0.2765776 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path925" />
|
||||
<path
|
||||
d="m 68.036554,7.1599009 q -0.406399,0 -0.620888,-0.1749776 -0.208844,-0.1806221 -0.208844,-0.5757329 0,-0.1128888 0.02258,-0.2596443 0.02258,-0.1467554 0.04516,-0.2596442 l 0.231422,-1.1063103 h -0.423333 l 0.112889,-0.524933 0.59831,-0.2427109 0.378178,-0.6603995 h 0.711199 l -0.135466,0.6265329 h 0.795866 l -0.174978,0.8015105 h -0.795866 l -0.231422,1.0555103 q -0.01693,0.079022 -0.03387,0.1636888 -0.01129,0.079022 -0.01129,0.1241776 0,0.090311 0.0508,0.1354666 0.0508,0.039511 0.124178,0.039511 0.107244,0 0.237067,-0.033867 0.129822,-0.039511 0.265288,-0.095956 v 0.8015105 q -0.174977,0.084667 -0.406399,0.1354665 -0.225778,0.0508 -0.530578,0.0508 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path927" />
|
||||
<path
|
||||
d="m 70.954734,7.1599009 q -0.592666,0 -0.914399,-0.3273775 -0.321733,-0.333022 -0.321733,-0.9087549 0,-0.3838219 0.107244,-0.7394217 0.112889,-0.3612441 0.333022,-0.6434661 0.220133,-0.2822221 0.553155,-0.4459108 0.338667,-0.1693332 0.795866,-0.1693332 0.524933,0 0.824089,0.2370665 0.299155,0.2370665 0.299155,0.6321773 0,0.513644 -0.400755,0.8297327 -0.400756,0.3160886 -1.275644,0.3160886 h -0.163689 v 0.045155 q 0,0.4063997 0.451556,0.4063997 0.237066,0 0.44591,-0.073378 0.214489,-0.073378 0.4572,-0.1975554 v 0.756355 q -0.248355,0.1241777 -0.519288,0.2031998 -0.265289,0.079022 -0.671689,0.079022 z m 0.02258,-1.885243 q 0.361244,0 0.502355,-0.1354666 0.141111,-0.141111 0.141111,-0.282222 0,-0.090311 -0.05644,-0.1467554 -0.05644,-0.062089 -0.174978,-0.062089 -0.124178,0 -0.231422,0.095955 -0.1016,0.095955 -0.169333,0.2427109 -0.06773,0.141111 -0.09031,0.2878665 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path929" />
|
||||
<path
|
||||
d="m 72.817404,7.1034565 0.660399,-3.1213754 h 0.852311 l -0.0508,0.5192885 h 0.02258 q 0.197556,-0.333022 0.4064,-0.4515552 0.214489,-0.1241777 0.530578,-0.1241777 0.06209,0 0.129822,0.00564 0.06773,0.00564 0.09031,0.016933 L 75.22758,5.0037248 q -0.05644,-0.028222 -0.146756,-0.045156 -0.09031,-0.016933 -0.191911,-0.016933 -0.248355,0 -0.434622,0.1693332 -0.180622,0.1693332 -0.276577,0.6208884 l -0.293511,1.371599 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path931" />
|
||||
<path
|
||||
d="m 76.576595,7.1599009 q -0.592667,0 -0.9144,-0.3273775 -0.321733,-0.333022 -0.321733,-0.9087549 0,-0.3838219 0.107245,-0.7394217 0.112888,-0.3612441 0.333022,-0.6434661 0.220133,-0.2822221 0.553155,-0.4459108 0.338666,-0.1693332 0.795866,-0.1693332 0.524933,0 0.824088,0.2370665 0.299155,0.2370665 0.299155,0.6321773 0,0.513644 -0.400755,0.8297327 -0.400755,0.3160886 -1.275643,0.3160886 h -0.163689 v 0.045155 q 0,0.4063997 0.451555,0.4063997 0.237067,0 0.445911,-0.073378 0.214489,-0.073378 0.4572,-0.1975554 v 0.756355 q -0.248356,0.1241777 -0.519289,0.2031998 -0.265289,0.079022 -0.671688,0.079022 z m 0.02258,-1.885243 q 0.361245,0 0.502356,-0.1354666 0.141111,-0.141111 0.141111,-0.282222 0,-0.090311 -0.05644,-0.1467554 -0.05644,-0.062089 -0.174977,-0.062089 -0.124178,0 -0.231422,0.095955 -0.1016,0.095955 -0.169334,0.2427109 -0.06773,0.141111 -0.09031,0.2878665 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path933" />
|
||||
<path
|
||||
d="m 79.810863,7.1599009 q -0.575733,0 -0.891821,-0.3104442 -0.310445,-0.3160887 -0.310445,-0.8918216 0,-0.4007552 0.112889,-0.7619994 0.112889,-0.3668886 0.333022,-0.6491106 0.220133,-0.2878665 0.547511,-0.4515552 0.333022,-0.1693332 0.767644,-0.1693332 0.575733,0 0.886177,0.3160886 0.316088,0.3104442 0.316088,0.8861771 0,0.4007553 -0.112888,0.7676439 -0.112889,0.3612442 -0.333022,0.6491106 -0.220133,0.282222 -0.553155,0.4515552 -0.327378,0.1636888 -0.762,0.1636888 z m 0.118533,-0.8015105 q 0.158045,0 0.282222,-0.1862665 0.124178,-0.191911 0.197556,-0.4797774 0.07338,-0.2935109 0.07338,-0.5983107 0,-0.3668886 -0.237067,-0.3668886 -0.158044,0 -0.282222,0.1919109 -0.124178,0.1862666 -0.197555,0.474133 -0.06773,0.2878665 -0.06773,0.5983107 0,0.3668886 0.231422,0.3668886 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path935" />
|
||||
<path
|
||||
d="m 81.436465,7.995278 q 0.400755,-0.4346218 0.711199,-0.9313326 0.310444,-0.5023552 0.485422,-1.0893769 0.180622,-0.5870218 0.180622,-1.2699991 0,-0.2652887 -0.03951,-0.5700884 -0.03951,-0.3047998 -0.112889,-0.6095996 -0.07338,-0.3047997 -0.174977,-0.564444 h 0.812799 q 0.146755,0.2483554 0.237066,0.5531551 0.09031,0.3047998 0.135467,0.6265329 0.04516,0.3160887 0.04516,0.6095995 0,0.9595549 -0.349956,1.7497765 -0.344311,0.7902216 -1.032932,1.4957766 z"
|
||||
style="font-weight:900;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke:none;stroke-width:0.285"
|
||||
id="path937" />
|
||||
</g>
|
||||
<path
|
||||
id="path1348"
|
||||
style="color:#000000;fill:#e0e0e0;fill-opacity:0.752941;stroke-width:0.714406;-inkscape-stroke:none"
|
||||
d="M 5.4193109,1.6360535 C 4.0746261,1.6465667 2.9804856,2.7485866 2.9805103,4.0933129 v 1.5080987 0.00443 0.00406 0.00702 c 0.00324,0.6351315 0.1709081,1.2397841 0.5330952,1.705241 0.091293,0.1173226 0.1960748,0.2241342 0.3126952,0.3186015 V 5.3666133 h 0.00259 V 4.0933129 C 3.8288705,3.2043172 4.5362516,2.4899017 5.4252198,2.4829515 6.3176074,2.4761075 7.0387059,3.1839609 7.0477631,4.0763306 v 0.016982 1.6742295 c 0,0.3851813 -0.1170262,0.6035969 -0.3182329,0.7675243 C 6.5283236,6.6989941 6.2034026,6.8056753 5.769664,6.8056753 H 5.437754 V 8.3957797 H 6.193851 V 7.5229912 C 6.5799202,7.4642455 6.9804539,7.4245038 7.2655789,7.1922063 7.6635843,6.8679419 7.8946602,6.354867 7.8946602,5.7675423 V 4.0933128 4.0693159 4.0682086 C 7.8809586,2.7185401 6.7690097,1.6257071 5.4193109,1.6360535 Z"
|
||||
sodipodi:nodetypes="ccccccscccccccsssccccsscccc" />
|
||||
<g
|
||||
aria-label="B"
|
||||
id="text1054"
|
||||
style="font-style:italic;font-weight:900;font-size:6.35px;font-family:Roboto;-inkscape-font-specification:'Roboto, Heavy Italic';fill:#e0e0e0;fill-opacity:0.752941;stroke-width:0.285001;stop-color:#000000"
|
||||
transform="matrix(0.71440613,0,0,0.71440613,-2.144828,0.00813001)">
|
||||
<path
|
||||
id="path1085"
|
||||
style="font-style:normal;-inkscape-font-specification:'Roboto, Heavy';stroke-width:0.285"
|
||||
d="M 8.865092,5.8580404 V 8.9958333 11.74073 H 9.9533976 V 8.9958333 h 0.7441404 c 0.549837,-0.00413 0.964283,-0.116789 1.243335,-0.3379638 0.281119,-0.223242 0.42168,-0.5560389 0.42168,-0.9983887 0,-0.2439125 -0.06305,-0.4506186 -0.189136,-0.6201172 -0.12609,-0.1694982 -0.306958,-0.2852537 -0.542602,-0.3472656 0.208772,-0.078548 0.366902,-0.2005048 0.474389,-0.3658692 0.107487,-0.1653644 0.161231,-0.3648358 0.161231,-0.598413 0,-0.4051429 -0.151929,-0.7141686 -0.455786,-0.9270752 C 11.508859,4.5878339 11.18123,4.4813802 10.486698,4.4813802 H 9.9533976 c -1.0883054,0 -1.0883056,1.029605 -1.0883056,1.3766602 z m 1.0883056,-0.022757 c 0,-0.3308701 0.1341694,-0.4768142 0.3334184,-0.4952 l 0.199882,-0.018444 c 0.203885,-0.018814 0.420647,0.042375 0.530201,0.127124 0.109553,0.082682 0.164331,0.2191083 0.164331,0.4092774 0,0.1653644 -0.05064,0.2904216 -0.151929,0.3751709 -0.101285,0.08475 -0.270784,0.1281579 -0.508496,0.1302246 H 9.9533976 Z m 0,1.2412875 h 0.7627444 c 0.374137,0.00207 0.561206,0.1912032 0.561206,0.5674073 0,0.1632973 -0.05271,0.2904217 -0.15813,0.381372 -0.105419,0.088883 -0.256315,0.1333252 -0.452686,0.1333252 H 9.9533976 Z"
|
||||
sodipodi:nodetypes="cccccccsscssczccssscssccsccscscc" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 7.2 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
|
After Width: | Height: | Size: 5.8 KiB |
@@ -720,7 +720,7 @@ namespace pipedal
|
||||
|
||||
std::vector<float *> &buffers = this->captureBuffers;
|
||||
int channels = this->captureChannels;
|
||||
constexpr float scale = 1.0f / (std::numeric_limits<int16_t>::max() + 1L);
|
||||
constexpr double scale = 1.0f / (std::numeric_limits<int16_t>::max() + 1L);
|
||||
for (size_t frame = 0; frame < frames; ++frame)
|
||||
{
|
||||
for (int channel = 0; channel < channels; ++channel)
|
||||
@@ -891,7 +891,7 @@ namespace pipedal
|
||||
|
||||
std::vector<float *> &buffers = this->playbackBuffers;
|
||||
int channels = this->playbackChannels;
|
||||
constexpr float scale = std::numeric_limits<int32_t>::max();
|
||||
constexpr double scale = std::numeric_limits<int32_t>::max();
|
||||
for (size_t frame = 0; frame < frames; ++frame)
|
||||
{
|
||||
for (int channel = 0; channel < channels; ++channel)
|
||||
@@ -913,7 +913,7 @@ namespace pipedal
|
||||
|
||||
std::vector<float *> &buffers = this->playbackBuffers;
|
||||
int channels = this->playbackChannels;
|
||||
constexpr float scale = 0x00FFFFFF;
|
||||
constexpr double scale = 0x00FFFFFF;
|
||||
for (size_t frame = 0; frame < frames; ++frame)
|
||||
{
|
||||
for (int channel = 0; channel < channels; ++channel)
|
||||
@@ -935,7 +935,7 @@ namespace pipedal
|
||||
|
||||
std::vector<float *> &buffers = this->playbackBuffers;
|
||||
int channels = this->playbackChannels;
|
||||
constexpr float scale = 0x00FFFFFF;
|
||||
constexpr double scale = 0x00FFFFFF;
|
||||
for (size_t frame = 0; frame < frames; ++frame)
|
||||
{
|
||||
for (int channel = 0; channel < channels; ++channel)
|
||||
@@ -955,7 +955,7 @@ namespace pipedal
|
||||
|
||||
std::vector<float *> &buffers = this->playbackBuffers;
|
||||
int channels = this->playbackChannels;
|
||||
constexpr float scale = std::numeric_limits<int32_t>::max();
|
||||
constexpr double scale = std::numeric_limits<int32_t>::max();
|
||||
for (size_t frame = 0; frame < frames; ++frame)
|
||||
{
|
||||
for (int channel = 0; channel < channels; ++channel)
|
||||
@@ -975,7 +975,7 @@ namespace pipedal
|
||||
|
||||
std::vector<float *> &buffers = this->playbackBuffers;
|
||||
int channels = this->playbackChannels;
|
||||
constexpr float scale = std::numeric_limits<int32_t>::max();
|
||||
constexpr double scale = std::numeric_limits<int32_t>::max();
|
||||
for (size_t frame = 0; frame < frames; ++frame)
|
||||
{
|
||||
for (int channel = 0; channel < channels; ++channel)
|
||||
@@ -1000,7 +1000,7 @@ namespace pipedal
|
||||
|
||||
std::vector<float *> &buffers = this->playbackBuffers;
|
||||
int channels = this->playbackChannels;
|
||||
constexpr float scale = std::numeric_limits<int32_t>::max();
|
||||
constexpr double scale = std::numeric_limits<int32_t>::max();
|
||||
for (size_t frame = 0; frame < frames; ++frame)
|
||||
{
|
||||
for (int channel = 0; channel < channels; ++channel)
|
||||
|
||||
@@ -867,6 +867,7 @@ private:
|
||||
pEffect->RequestAllPathPatchProperties();
|
||||
}
|
||||
}
|
||||
realtimeActivePedalboard->UpdateAudioPorts();
|
||||
}
|
||||
reEntered = false;
|
||||
|
||||
@@ -1696,7 +1697,6 @@ public:
|
||||
{
|
||||
if (pPedalboard)
|
||||
{
|
||||
pPedalboard->Deactivate();
|
||||
std::lock_guard guard(mutex);
|
||||
|
||||
for (auto it = activePedalboards.begin(); it != activePedalboards.end(); ++it)
|
||||
|
||||
@@ -5,7 +5,7 @@ set (CMAKE_INSTALL_PREFIX "/usr/")
|
||||
|
||||
set (USE_PCH 1)
|
||||
|
||||
set (ENABLE_BACKTRACE 1)
|
||||
set (ENABLE_BACKTRACE 0)
|
||||
|
||||
set (USE_SANITIZE OFF) # seems to be broken on Ubuntu 24.10
|
||||
|
||||
|
||||
@@ -724,7 +724,8 @@ void SetVarPermissions(
|
||||
|
||||
if (chown(entry.path().c_str(), uid, gid) != 0)
|
||||
{
|
||||
std::cout << "Error: failed to set ownership of file " << entry.path() << std::endl;
|
||||
// Expect spurious pulse config files to be un-chown-able.
|
||||
// std::cout << "Error: failed to set ownership of file " << entry.path() << std::endl;
|
||||
}
|
||||
|
||||
try
|
||||
@@ -740,7 +741,8 @@ void SetVarPermissions(
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
std::cout << "Error: failed to set permissions on file " << entry.path() << std::endl;
|
||||
// spurious errors on pulse config files.
|
||||
// std::cout << "Error: failed to set permissions on file " << entry.path() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -353,7 +353,6 @@ void Lv2Effect::PreparePortIndices()
|
||||
{
|
||||
this->isInputTriggerControlPort[portIndex] = true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -402,6 +401,13 @@ void Lv2Effect::SetAudioInputBuffer(int index, float *buffer)
|
||||
{
|
||||
this->inputAudioBuffers[index] = buffer;
|
||||
|
||||
if (borrowedEffect)
|
||||
{
|
||||
// Already running on the realtime thread,
|
||||
// so don't update the audio ports until the effect gets placed on the realtime thread.
|
||||
return;
|
||||
}
|
||||
|
||||
if (inputAudioPortIndices.size() == inputAudioBuffers.size())
|
||||
{
|
||||
int pluginIndex = this->inputAudioPortIndices[index];
|
||||
@@ -409,12 +415,13 @@ void Lv2Effect::SetAudioInputBuffer(int index, float *buffer)
|
||||
}
|
||||
else
|
||||
{
|
||||
// cases: 1->0, 1->1, 2->0, 2->1
|
||||
if (index < inputAudioPortIndices.size())
|
||||
{
|
||||
int pluginIndex = this->inputAudioPortIndices[index];
|
||||
lilv_instance_connect_port(this->pInstance, pluginIndex, buffer);
|
||||
}
|
||||
throw std::runtime_error("Invalid input buffer index.");
|
||||
// // cases: 1->0, 1->1, 2->0, 2->1
|
||||
// if (index < inputAudioPortIndices.size())
|
||||
// {
|
||||
// int pluginIndex = this->inputAudioPortIndices[index];
|
||||
// lilv_instance_connect_port(this->pInstance, pluginIndex, buffer);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -425,7 +432,7 @@ void Lv2Effect::SetAudioInputBuffer(float *left)
|
||||
SetAudioInputBuffer(0, left);
|
||||
SetAudioInputBuffer(1, left);
|
||||
}
|
||||
else if (GetNumberOfInputAudioBuffers() != 0)
|
||||
else if (GetNumberOfInputAudioBuffers() != 0)
|
||||
{
|
||||
SetAudioInputBuffer(0, left);
|
||||
}
|
||||
@@ -448,9 +455,16 @@ void Lv2Effect::SetAudioOutputBuffer(int index, float *buffer)
|
||||
{
|
||||
this->outputAudioBuffers[index] = buffer;
|
||||
|
||||
if (borrowedEffect)
|
||||
{
|
||||
// Effect is already running on the realtime thread,
|
||||
// so don't update the audio ports until the updated pedalboard gets placed on the realtime thread.
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->inputAudioPortIndices.size() != 0) // i.e. we're not mixing a zero-input control
|
||||
{
|
||||
if ((size_t)index < this->inputAudioPortIndices.size())
|
||||
if ((size_t)index < this->outputAudioPortIndices.size())
|
||||
{
|
||||
int pluginIndex = this->outputAudioPortIndices[index];
|
||||
lilv_instance_connect_port(pInstance, pluginIndex, buffer);
|
||||
@@ -470,6 +484,10 @@ int Lv2Effect::GetControlIndex(const std::string &key) const
|
||||
|
||||
Lv2Effect::~Lv2Effect()
|
||||
{
|
||||
if (activated)
|
||||
{
|
||||
Deactivate();
|
||||
}
|
||||
if (worker)
|
||||
{
|
||||
worker->Close();
|
||||
@@ -489,11 +507,40 @@ Lv2Effect::~Lv2Effect()
|
||||
|
||||
void Lv2Effect::Activate()
|
||||
{
|
||||
if (this->activated)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this->activated = true;
|
||||
this->AssignUnconnectedPorts();
|
||||
lilv_instance_activate(pInstance);
|
||||
this->BypassTo(this->bypass ? 1.0f : 0.0f);
|
||||
}
|
||||
|
||||
void Lv2Effect::UpdateAudioPorts()
|
||||
{
|
||||
// called on realtime thread to switch borrowed effects to the new buffer pointers.
|
||||
if (borrowedEffect)
|
||||
{
|
||||
for (size_t i = 0; i < this->inputAudioPortIndices.size(); ++i)
|
||||
{
|
||||
int portIndex = this->inputAudioPortIndices[i];
|
||||
if (GetAudioInputBuffer(i) != nullptr)
|
||||
{
|
||||
lilv_instance_connect_port(pInstance, portIndex, GetAudioInputBuffer(i));
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < this->outputAudioPortIndices.size(); ++i)
|
||||
{
|
||||
int portIndex = this->outputAudioPortIndices[i];
|
||||
if (GetAudioOutputBuffer(i) != nullptr)
|
||||
{
|
||||
lilv_instance_connect_port(pInstance, portIndex, GetAudioOutputBuffer(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Lv2Effect::AssignUnconnectedPorts()
|
||||
{
|
||||
for (size_t i = 0; i < this->inputAudioPortIndices.size(); ++i)
|
||||
@@ -515,6 +562,7 @@ void Lv2Effect::AssignUnconnectedPorts()
|
||||
{
|
||||
float *buffer = bufferPool.AllocateBuffer<float>(pHost->GetMaxAudioBufferSize());
|
||||
int pluginIndex = this->outputAudioPortIndices[i];
|
||||
lilv_instance_connect_port(pInstance, pluginIndex, buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -545,6 +593,11 @@ void Lv2Effect::AssignUnconnectedPorts()
|
||||
}
|
||||
void Lv2Effect::Deactivate()
|
||||
{
|
||||
if (!activated)
|
||||
{
|
||||
return;
|
||||
}
|
||||
activated = false;
|
||||
if (worker)
|
||||
{
|
||||
worker->Close();
|
||||
@@ -591,15 +644,18 @@ void Lv2Effect::Run(uint32_t samples, RealtimeRingBufferWriter *realtimeRingBuff
|
||||
for (size_t i = 0; i < this->outputMixBuffers.size(); ++i)
|
||||
{
|
||||
float *__restrict input;
|
||||
if (i >= this->inputAudioBuffers.size()) {
|
||||
if (i >= this->inputAudioBuffers.size())
|
||||
{
|
||||
if (this->inputAudioBuffers.size() == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
input = this->inputAudioBuffers[0];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
input = this->inputAudioBuffers[i];
|
||||
}
|
||||
}
|
||||
float *__restrict pluginOutput = this->outputMixBuffers[i].data();
|
||||
float *__restrict finalOutput = this->outputAudioBuffers[i];
|
||||
|
||||
|
||||
@@ -199,9 +199,14 @@ namespace pipedal
|
||||
int actualAudioOutputs = 0;
|
||||
std::vector<std::vector<float>> outputMixBuffers;
|
||||
void BypassTo(float value);
|
||||
bool borrowedEffect = false;
|
||||
bool activated = false;
|
||||
|
||||
public:
|
||||
|
||||
bool IsBorrowedEffect() const { return borrowedEffect; }
|
||||
void SetBorrowedEffect(bool value) { borrowedEffect = value; }
|
||||
void UpdateAudioPorts();
|
||||
|
||||
// non RT-thread use only.
|
||||
std::string GetPathPatchProperty(const std::string&propertyUri);
|
||||
// non RT-thread use only.
|
||||
|
||||
@@ -60,18 +60,20 @@ int Lv2Pedalboard::GetControlIndex(uint64_t instanceId, const std::string &symbo
|
||||
std::vector<float *> Lv2Pedalboard::PrepareItems(
|
||||
std::vector<PedalboardItem> &items,
|
||||
std::vector<float *> inputBuffers,
|
||||
Lv2PedalboardErrorList &errorList)
|
||||
Lv2PedalboardErrorList &errorList,
|
||||
ExistingEffectMap *existingEffects)
|
||||
{
|
||||
for (int i = 0; i < items.size(); ++i)
|
||||
{
|
||||
auto &item = items[i];
|
||||
if (!item.isEmpty())
|
||||
{
|
||||
IEffect *pEffect = nullptr;
|
||||
std::shared_ptr<IEffect> pEffect = nullptr;
|
||||
|
||||
if (item.isSplit())
|
||||
{
|
||||
auto pSplit = new SplitEffect(item.instanceId(), pHost->GetSampleRate(), inputBuffers);
|
||||
pEffect = pSplit;
|
||||
pEffect = std::shared_ptr<IEffect>(pSplit);
|
||||
|
||||
int topInputChannels = inputBuffers.size();
|
||||
int bottomInputChannels = inputBuffers.size();
|
||||
@@ -84,8 +86,8 @@ std::vector<float *> Lv2Pedalboard::PrepareItems(
|
||||
|
||||
this->processActions.push_back(preMixAction);
|
||||
|
||||
std::vector<float *> topResult = PrepareItems(item.topChain(), topInputs, errorList);
|
||||
std::vector<float *> bottomResult = PrepareItems(item.bottomChain(), bottomInputs, errorList);
|
||||
std::vector<float *> topResult = PrepareItems(item.topChain(), topInputs, errorList,existingEffects);
|
||||
std::vector<float *> bottomResult = PrepareItems(item.bottomChain(), bottomInputs, errorList,existingEffects);
|
||||
|
||||
this->processActions.push_back(
|
||||
[pSplit](uint32_t frames)
|
||||
@@ -94,7 +96,7 @@ std::vector<float *> Lv2Pedalboard::PrepareItems(
|
||||
// if split is L/R, always output stereo.
|
||||
|
||||
bool forceStereo = (controlValue != nullptr && controlValue->value() == 2);
|
||||
pSplit->SetChainBuffers(topInputs, bottomInputs, topResult, bottomResult,forceStereo);
|
||||
pSplit->SetChainBuffers(topInputs, bottomInputs, topResult, bottomResult, forceStereo);
|
||||
|
||||
for (int i = 0; i < item.controlValues().size(); ++i)
|
||||
{
|
||||
@@ -108,31 +110,40 @@ std::vector<float *> Lv2Pedalboard::PrepareItems(
|
||||
}
|
||||
else
|
||||
{
|
||||
std::shared_ptr<IEffect> pLv2Effect;
|
||||
|
||||
IEffect *pLv2Effect = nullptr;
|
||||
try
|
||||
if (existingEffects && existingEffects->contains(item.instanceId())
|
||||
)
|
||||
{
|
||||
pLv2Effect = this->pHost->CreateEffect(item);
|
||||
pLv2Effect = existingEffects->at(item.instanceId());
|
||||
((Lv2Effect*)pLv2Effect.get())->SetBorrowedEffect(true);
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
else
|
||||
{
|
||||
Lv2Log::warning(SS(e.what()));
|
||||
}
|
||||
try
|
||||
{
|
||||
pLv2Effect = std::shared_ptr<IEffect>(this->pHost->CreateEffect(item));
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
Lv2Log::warning(SS(e.what()));
|
||||
}
|
||||
|
||||
if (pLv2Effect)
|
||||
{
|
||||
|
||||
if (pLv2Effect->HasErrorMessage())
|
||||
if (pLv2Effect && pLv2Effect->HasErrorMessage())
|
||||
{
|
||||
std::string error = pLv2Effect->TakeErrorMessage();
|
||||
Lv2Log::error(error);
|
||||
errorList.push_back({item.instanceId(), error});
|
||||
}
|
||||
}
|
||||
|
||||
if (pLv2Effect)
|
||||
{
|
||||
|
||||
pEffect = pLv2Effect;
|
||||
|
||||
uint64_t instanceId = pEffect->GetInstanceId();
|
||||
pLv2Effect->PrepareNoInputEffect(inputBuffers.size(),pHost->GetMaxAudioBufferSize());
|
||||
pLv2Effect->PrepareNoInputEffect(inputBuffers.size(), pHost->GetMaxAudioBufferSize());
|
||||
|
||||
if (inputBuffers.size() == 1)
|
||||
{
|
||||
@@ -173,35 +184,34 @@ std::vector<float *> Lv2Pedalboard::PrepareItems(
|
||||
// Reset any trigger controls to default state after processing
|
||||
if (pLv2Effect->IsLv2Effect())
|
||||
{
|
||||
Lv2Effect*lv2Effect = (Lv2Effect*)pLv2Effect;
|
||||
Lv2Effect *lv2Effect = (Lv2Effect *)pLv2Effect.get();
|
||||
auto pluginInfo = pHost->GetPluginInfo(item.uri());
|
||||
if (pluginInfo) {
|
||||
for (auto control: pluginInfo->ports())
|
||||
if (pluginInfo)
|
||||
{
|
||||
for (auto control : pluginInfo->ports())
|
||||
{
|
||||
if (control->trigger_property() && control->is_input() && control->is_control_port())
|
||||
{
|
||||
int controlIndex = lv2Effect->GetControlIndex(control->symbol());
|
||||
if (controlIndex >= 0)
|
||||
if (controlIndex >= 0)
|
||||
{
|
||||
float defaultValue = control->default_value();
|
||||
this->processActions.push_back(
|
||||
[pLv2Effect,controlIndex,defaultValue](int32_t frames) {
|
||||
pLv2Effect->SetControl(controlIndex,defaultValue);
|
||||
}
|
||||
);
|
||||
[pLv2Effect, controlIndex, defaultValue](int32_t frames)
|
||||
{
|
||||
pLv2Effect->SetControl(controlIndex, defaultValue);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pEffect)
|
||||
{
|
||||
this->effects.push_back(std::shared_ptr<IEffect>(pEffect)); // for ownership.
|
||||
this->realtimeEffects.push_back(pEffect); // because std::shared_ptr is not threadsafe.
|
||||
this->effects.push_back(pEffect); // for ownership.
|
||||
this->realtimeEffects.push_back(pEffect.get()); // because std::shared_ptr is not threadsafe.
|
||||
|
||||
std::vector<float *> effectOutput;
|
||||
|
||||
@@ -214,7 +224,7 @@ std::vector<float *> Lv2Pedalboard::PrepareItems(
|
||||
effectOutput.push_back(CreateNewAudioBuffer());
|
||||
effectOutput.push_back(CreateNewAudioBuffer());
|
||||
}
|
||||
for (size_t i = 0; i < effectOutput.size(); ++i)
|
||||
for (size_t i = 0; i < effectOutput.size(); ++i)
|
||||
{
|
||||
pEffect->SetAudioOutputBuffer(i, effectOutput[i]);
|
||||
}
|
||||
@@ -225,7 +235,7 @@ std::vector<float *> Lv2Pedalboard::PrepareItems(
|
||||
return inputBuffers;
|
||||
}
|
||||
|
||||
void Lv2Pedalboard::Prepare(IHost *pHost, Pedalboard &pedalboard, Lv2PedalboardErrorList &errorList)
|
||||
void Lv2Pedalboard::Prepare(IHost *pHost, Pedalboard &pedalboard, Lv2PedalboardErrorList &errorList, ExistingEffectMap *existingEffects)
|
||||
{
|
||||
this->pHost = pHost;
|
||||
|
||||
@@ -242,7 +252,7 @@ void Lv2Pedalboard::Prepare(IHost *pHost, Pedalboard &pedalboard, Lv2PedalboardE
|
||||
this->pedalboardInputBuffers.push_back(bufferPool.AllocateBuffer<float>(pHost->GetMaxAudioBufferSize()));
|
||||
}
|
||||
|
||||
auto outputs = PrepareItems(pedalboard.items(), this->pedalboardInputBuffers, errorList);
|
||||
auto outputs = PrepareItems(pedalboard.items(), this->pedalboardInputBuffers, errorList, existingEffects);
|
||||
int nOutputs = pHost->GetNumberOfOutputAudioChannels();
|
||||
if (nOutputs == 1)
|
||||
{
|
||||
@@ -276,7 +286,6 @@ void Lv2Pedalboard::PrepareMidiMap(const PedalboardItem &pedalboardItem)
|
||||
else
|
||||
{
|
||||
pluginInfo = pHost->GetPluginInfo(pedalboardItem.uri());
|
||||
|
||||
}
|
||||
|
||||
int effectIndex = this->GetIndexOfInstanceId(pedalboardItem.instanceId());
|
||||
@@ -315,10 +324,15 @@ void Lv2Pedalboard::PrepareMidiMap(const PedalboardItem &pedalboardItem)
|
||||
mapping.midiBinding = binding;
|
||||
mapping.instanceId = pedalboardItem.instanceId();
|
||||
|
||||
if (pPortInfo->trigger_property())
|
||||
if (pPortInfo->mod_momentaryOffByDefault() || pPortInfo->mod_momentaryOnByDefault())
|
||||
{
|
||||
mapping.mappingType = MidiControlType::MomentarySwitch;
|
||||
}
|
||||
else if (pPortInfo->trigger_property())
|
||||
{
|
||||
mapping.mappingType = MidiControlType::Trigger;
|
||||
} else if (pPortInfo->IsSwitch())
|
||||
}
|
||||
else if (pPortInfo->IsSwitch())
|
||||
{
|
||||
mapping.mappingType = MidiControlType::Toggle;
|
||||
}
|
||||
@@ -326,7 +340,7 @@ void Lv2Pedalboard::PrepareMidiMap(const PedalboardItem &pedalboardItem)
|
||||
{
|
||||
mapping.mappingType = MidiControlType::Select;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
mapping.mappingType = MidiControlType::Dial;
|
||||
}
|
||||
@@ -365,12 +379,25 @@ void Lv2Pedalboard::PrepareMidiMap(const Pedalboard &pedalboard)
|
||||
{
|
||||
auto &item = pedalboard.items()[i];
|
||||
PrepareMidiMap(item);
|
||||
|
||||
}
|
||||
std::sort(this->midiMappings.begin(), this->midiMappings.end(),
|
||||
[](const MidiMapping &left, const MidiMapping &right)
|
||||
{ return left.key < right.key; });
|
||||
[](const MidiMapping &left, const MidiMapping &right)
|
||||
{ return left.key < right.key; });
|
||||
}
|
||||
|
||||
void Lv2Pedalboard::UpdateAudioPorts()
|
||||
{
|
||||
for (int i = 0; i < this->effects.size(); ++i)
|
||||
{
|
||||
IEffect *effect = this->realtimeEffects[i];
|
||||
if (effect->IsLv2Effect())
|
||||
{
|
||||
Lv2Effect *lv2Effect = (Lv2Effect *)effect;
|
||||
lv2Effect->UpdateAudioPorts();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Lv2Pedalboard::Activate()
|
||||
{
|
||||
for (int i = 0; i < this->effects.size(); ++i)
|
||||
@@ -522,19 +549,18 @@ void Lv2Pedalboard::ResetAtomBuffers()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Lv2Pedalboard::GatherPathPatchProperties(IPatchWriterCallback*cbPatchWriter)
|
||||
void Lv2Pedalboard::GatherPathPatchProperties(IPatchWriterCallback *cbPatchWriter)
|
||||
{
|
||||
for (auto& pEffect : this->effects) {
|
||||
for (auto &pEffect : this->effects)
|
||||
{
|
||||
if (pEffect->IsLv2Effect())
|
||||
{
|
||||
Lv2Effect *pLv2Effect = (Lv2Effect*)pEffect.get();
|
||||
Lv2Effect *pLv2Effect = (Lv2Effect *)pEffect.get();
|
||||
pLv2Effect->GatherPathPatchProperties(cbPatchWriter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Lv2Pedalboard::ProcessParameterRequests(RealtimePatchPropertyRequest *pParameterRequests)
|
||||
{
|
||||
while (pParameterRequests != nullptr)
|
||||
@@ -572,7 +598,6 @@ void Lv2Pedalboard::ProcessParameterRequests(RealtimePatchPropertyRequest *pPara
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Lv2Pedalboard::GatherPatchProperties(RealtimePatchPropertyRequest *pParameterRequests)
|
||||
{
|
||||
while (pParameterRequests != nullptr)
|
||||
@@ -630,7 +655,7 @@ void Lv2Pedalboard::OnMidiMessage(size_t size, uint8_t *message,
|
||||
if (size < 3)
|
||||
return;
|
||||
index = message[1];
|
||||
value = message[2] == 0? 0: 127; // zero velocity = note off.
|
||||
value = message[2] == 0 ? 0 : 127; // zero velocity = note off.
|
||||
}
|
||||
else if (cmd == 0xB0) // midi control.
|
||||
{
|
||||
@@ -689,22 +714,25 @@ void Lv2Pedalboard::OnMidiMessage(size_t size, uint8_t *message,
|
||||
case MidiControlType::Trigger:
|
||||
{
|
||||
bool triggered = false;
|
||||
if (mapping.midiBinding.switchControlType() == SwitchControlTypeT::TRIGGER_ON_RISING_EDGE
|
||||
|| mapping.midiBinding.bindingType() == BINDING_TYPE_NOTE
|
||||
)
|
||||
if (mapping.midiBinding.switchControlType() == SwitchControlTypeT::TRIGGER_ON_RISING_EDGE || mapping.midiBinding.bindingType() == BINDING_TYPE_NOTE)
|
||||
{
|
||||
if (mapping.lastValue < range)
|
||||
{
|
||||
if (!mapping.lastValueIncreasing) {
|
||||
if (!mapping.lastValueIncreasing)
|
||||
{
|
||||
triggered = true;
|
||||
}
|
||||
mapping.lastValueIncreasing = true;
|
||||
mapping.lastValue = range;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
mapping.lastValueIncreasing = false;
|
||||
mapping.lastValue = range;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
triggered = true;
|
||||
}
|
||||
if (triggered)
|
||||
@@ -730,12 +758,15 @@ void Lv2Pedalboard::OnMidiMessage(size_t size, uint8_t *message,
|
||||
{
|
||||
if (range > mapping.lastValue)
|
||||
{
|
||||
if (!mapping.lastValueIncreasing) {
|
||||
if (!mapping.lastValueIncreasing)
|
||||
{
|
||||
triggered = true;
|
||||
}
|
||||
mapping.lastValueIncreasing = true;
|
||||
mapping.lastValue = range;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
mapping.lastValueIncreasing = false;
|
||||
mapping.lastValue = range;
|
||||
}
|
||||
@@ -748,30 +779,40 @@ void Lv2Pedalboard::OnMidiMessage(size_t size, uint8_t *message,
|
||||
pEffect->SetControl(mapping.controlIndex, currentValue);
|
||||
pfnCallback(callbackHandle, mapping.instanceId, mapping.pPortInfo->index(), currentValue);
|
||||
}
|
||||
} else if (mapping.midiBinding.switchControlType() == SwitchControlTypeT::TOGGLE_ON_VALUE)
|
||||
}
|
||||
else if (mapping.midiBinding.switchControlType() == SwitchControlTypeT::TOGGLE_ON_VALUE)
|
||||
{
|
||||
triggered = true;
|
||||
mapping.lastValue = range;
|
||||
IEffect *pEffect = this->realtimeEffects[mapping.effectIndex];
|
||||
IEffect *pEffect = this->realtimeEffects[mapping.effectIndex];
|
||||
float currentValue = pEffect->GetControlValue(mapping.controlIndex);
|
||||
if (currentValue != range)
|
||||
{
|
||||
pEffect->SetControl(mapping.controlIndex, range);
|
||||
pfnCallback(callbackHandle, mapping.instanceId, mapping.pPortInfo->index(), range);
|
||||
}
|
||||
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
// any control value toggles.
|
||||
triggered = true;
|
||||
mapping.lastValue = range;
|
||||
IEffect *pEffect = this->realtimeEffects[mapping.effectIndex];
|
||||
IEffect *pEffect = this->realtimeEffects[mapping.effectIndex];
|
||||
float currentValue = pEffect->GetControlValue(mapping.controlIndex);
|
||||
currentValue = currentValue == 0 ? 1: 0;
|
||||
currentValue = currentValue == 0 ? 1 : 0;
|
||||
pEffect->SetControl(mapping.controlIndex, currentValue);
|
||||
pfnCallback(callbackHandle, mapping.instanceId, mapping.pPortInfo->index(), currentValue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MidiControlType::MomentarySwitch:
|
||||
{
|
||||
IEffect *pEffect = this->realtimeEffects[mapping.effectIndex];
|
||||
pEffect->SetControl(mapping.controlIndex, range != 0 ? mapping.pPortInfo->max_value() : mapping.pPortInfo->min_value());
|
||||
// do NOT notify anyone!
|
||||
}
|
||||
break;
|
||||
|
||||
case MidiControlType::Select:
|
||||
case MidiControlType::Dial:
|
||||
{
|
||||
@@ -780,12 +821,12 @@ void Lv2Pedalboard::OnMidiMessage(size_t size, uint8_t *message,
|
||||
float currentValue = mapping.pPortInfo->rangeToValue(range);
|
||||
if (pEffect->GetControlValue(mapping.controlIndex) != currentValue)
|
||||
{
|
||||
this->SetControlValue(mapping.effectIndex, mapping.controlIndex,currentValue);
|
||||
this->SetControlValue(mapping.effectIndex, mapping.controlIndex, currentValue);
|
||||
pfnCallback(callbackHandle, mapping.instanceId, mapping.pPortInfo->index(), currentValue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MidiControlType::None:
|
||||
case MidiControlType::None:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -35,6 +35,8 @@ namespace pipedal
|
||||
class RealtimePatchPropertyRequest;
|
||||
class RealtimeRingBufferWriter;
|
||||
|
||||
using ExistingEffectMap = std::map<uint64_t, std::shared_ptr<IEffect>>;
|
||||
|
||||
struct Lv2PedalboardError
|
||||
{
|
||||
int64_t intanceId;
|
||||
@@ -78,7 +80,8 @@ namespace pipedal
|
||||
Select,
|
||||
Dial,
|
||||
Toggle,
|
||||
Trigger
|
||||
Trigger,
|
||||
MomentarySwitch
|
||||
};
|
||||
class MidiMapping
|
||||
{
|
||||
@@ -101,7 +104,8 @@ namespace pipedal
|
||||
std::vector<float *> PrepareItems(
|
||||
std::vector<PedalboardItem> &items,
|
||||
std::vector<float *> inputBuffers,
|
||||
Lv2PedalboardErrorList &errorList);
|
||||
Lv2PedalboardErrorList &errorList,
|
||||
ExistingEffectMap *existingEffects);
|
||||
|
||||
void PrepareMidiMap(const Pedalboard &pedalboard);
|
||||
void PrepareMidiMap(const PedalboardItem &pedalboardItem);
|
||||
@@ -114,9 +118,12 @@ namespace pipedal
|
||||
Lv2Pedalboard() {}
|
||||
~Lv2Pedalboard() {}
|
||||
|
||||
void Prepare(IHost *pHost, Pedalboard &pedalboard, Lv2PedalboardErrorList &errorList);
|
||||
|
||||
void Prepare(IHost *pHost, Pedalboard &pedalboard, Lv2PedalboardErrorList &errorList, ExistingEffectMap *existingEffects = nullptr);
|
||||
|
||||
std::vector<IEffect *> &GetEffects() { return realtimeEffects; }
|
||||
std::vector<std::shared_ptr<IEffect>> &GetSharedEffectList() { return effects; }
|
||||
|
||||
|
||||
int GetIndexOfInstanceId(uint64_t instanceId)
|
||||
{
|
||||
@@ -140,6 +147,8 @@ namespace pipedal
|
||||
}
|
||||
void Activate();
|
||||
void Deactivate();
|
||||
void UpdateAudioPorts();
|
||||
|
||||
bool Run(float **inputBuffers, float **outputBuffers, uint32_t samples, RealtimeRingBufferWriter *realtimeWriter);
|
||||
|
||||
void ResetAtomBuffers();
|
||||
|
||||
@@ -167,6 +167,10 @@ MimeTypes::MimeTypes()
|
||||
AddMimeType("MPG", "video/mp2p");
|
||||
AddMimeType("MPEG", "video/mp2p");
|
||||
|
||||
// custom.
|
||||
AddMimeType("NAM", "application/x-nam+json");
|
||||
|
||||
|
||||
}
|
||||
|
||||
const MimeTypes&MimeTypes::instance()
|
||||
|
||||
@@ -508,6 +508,7 @@ void PiPedalModel::FireBanksChanged(int64_t clientId)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PiPedalModel::FirePedalboardChanged(int64_t clientId, bool loadAudioThread)
|
||||
{
|
||||
if (loadAudioThread)
|
||||
@@ -593,10 +594,28 @@ void PiPedalModel::UpdateCurrentPedalboard(int64_t clientId, Pedalboard &pedalbo
|
||||
|
||||
UpdateVst3Settings(pedalboard);
|
||||
|
||||
this->pedalboard = pedalboard;
|
||||
UpdateDefaults(&this->pedalboard);
|
||||
|
||||
this->FirePedalboardChanged(clientId);
|
||||
|
||||
Lv2PedalboardErrorList errorMessages;
|
||||
std::shared_ptr<Lv2Pedalboard> lv2Pedalboard{
|
||||
this->pluginHost.UpdateLv2PedalboardStructure(pedalboard, this->lv2Pedalboard.get(), errorMessages)
|
||||
};
|
||||
this->lv2Pedalboard = lv2Pedalboard;
|
||||
|
||||
// apply the error messages to the lv2Pedalboard.
|
||||
// return true if the error messages have changed
|
||||
audioHost->SetPedalboard(lv2Pedalboard);
|
||||
this->pedalboard = pedalboard;
|
||||
previousPedalboard = this->pedalboard;
|
||||
previousPedalboardLoaded = true;
|
||||
this->pedalboard = pedalboard;
|
||||
|
||||
UpdateRealtimeVuSubscriptions();
|
||||
UpdateRealtimeMonitorPortSubscriptions();
|
||||
|
||||
|
||||
|
||||
this->FirePedalboardChanged(clientId,false);
|
||||
this->SetPresetChanged(clientId, true);
|
||||
}
|
||||
}
|
||||
@@ -2159,10 +2178,10 @@ void PiPedalModel::OnNotifyMidiListen(bool isNote, uint8_t noteOrControl)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(mutex);
|
||||
|
||||
for (int i = 0; i < midiEventListeners.size(); ++i)
|
||||
for (int i = 0; i < midiEventListeners.size(); ++i)
|
||||
{
|
||||
auto &listener = midiEventListeners[i];
|
||||
if ((!isNote) || (!listener.listenForControlsOnly))
|
||||
if ((!isNote) == (listener.listenForControls))
|
||||
{
|
||||
auto subscriber = this->GetNotificationSubscriber(listener.clientId);
|
||||
if (subscriber)
|
||||
@@ -2179,10 +2198,10 @@ void PiPedalModel::OnNotifyMidiListen(bool isNote, uint8_t noteOrControl)
|
||||
audioHost->SetListenForMidiEvent(midiEventListeners.size() != 0);
|
||||
}
|
||||
|
||||
void PiPedalModel::ListenForMidiEvent(int64_t clientId, int64_t clientHandle, bool listenForControlsOnly)
|
||||
void PiPedalModel::ListenForMidiEvent(int64_t clientId, int64_t clientHandle, bool listenForControls)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(mutex);
|
||||
MidiListener listener{clientId, clientHandle, listenForControlsOnly};
|
||||
MidiListener listener{clientId, clientHandle, listenForControls};
|
||||
midiEventListeners.push_back(listener);
|
||||
audioHost->SetListenForMidiEvent(true);
|
||||
}
|
||||
@@ -2879,3 +2898,8 @@ void PiPedalModel::OnAlsaDriverTerminatedAbnormally() {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
bool PiPedalModel::IsInUploadsDirectory(const std::string &path)
|
||||
{
|
||||
return storage.IsInUploadsDirectory(path);
|
||||
}
|
||||
@@ -145,7 +145,7 @@ namespace pipedal
|
||||
public:
|
||||
int64_t clientId;
|
||||
int64_t clientHandle;
|
||||
bool listenForControlsOnly;
|
||||
bool listenForControls;
|
||||
};
|
||||
class AtomOutputListener
|
||||
{
|
||||
@@ -436,7 +436,7 @@ namespace pipedal
|
||||
JackServerSettings GetJackServerSettings();
|
||||
void SetJackServerSettings(const JackServerSettings &jackServerSettings);
|
||||
|
||||
void ListenForMidiEvent(int64_t clientId, int64_t clientHandle, bool listenForControlsOnly);
|
||||
void ListenForMidiEvent(int64_t clientId, int64_t clientHandle, bool listenForControls);
|
||||
void CancelListenForMidiEvent(int64_t clientId, int64_t clientHandle);
|
||||
|
||||
void MonitorPatchProperty(int64_t clientId, int64_t clientHandle, uint64_t instanceId, const std::string &propertyUri);
|
||||
@@ -456,6 +456,8 @@ namespace pipedal
|
||||
std::string RenameFilePropertyFile(const std::string &oldRelativePath, const std::string &newRelativePath, const UiFileProperty &uiFileProperty);
|
||||
FilePropertyDirectoryTree::ptr GetFilePropertydirectoryTree(const UiFileProperty &uiFileProperty,const std::string&selectedPath);
|
||||
|
||||
bool IsInUploadsDirectory(const std::string &path);
|
||||
|
||||
std::string UploadUserFile(const std::string &directory, int64_t instanceId, const std::string &patchProperty, const std::string &filename, std::istream &inputStream, size_t streamLength);
|
||||
uint64_t CreateNewPreset();
|
||||
|
||||
|
||||
@@ -181,13 +181,13 @@ JSON_MAP_END()
|
||||
class ListenForMidiEventBody
|
||||
{
|
||||
public:
|
||||
bool listenForControlsOnly_;
|
||||
bool listenForControls_;
|
||||
int64_t handle_;
|
||||
DECLARE_JSON_MAP(ListenForMidiEventBody);
|
||||
};
|
||||
|
||||
JSON_MAP_BEGIN(ListenForMidiEventBody)
|
||||
JSON_MAP_REFERENCE(ListenForMidiEventBody, listenForControlsOnly)
|
||||
JSON_MAP_REFERENCE(ListenForMidiEventBody, listenForControls)
|
||||
JSON_MAP_REFERENCE(ListenForMidiEventBody, handle)
|
||||
JSON_MAP_END()
|
||||
|
||||
@@ -1072,7 +1072,7 @@ public:
|
||||
{
|
||||
ListenForMidiEventBody body;
|
||||
pReader->read(&body);
|
||||
this->model.ListenForMidiEvent(this->clientId, body.handle_, body.listenForControlsOnly_);
|
||||
this->model.ListenForMidiEvent(this->clientId, body.handle_, body.listenForControls_);
|
||||
}
|
||||
else if (message == "cancelListenForMidiEvent")
|
||||
{
|
||||
|
||||
@@ -33,6 +33,10 @@
|
||||
#include "ModFileTypes.hpp"
|
||||
|
||||
|
||||
#define PIPEDAL_PATCH "http://github.com/rerdavies/pipedal/patch"
|
||||
#define PIPEDAL_PATCH_PREFIX PIPEDAL_PATCH "#"
|
||||
#define PIPEDAL_PATCH__readable (PIPEDAL_PATCH_PREFIX "readable")
|
||||
|
||||
#define PIPEDAL_UI "http://github.com/rerdavies/pipedal/ui"
|
||||
#define PIPEDAL_UI_PREFIX PIPEDAL_UI "#"
|
||||
|
||||
|
||||
@@ -172,6 +172,8 @@ void PluginHost::LilvUris::Initialize(LilvWorld *pWorld)
|
||||
#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");
|
||||
mod__preferMomentaryOffByDefault = lilv_new_uri(pWorld, MOD_PREFIX "preferMomentaryOffByDefault");
|
||||
mod__preferMomentaryOnByDefault = lilv_new_uri(pWorld, MOD_PREFIX "preferMomentaryOnByDefault");
|
||||
// ui:portNotification
|
||||
// [
|
||||
// ui:portIndex 3;
|
||||
@@ -191,6 +193,7 @@ void PluginHost::LilvUris::Initialize(LilvWorld *pWorld)
|
||||
|
||||
patch__writable = lilv_new_uri(pWorld, LV2_PATCH__writable);
|
||||
patch__readable = lilv_new_uri(pWorld, LV2_PATCH__readable);
|
||||
pipedal_patch__readable = lilv_new_uri(pWorld, PIPEDAL_PATCH__readable);
|
||||
|
||||
dc__format = lilv_new_uri(pWorld, "http://purl.org/dc/terms/format");
|
||||
|
||||
@@ -1000,7 +1003,8 @@ Lv2PortInfo::Lv2PortInfo(PluginHost *host, const LilvPlugin *plugin, const LilvP
|
||||
}
|
||||
}
|
||||
this->integer_property_ = lilv_port_has_property(plugin, pPort, host->lilvUris->integer_property_uri);
|
||||
|
||||
this->mod_momentaryOffByDefault_ = lilv_port_has_property(plugin, pPort, host->lilvUris->mod__preferMomentaryOffByDefault);
|
||||
this->mod_momentaryOnByDefault_ = lilv_port_has_property(plugin, pPort, host->lilvUris->mod__preferMomentaryOnByDefault);
|
||||
this->enumeration_property_ = lilv_port_has_property(plugin, pPort, host->lilvUris->enumeration_property_uri);
|
||||
|
||||
this->toggled_property_ = lilv_port_has_property(plugin, pPort, host->lilvUris->core__toggled);
|
||||
@@ -1238,6 +1242,32 @@ std::shared_ptr<Lv2PluginInfo> PluginHost::GetPluginInfo(const std::string &uri)
|
||||
return ff->second;
|
||||
}
|
||||
|
||||
Lv2Pedalboard *PluginHost::UpdateLv2PedalboardStructure(Pedalboard &pedalboard,Lv2Pedalboard *existingPedalboard,Lv2PedalboardErrorList &errorList)
|
||||
{
|
||||
ExistingEffectMap existingEffects;
|
||||
|
||||
if (existingPedalboard)
|
||||
{
|
||||
for (auto &effect : existingPedalboard->GetSharedEffectList())
|
||||
{
|
||||
if (effect->IsLv2Effect()) {
|
||||
existingEffects[effect->GetInstanceId()] = effect;
|
||||
}
|
||||
}
|
||||
}
|
||||
Lv2Pedalboard *pPedalboard = new Lv2Pedalboard();
|
||||
try
|
||||
{
|
||||
pPedalboard->Prepare(this, pedalboard, errorList,&existingEffects);
|
||||
return pPedalboard;
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
delete pPedalboard;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
Lv2Pedalboard *PluginHost::CreateLv2Pedalboard(Pedalboard &pedalboard, Lv2PedalboardErrorList &errorMessages)
|
||||
{
|
||||
Lv2Pedalboard *pPedalboard = new Lv2Pedalboard();
|
||||
@@ -1697,6 +1727,8 @@ json_map::storage_type<Lv2PortInfo> Lv2PortInfo::jmap{
|
||||
MAP_REF(Lv2PortInfo, integer_property),
|
||||
MAP_REF(Lv2PortInfo, enumeration_property),
|
||||
MAP_REF(Lv2PortInfo, toggled_property),
|
||||
MAP_REF(Lv2PortInfo, mod_momentaryOffByDefault),
|
||||
MAP_REF(Lv2PortInfo, mod_momentaryOnByDefault),
|
||||
MAP_REF(Lv2PortInfo, not_on_gui),
|
||||
MAP_REF(Lv2PortInfo, buffer_type),
|
||||
MAP_REF(Lv2PortInfo, port_group),
|
||||
@@ -1761,6 +1793,9 @@ json_map::storage_type<Lv2PluginUiPort> Lv2PluginUiPort::jmap{{
|
||||
|
||||
MAP_REF(Lv2PluginUiPort, range_steps),
|
||||
MAP_REF(Lv2PluginUiPort, integer_property),
|
||||
|
||||
MAP_REF(Lv2PluginUiPort, mod_momentaryOffByDefault),
|
||||
MAP_REF(Lv2PluginUiPort, mod_momentaryOnByDefault),
|
||||
MAP_REF(Lv2PluginUiPort, enumeration_property),
|
||||
MAP_REF(Lv2PluginUiPort, not_on_gui),
|
||||
MAP_REF(Lv2PluginUiPort, toggled_property),
|
||||
|
||||
@@ -218,6 +218,10 @@ namespace pipedal
|
||||
bool integer_property_ = false;
|
||||
bool enumeration_property_ = false;
|
||||
bool toggled_property_ = false;
|
||||
|
||||
bool mod_momentaryOffByDefault_ = false;
|
||||
bool mod_momentaryOnByDefault_ = false;
|
||||
|
||||
bool not_on_gui_ = false;
|
||||
std::string buffer_type_;
|
||||
std::string port_group_;
|
||||
@@ -288,6 +292,8 @@ namespace pipedal
|
||||
LV2_PROPERTY_GETSET_SCALAR(range_steps);
|
||||
LV2_PROPERTY_GETSET_SCALAR(trigger_property);
|
||||
LV2_PROPERTY_GETSET_SCALAR(integer_property);
|
||||
LV2_PROPERTY_GETSET_SCALAR(mod_momentaryOffByDefault);
|
||||
LV2_PROPERTY_GETSET_SCALAR(mod_momentaryOnByDefault);
|
||||
LV2_PROPERTY_GETSET_SCALAR(enumeration_property);
|
||||
LV2_PROPERTY_GETSET_SCALAR(toggled_property);
|
||||
LV2_PROPERTY_GETSET_SCALAR(not_on_gui);
|
||||
@@ -503,7 +509,12 @@ namespace pipedal
|
||||
: symbol_(pPort->symbol()), index_(pPort->index()),
|
||||
is_input_(pPort->is_input()), name_(pPort->name()), min_value_(pPort->min_value()), max_value_(pPort->max_value()),
|
||||
default_value_(pPort->default_value()), range_steps_(pPort->range_steps()), display_priority_(pPort->display_priority()),
|
||||
is_logarithmic_(pPort->is_logarithmic()), integer_property_(pPort->integer_property()), enumeration_property_(pPort->enumeration_property()),
|
||||
is_logarithmic_(pPort->is_logarithmic()),
|
||||
integer_property_(pPort->integer_property()),
|
||||
mod_momentaryOffByDefault_(pPort->mod_momentaryOffByDefault()),
|
||||
mod_momentaryOnByDefault_(pPort->mod_momentaryOnByDefault()),
|
||||
|
||||
enumeration_property_(pPort->enumeration_property()),
|
||||
toggled_property_(pPort->toggled_property()), not_on_gui_(pPort->not_on_gui()), scale_points_(pPort->scale_points()),
|
||||
trigger_property_(pPort->trigger_property()),
|
||||
pipedal_ledColor_(pPort->pipedal_ledColor()),
|
||||
@@ -544,6 +555,9 @@ namespace pipedal
|
||||
|
||||
int range_steps_ = 0;
|
||||
bool integer_property_ = false;
|
||||
|
||||
bool mod_momentaryOffByDefault_ = false;
|
||||
bool mod_momentaryOnByDefault_ = false;
|
||||
bool enumeration_property_ = false;
|
||||
bool not_on_gui_ = false;
|
||||
bool toggled_property_ = false;
|
||||
@@ -743,10 +757,12 @@ namespace pipedal
|
||||
|
||||
AutoLilvNode patch__writable;
|
||||
AutoLilvNode patch__readable;
|
||||
AutoLilvNode pipedal_patch__readable;
|
||||
|
||||
AutoLilvNode mod__brand;
|
||||
AutoLilvNode mod__label;
|
||||
|
||||
AutoLilvNode mod__preferMomentaryOffByDefault;
|
||||
AutoLilvNode mod__preferMomentaryOnByDefault;
|
||||
AutoLilvNode dc__format;
|
||||
|
||||
AutoLilvNode mod__fileTypes;
|
||||
@@ -885,6 +901,8 @@ namespace pipedal
|
||||
|
||||
virtual Lv2Pedalboard *CreateLv2Pedalboard(Pedalboard &pedalboard,Lv2PedalboardErrorList &errorList);
|
||||
|
||||
virtual Lv2Pedalboard *UpdateLv2PedalboardStructure(Pedalboard &pedalboard,Lv2Pedalboard *existingPedalboard,Lv2PedalboardErrorList &errorList);
|
||||
|
||||
void setSampleRate(double sampleRate)
|
||||
{
|
||||
this->sampleRate = sampleRate;
|
||||
|
||||
@@ -153,7 +153,7 @@ namespace pipedal
|
||||
}
|
||||
}
|
||||
template <class Clock, class Duration>
|
||||
RingBufferStatus readWait_until(size_t size,const std::chrono::time_point<Clock, Duration> &time_point)
|
||||
RingBufferStatus readWait_until(size_t size, const std::chrono::time_point<Clock, Duration> &time_point)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
@@ -161,7 +161,7 @@ namespace pipedal
|
||||
{
|
||||
std::unique_lock lock(mutex);
|
||||
size_t available = readSpace_();
|
||||
if (available >= size)
|
||||
if (available >= size)
|
||||
{
|
||||
return RingBufferStatus::Ready;
|
||||
}
|
||||
@@ -215,12 +215,13 @@ namespace pipedal
|
||||
return (size_t)size;
|
||||
}
|
||||
|
||||
|
||||
size_t readSpace()
|
||||
{
|
||||
std::unique_lock lock(mutex);
|
||||
return readSpace_();
|
||||
}
|
||||
|
||||
|
||||
bool write(size_t bytes, uint8_t *data)
|
||||
{
|
||||
if (MULTI_WRITER)
|
||||
@@ -273,7 +274,7 @@ namespace pipedal
|
||||
if (MULTI_WRITER)
|
||||
{
|
||||
std::lock_guard guard(writeMutex);
|
||||
if (writeSpace() <= sizeof(bytes) + bytes +bytes2)
|
||||
if (writeSpace() <= sizeof(bytes) + bytes + bytes2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -340,6 +341,23 @@ namespace pipedal
|
||||
}
|
||||
}
|
||||
|
||||
size_t read_packet(size_t maxSize, void*data) {
|
||||
size_t packet_size;
|
||||
if (!read(sizeof(packet_size), (uint8_t*)&packet_size))
|
||||
{
|
||||
throw std::runtime_error("RingBuffer::read_packet: failed to read packet size.");
|
||||
}
|
||||
if (packet_size > maxSize)
|
||||
{
|
||||
throw std::runtime_error("RingBuffer::read_packet: packet size too large.");
|
||||
}
|
||||
if (!read(packet_size, (uint8_t*)data))
|
||||
{
|
||||
throw std::runtime_error("RingBuffer::read_packet: failed to read packet data.");
|
||||
}
|
||||
return packet_size;
|
||||
}
|
||||
|
||||
bool read(size_t bytes, uint8_t *data)
|
||||
{
|
||||
if (readSpace() < bytes)
|
||||
@@ -366,18 +384,20 @@ namespace pipedal
|
||||
|
||||
delete[] buffer;
|
||||
}
|
||||
bool isReadReady() {
|
||||
bool isReadReady()
|
||||
{
|
||||
std::lock_guard lock(mutex);
|
||||
if (isReadReady_()) return true;
|
||||
if (isReadReady_())
|
||||
return true;
|
||||
return !this->is_open;
|
||||
}
|
||||
bool isReadReady(size_t size) {
|
||||
bool isReadReady(size_t size)
|
||||
{
|
||||
size_t available = readSpace();
|
||||
return available >= size;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
size_t readSpace_()
|
||||
{
|
||||
int64_t size = writePosition - readPosition;
|
||||
@@ -389,7 +409,7 @@ namespace pipedal
|
||||
uint32_t peekSize()
|
||||
{
|
||||
volatile uint32_t result;
|
||||
uint8_t *p = (uint8_t*)&result;
|
||||
uint8_t *p = (uint8_t *)&result;
|
||||
size_t ix = this->readPosition;
|
||||
for (size_t i = 0; i < sizeof(result); ++i)
|
||||
{
|
||||
@@ -400,14 +420,12 @@ namespace pipedal
|
||||
bool isReadReady_()
|
||||
{
|
||||
size_t available = readSpace_();
|
||||
if (available < sizeof(uint32_t)) return false;
|
||||
if (available < sizeof(uint32_t))
|
||||
return false;
|
||||
// peak to get the size!
|
||||
uint32_t packetSize = peekSize();
|
||||
return packetSize+sizeof(uint32_t) <= available;
|
||||
return packetSize + sizeof(uint32_t) <= available;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
|
||||
@@ -327,6 +327,7 @@ namespace pipedal
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void write(RingBufferCommand command, const T &value, size_t dataLength, uint8_t *variableData)
|
||||
{
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "PresetBundle.hpp"
|
||||
#include "json.hpp"
|
||||
#include "HotspotManager.hpp"
|
||||
#include "MimeTypes.hpp"
|
||||
|
||||
#define OLD_PRESET_EXTENSION ".piPreset"
|
||||
#define PRESET_EXTENSION ".piPreset"
|
||||
@@ -51,6 +52,22 @@ using namespace pipedal;
|
||||
using namespace boost::system;
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
|
||||
|
||||
static bool HasDotDot(const std::filesystem::path &path) {
|
||||
for (auto &part : path)
|
||||
{
|
||||
if (part == "..") {
|
||||
return true;
|
||||
}
|
||||
if (part == ".")
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
class UserUploadResponse
|
||||
{
|
||||
public:
|
||||
@@ -63,6 +80,13 @@ JSON_MAP_REFERENCE(UserUploadResponse, errorMessage)
|
||||
JSON_MAP_REFERENCE(UserUploadResponse, path)
|
||||
JSON_MAP_END()
|
||||
|
||||
static std::string GetMimeType(const std::filesystem::path&path) {
|
||||
std::string extension = path.extension();
|
||||
const MimeTypes&mimeTypes = MimeTypes::instance();
|
||||
auto result = mimeTypes.MimeTypeFromExtension(extension);
|
||||
return result;
|
||||
|
||||
}
|
||||
static bool IsZipFile(const std::filesystem::path &path)
|
||||
{
|
||||
std::ifstream f(path);
|
||||
@@ -119,6 +143,10 @@ public:
|
||||
return false;
|
||||
}
|
||||
std::string segment = request_uri.segment(1);
|
||||
if (segment == "downloadMediaFile")
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (segment == "uploadPluginPresets")
|
||||
{
|
||||
return true;
|
||||
@@ -154,7 +182,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string GetContentDispositionHeader(const std::string &name, const std::string &extension)
|
||||
static std::string GetContentDispositionHeader(const std::string &name, const std::string &extension)
|
||||
{
|
||||
std::string fileName = name.substr(0, 64) + extension;
|
||||
std::stringstream s;
|
||||
@@ -218,6 +246,26 @@ public:
|
||||
try
|
||||
{
|
||||
std::string segment = request_uri.segment(1);
|
||||
if (segment == "downloadMediaFile") {
|
||||
fs::path path = request_uri.query("path");
|
||||
|
||||
if (!fs::exists(path) || !this->model->IsInUploadsDirectory(path) || HasDotDot(path))
|
||||
{
|
||||
throw PiPedalException("File not found.");
|
||||
}
|
||||
auto mimeType = GetMimeType(path);
|
||||
if (mimeType.empty()) {
|
||||
throw PiPedalException("Can't download files of this type.");
|
||||
}
|
||||
res.set(HttpField::content_type, mimeType);
|
||||
res.set(HttpField::cache_control, "no-cache");
|
||||
std::string disposition = GetContentDispositionHeader(path.stem().string(), path.extension().string());
|
||||
res.set(HttpField::content_disposition, disposition);
|
||||
size_t contentLength = std::filesystem::file_size(path);
|
||||
res.setContentLength(contentLength);
|
||||
return;
|
||||
}
|
||||
|
||||
if (segment == "downloadPluginPresets")
|
||||
{
|
||||
std::string name;
|
||||
@@ -235,6 +283,7 @@ public:
|
||||
res.set(HttpField::content_disposition, GetContentDispositionHeader(name, PLUGIN_PRESETS_EXTENSION));
|
||||
return;
|
||||
}
|
||||
|
||||
if (segment == "downloadPreset")
|
||||
{
|
||||
std::string name;
|
||||
@@ -294,7 +343,29 @@ public:
|
||||
{
|
||||
std::string segment = request_uri.segment(1);
|
||||
|
||||
if (segment == "downloadPluginPresets")
|
||||
if (segment == "downloadMediaFile") {
|
||||
fs::path path = request_uri.query("path");
|
||||
|
||||
bool t = this->model->IsInUploadsDirectory(path);
|
||||
std::cout << (t? "true": "false") << std::endl;
|
||||
(void)t;
|
||||
if (!fs::exists(path) || !this->model->IsInUploadsDirectory(path) || HasDotDot(path))
|
||||
{
|
||||
throw PiPedalException("File not found.");
|
||||
}
|
||||
auto mimeType = GetMimeType(path);
|
||||
if (mimeType.empty()) {
|
||||
throw PiPedalException("Can't download files of this type.");
|
||||
}
|
||||
res.set(HttpField::content_type, mimeType);
|
||||
res.set(HttpField::cache_control, "no-cache");
|
||||
std::string disposition = GetContentDispositionHeader(path.stem().string(), path.extension().string());
|
||||
res.set(HttpField::content_disposition, disposition);
|
||||
size_t contentLength = std::filesystem::file_size(path);
|
||||
res.setContentLength(contentLength);
|
||||
res.setBodyFile(path,false);
|
||||
return;
|
||||
} else if (segment == "downloadPluginPresets")
|
||||
{
|
||||
std::string name;
|
||||
std::string content;
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
npm run dev -- --host 0.0.0.0
|
||||
@@ -29,7 +29,7 @@
|
||||
"@vitejs/plugin-react": "^4.3.4",
|
||||
"eslint": "^9.19.0",
|
||||
"eslint-plugin-react-hooks": "^5.0.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.18",
|
||||
"eslint-plugin-react-refresh": "^0.4.19",
|
||||
"globals": "^15.14.0",
|
||||
"typescript": "~5.7.2",
|
||||
"typescript-eslint": "^8.22.0",
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
"@vitejs/plugin-react": "^4.3.4",
|
||||
"eslint": "^9.19.0",
|
||||
"eslint-plugin-react-hooks": "^5.0.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.18",
|
||||
"eslint-plugin-react-refresh": "^0.4.19",
|
||||
"globals": "^15.14.0",
|
||||
"typescript": "~5.7.2",
|
||||
"typescript-eslint": "^8.22.0",
|
||||
|
||||
@@ -44,7 +44,7 @@ import ListItemIcon from '@mui/material/ListItemIcon';
|
||||
import ListItemText from '@mui/material/ListItemText';
|
||||
import CircularProgress from '@mui/material/CircularProgress';
|
||||
import { type OnChangedHandler } from './ObservableProperty';
|
||||
import ErrorOutlineIcon from '@mui/icons-material/Error';
|
||||
import ErrorOutlineIcon from '@mui/icons-material/ErrorOutline';
|
||||
import ResizeResponsiveComponent from './ResizeResponsiveComponent';
|
||||
import Button from '@mui/material/Button';
|
||||
import PresetSelector from './PresetSelector';
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
|
||||
import React from 'react';
|
||||
import {createStyles} from './WithStyles';
|
||||
import { createStyles } from './WithStyles';
|
||||
|
||||
|
||||
import { Theme } from '@mui/material/styles';
|
||||
@@ -33,6 +33,7 @@ import { PiPedalModel, PiPedalModelFactory, FileEntry, BreadcrumbEntry, FileRequ
|
||||
import { isDarkMode } from './DarkMode';
|
||||
import Button from '@mui/material/Button';
|
||||
import FileUploadIcon from '@mui/icons-material/FileUpload';
|
||||
import FileDownloadIcon from '@mui/icons-material/FileDownload';
|
||||
import AudioFileIcon from '@mui/icons-material/AudioFile';
|
||||
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
|
||||
import FolderIcon from '@mui/icons-material/Folder';
|
||||
@@ -100,6 +101,7 @@ export interface FilePropertyDialogProps extends WithStyles<typeof styles> {
|
||||
instanceId: number,
|
||||
selectedFile: string,
|
||||
onOk: (fileProperty: UiFileProperty, selectedItem: string) => void,
|
||||
onApply: (fileProperty: UiFileProperty, selectedItem: string) => void,
|
||||
onCancel: () => void
|
||||
};
|
||||
export interface FilePropertyDialogState {
|
||||
@@ -108,9 +110,11 @@ export interface FilePropertyDialogState {
|
||||
selectedFileIsDirectory: boolean;
|
||||
selectedFileProtected: boolean;
|
||||
hasSelection: boolean;
|
||||
hasFileSelection: boolean;
|
||||
canDelete: boolean;
|
||||
fileResult: FileRequestResult;
|
||||
navDirectory: string;
|
||||
windowWidth: number;
|
||||
uploadDirectory: string;
|
||||
isProtectedDirectory: boolean;
|
||||
columns: number;
|
||||
@@ -121,6 +125,7 @@ export interface FilePropertyDialogState {
|
||||
newFolderDialogOpen: boolean;
|
||||
renameDialogOpen: boolean;
|
||||
moveDialogOpen: boolean;
|
||||
initialSelection: string;
|
||||
};
|
||||
|
||||
function pathExtension(path: string) {
|
||||
@@ -199,10 +204,12 @@ export default withStyles(
|
||||
fullScreen: this.getFullScreen(),
|
||||
selectedFile: selectedFile,
|
||||
selectedFileProtected: true,
|
||||
windowWidth: this.windowSize.width,
|
||||
selectedFileIsDirectory: false,
|
||||
navDirectory: this.getNavDirectoryFromFile(selectedFile, props.fileProperty),
|
||||
uploadDirectory: "",
|
||||
hasSelection: false,
|
||||
hasFileSelection: false,
|
||||
canDelete: false,
|
||||
columns: 0,
|
||||
columnWidth: 1,
|
||||
@@ -213,7 +220,8 @@ export default withStyles(
|
||||
menuAnchorEl: null,
|
||||
newFolderDialogOpen: false,
|
||||
renameDialogOpen: false,
|
||||
moveDialogOpen: false
|
||||
moveDialogOpen: false,
|
||||
initialSelection: this.props.selectedFile
|
||||
};
|
||||
this.requestScroll = true;
|
||||
}
|
||||
@@ -259,12 +267,13 @@ export default withStyles(
|
||||
// }
|
||||
filesResult.files.splice(0, 0, { pathname: "", displayName: "<none>", isDirectory: false, isProtected: true });
|
||||
|
||||
let fileEntry = this.getFileEntry(filesResult.files, this.state.selectedFile);
|
||||
let fileEntry = this.getFileEntry(filesResult.files, this.state.selectedFile);
|
||||
this.setState({
|
||||
isProtectedDirectory: filesResult.isProtected,
|
||||
fileResult: filesResult,
|
||||
hasSelection: !!fileEntry,
|
||||
selectedFileProtected: fileEntry ? fileEntry.isProtected: true,
|
||||
hasFileSelection: !!fileEntry && (!fileEntry.isDirectory) && (!fileEntry.isProtected),
|
||||
selectedFileProtected: fileEntry ? fileEntry.isProtected : true,
|
||||
navDirectory: navPath,
|
||||
uploadDirectory: filesResult.currentDirectory
|
||||
});
|
||||
@@ -297,7 +306,8 @@ export default withStyles(
|
||||
onWindowSizeChanged(width: number, height: number): void {
|
||||
|
||||
this.setState({
|
||||
fullScreen: this.getFullScreen()
|
||||
fullScreen: this.getFullScreen(),
|
||||
windowWidth: width
|
||||
})
|
||||
if (this.lastDivRef !== null) {
|
||||
this.onMeasureRef(this.lastDivRef);
|
||||
@@ -373,11 +383,16 @@ export default withStyles(
|
||||
|
||||
onSelectValue(fileEntry: FileEntry) {
|
||||
this.requestScroll = true;
|
||||
if (!fileEntry.isDirectory)
|
||||
{
|
||||
this.props.onApply(this.props.fileProperty,fileEntry.pathname);
|
||||
}
|
||||
this.setState({
|
||||
selectedFile: fileEntry.pathname,
|
||||
selectedFileIsDirectory: fileEntry.isDirectory,
|
||||
selectedFileProtected: fileEntry.isProtected,
|
||||
hasSelection: this.isFileInList(this.state.fileResult.files, fileEntry.pathname)
|
||||
hasSelection: this.isFileInList(this.state.fileResult.files, fileEntry.pathname),
|
||||
hasFileSelection: !fileEntry.isDirectory && !fileEntry.isDirectory && !fileEntry.isProtected
|
||||
})
|
||||
}
|
||||
onDoubleClickValue(selectedFile: string) {
|
||||
@@ -392,14 +407,21 @@ export default withStyles(
|
||||
this.setState({ menuAnchorEl: null });
|
||||
}
|
||||
handleDelete() {
|
||||
if (this.state.selectedFileProtected) {
|
||||
return;
|
||||
if (this.state.selectedFileProtected) {
|
||||
return;
|
||||
}
|
||||
this.setState({ openConfirmDeleteDialog: true });
|
||||
}
|
||||
handleDownloadFile() {
|
||||
if (this.state.selectedFileProtected || !this.state.hasFileSelection) {
|
||||
return;
|
||||
}
|
||||
let file = this.state.selectedFile;
|
||||
this.model.downloadAudioFile(file);
|
||||
}
|
||||
handleConfirmDelete() {
|
||||
if (this.state.selectedFileProtected) {
|
||||
return;
|
||||
if (this.state.selectedFileProtected) {
|
||||
return;
|
||||
}
|
||||
this.setState({ openConfirmDeleteDialog: false });
|
||||
if (this.state.hasSelection) {
|
||||
@@ -424,20 +446,21 @@ export default withStyles(
|
||||
this.model.deleteUserFile(this.state.selectedFile)
|
||||
.then(
|
||||
() => {
|
||||
if (newSelection)
|
||||
{
|
||||
this.setState({
|
||||
if (newSelection) {
|
||||
this.setState({
|
||||
selectedFile: newSelection.pathname,
|
||||
selectedFileIsDirectory: newSelection.isDirectory,
|
||||
selectedFileProtected: newSelection.isProtected,
|
||||
hasSelection: true
|
||||
hasSelection: true,
|
||||
hasFileSelection: !newSelection.isDirectory && !newSelection.isProtected
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
selectedFile: "",
|
||||
selectedFileIsDirectory: false,
|
||||
selectedFileProtected: true,
|
||||
hasSelection: false
|
||||
hasSelection: false,
|
||||
hasFileSelection: false
|
||||
});
|
||||
|
||||
}
|
||||
@@ -580,8 +603,7 @@ export default withStyles(
|
||||
}
|
||||
let protectedDirectory = this.state.fileResult.isProtected;
|
||||
let protectedItem = true;
|
||||
if (this.state.hasSelection)
|
||||
{
|
||||
if (this.state.hasSelection) {
|
||||
protectedItem = this.state.selectedFileProtected;
|
||||
}
|
||||
let canMoveOrRename = this.hasSelectedFileOrFolder() && !protectedItem;
|
||||
@@ -719,31 +741,82 @@ export default withStyles(
|
||||
</DialogContent>
|
||||
<Divider />
|
||||
<DialogActions style={{ justifyContent: "stretch" }}>
|
||||
<div style={{ display: "flex", width: "100%", alignItems: "center", flexFlow: "row nowrap" }}>
|
||||
<IconButton style={{ visibility: (this.state.hasSelection ? "visible" : "hidden") }} aria-label="delete" component="label" color="primary"
|
||||
disabled={!this.state.hasSelection || this.state.selectedFile === "" || protectedItem}
|
||||
onClick={() => this.handleDelete()} >
|
||||
<OldDeleteIcon fontSize='small' />
|
||||
</IconButton>
|
||||
{this.state.windowWidth > 500 ? (
|
||||
<div style={{ display: "flex", width: "100%", alignItems: "center", flexFlow: "row nowrap" }}>
|
||||
<IconButton style={{ visibility: (this.state.hasSelection ? "visible" : "hidden") }} aria-label="delete" component="label" color="primary"
|
||||
disabled={!this.state.hasSelection || this.state.selectedFile === "" || protectedItem}
|
||||
onClick={() => this.handleDelete()} >
|
||||
<OldDeleteIcon fontSize='small' />
|
||||
</IconButton>
|
||||
|
||||
<Button style={{ flex: "0 0 auto" }} aria-label="upload" variant="text" startIcon={<FileUploadIcon />}
|
||||
onClick={() => { this.setState({ openUploadFileDialog: true }) }} disabled={protectedDirectory}
|
||||
>
|
||||
<div>Upload</div>
|
||||
</Button>
|
||||
<div style={{ flex: "1 1 auto" }}> </div>
|
||||
<Button style={{ flex: "0 0 auto" }} aria-label="upload" variant="text" startIcon={<FileUploadIcon />}
|
||||
onClick={() => { this.setState({ openUploadFileDialog: true }) }} disabled={protectedDirectory}
|
||||
>
|
||||
<div>Upload</div>
|
||||
</Button>
|
||||
|
||||
<Button variant="dialogSecondary" onClick={() => { this.props.onCancel(); }} aria-label="cancel">
|
||||
Cancel
|
||||
</Button>
|
||||
<Button variant="dialogPrimary" style={{ flex: "0 0 auto" }}
|
||||
onClick={() => { this.openSelectedFile(); }}
|
||||
<Button style={{ flex: "0 0 auto" }} aria-label="upload" variant="text" startIcon={<FileDownloadIcon />}
|
||||
onClick={() => { this.handleDownloadFile(); }} disabled={protectedDirectory || !this.state.hasFileSelection}
|
||||
>
|
||||
<div>Download</div>
|
||||
</Button>
|
||||
|
||||
disabled={(!this.state.hasSelection) && this.state.selectedFile !== ""} aria-label="select"
|
||||
>
|
||||
{okButtonText}
|
||||
</Button>
|
||||
</div>
|
||||
<div style={{ flex: "1 1 auto" }}> </div>
|
||||
|
||||
<Button variant="dialogSecondary" onClick={() => {
|
||||
this.props.onApply(this.props.fileProperty,this.state.initialSelection);
|
||||
this.props.onCancel();
|
||||
}} aria-label="cancel">
|
||||
Cancel
|
||||
</Button>
|
||||
<Button variant="dialogPrimary" style={{ flex: "0 0 auto" }}
|
||||
onClick={() => { this.openSelectedFile(); }}
|
||||
|
||||
disabled={(!this.state.hasSelection) && this.state.selectedFile !== ""} aria-label="select"
|
||||
>
|
||||
{okButtonText}
|
||||
</Button>
|
||||
</div>
|
||||
) : (
|
||||
<div style={{width: "100%"}}>
|
||||
<div style={{ display: "flex", width: "100%", alignItems: "center", flexFlow: "row nowrap" }}>
|
||||
<IconButton style={{ visibility: (this.state.hasSelection ? "visible" : "hidden") }} aria-label="delete" component="label" color="primary"
|
||||
disabled={!this.state.hasSelection || this.state.selectedFile === "" || protectedItem}
|
||||
onClick={() => this.handleDelete()} >
|
||||
<OldDeleteIcon fontSize='small' />
|
||||
</IconButton>
|
||||
|
||||
<Button style={{ flex: "0 0 auto" }} aria-label="upload" variant="text" startIcon={<FileUploadIcon />}
|
||||
onClick={() => { this.setState({ openUploadFileDialog: true }) }} disabled={protectedDirectory}
|
||||
>
|
||||
<div>Upload</div>
|
||||
</Button>
|
||||
|
||||
<Button style={{ flex: "0 0 auto" }} aria-label="upload" variant="text" startIcon={<FileDownloadIcon />}
|
||||
onClick={() => { this.handleDownloadFile(); }} disabled={protectedDirectory || !this.state.hasFileSelection}
|
||||
|
||||
>
|
||||
<div>Download</div>
|
||||
</Button>
|
||||
|
||||
<div style={{ flex: "1 1 auto" }}> </div>
|
||||
</div>
|
||||
<div style={{ display: "flex", width: "100%", alignItems: "center", flexFlow: "row nowrap" }}>
|
||||
<div style={{ flex: "1 1 auto" }}> </div>
|
||||
|
||||
<Button variant="dialogSecondary" onClick={() => { this.props.onCancel(); }} aria-label="cancel">
|
||||
Cancel
|
||||
</Button>
|
||||
<Button variant="dialogPrimary" style={{ flex: "0 0 auto" }}
|
||||
onClick={() => { this.openSelectedFile(); }}
|
||||
|
||||
disabled={(!this.state.hasSelection) && this.state.selectedFile !== ""} aria-label="select"
|
||||
>
|
||||
{okButtonText}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</DialogActions>
|
||||
<UploadFileDialog
|
||||
open={this.state.openUploadFileDialog}
|
||||
@@ -897,10 +970,10 @@ export default withStyles(
|
||||
private onExecuteNewFolder(newName: string) {
|
||||
this.model.createNewSampleDirectory(pathConcat(this.state.navDirectory, newName), this.props.fileProperty)
|
||||
.then((newPath) => {
|
||||
this.setState({
|
||||
this.setState({
|
||||
selectedFile: newPath,
|
||||
selectedFileIsDirectory:
|
||||
true,selectedFileProtected: false
|
||||
selectedFileIsDirectory:
|
||||
true, selectedFileProtected: false
|
||||
});
|
||||
this.requestFiles(this.state.navDirectory);
|
||||
this.requestScroll = true
|
||||
|
||||
@@ -197,7 +197,7 @@ const GxTunerControl =
|
||||
|
||||
let nameIndex = noteNumber -octave* tet;
|
||||
if (nameIndex < 0) nameIndex += tet;
|
||||
name = names[ nameIndex ] + (octave-2);
|
||||
name = names[ nameIndex ] + (octave-1);
|
||||
valid = true;
|
||||
fraction = note-noteNumber;
|
||||
if (fraction >= 0) {
|
||||
|
||||
@@ -451,9 +451,12 @@ export enum ControlType {
|
||||
ABSwitch,
|
||||
Select,
|
||||
Trigger,
|
||||
Momentary,
|
||||
MomentaryOnByDefault,
|
||||
|
||||
Tuner,
|
||||
Vu,
|
||||
Progress,
|
||||
DbVu,
|
||||
OutputText
|
||||
}
|
||||
@@ -494,6 +497,8 @@ deserialize(input: any): UiControl {
|
||||
this.display_priority = input.display_priority;
|
||||
this.range_steps = input.range_steps;
|
||||
this.integer_property = input.integer_property;
|
||||
this.mod_momentaryOffByDefault = input.mod_momentaryOffByDefault;
|
||||
this.mod_momentaryOnByDefault = input.mod_momentaryOnByDefault;
|
||||
this.enumeration_property = input.enumeration_property;
|
||||
this.toggled_property = input.toggled_property;
|
||||
this.trigger_property = input.trigger_property;
|
||||
@@ -522,6 +527,8 @@ deserialize(input: any): UiControl {
|
||||
|
||||
} else if (this.units === Units.db) {
|
||||
this.controlType = ControlType.DbVu;
|
||||
} else if (this.units === Units.pc) {
|
||||
this.controlType = ControlType.Progress;
|
||||
} else if (this.enumeration_property) {
|
||||
this.controlType = ControlType.OutputText;
|
||||
} else if (displayUnitAsText(this.units))
|
||||
@@ -533,7 +540,7 @@ deserialize(input: any): UiControl {
|
||||
}
|
||||
if (this.isValidEnumeration()) {
|
||||
this.controlType = ControlType.Select;
|
||||
if (this.scale_points.length === 2) {
|
||||
if (this.scale_points.length === 2 && this.min_value === 0 && this.max_value === 1) {
|
||||
this.controlType = ControlType.ABSwitch;
|
||||
}
|
||||
} else {
|
||||
@@ -541,9 +548,15 @@ deserialize(input: any): UiControl {
|
||||
this.controlType = ControlType.OnOffSwitch;
|
||||
}
|
||||
}
|
||||
if (this.is_input && this.trigger_property)
|
||||
if (this.is_input)
|
||||
{
|
||||
this.controlType = ControlType.Trigger;
|
||||
if (this.mod_momentaryOnByDefault) {
|
||||
this.controlType = ControlType.MomentaryOnByDefault;
|
||||
} else if (this.mod_momentaryOffByDefault) {
|
||||
this.controlType = ControlType.Momentary;
|
||||
} else if (this.trigger_property) {
|
||||
this.controlType = ControlType.Trigger;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@@ -591,6 +604,8 @@ deserialize(input: any): UiControl {
|
||||
display_priority: number = -1;
|
||||
range_steps: number = 0;
|
||||
integer_property: boolean = false;
|
||||
mod_momentaryOffByDefault: boolean = false;
|
||||
mod_momentaryOnByDefault: boolean = false;
|
||||
enumeration_property: boolean = false;
|
||||
trigger_property: boolean = false;
|
||||
not_on_gui: boolean = false;
|
||||
@@ -640,6 +655,14 @@ deserialize(input: any): UiControl {
|
||||
isTrigger(): boolean {
|
||||
return this.controlType === ControlType.Trigger;
|
||||
}
|
||||
isMomentary(): boolean {
|
||||
return this.controlType === ControlType.Momentary;
|
||||
}
|
||||
isMomentaryOnByDefault(): boolean {
|
||||
return this.controlType === ControlType.MomentaryOnByDefault;
|
||||
}
|
||||
|
||||
|
||||
isOutputText(): boolean {
|
||||
return !this.is_input && this.controlType === ControlType.OutputText;
|
||||
}
|
||||
@@ -662,6 +685,9 @@ deserialize(input: any): UiControl {
|
||||
isDbVu(): boolean {
|
||||
return this.controlType === ControlType.DbVu;
|
||||
}
|
||||
isProgress(): boolean {
|
||||
return this.controlType === ControlType.Progress;
|
||||
}
|
||||
|
||||
valueToRange(value: number): number {
|
||||
if (this.toggled_property) return value === 0 ? 0 : 1;
|
||||
|
||||
@@ -48,10 +48,11 @@ const styles = (theme: Theme) => createStyles({
|
||||
|
||||
enum MidiControlType {
|
||||
None,
|
||||
Select,
|
||||
Dial,
|
||||
Toggle,
|
||||
Trigger,
|
||||
Dial,
|
||||
Select,
|
||||
MomentarySwitch
|
||||
}
|
||||
|
||||
interface MidiBindingViewProps extends WithStyles<typeof styles> {
|
||||
@@ -149,7 +150,7 @@ const MidiBindingView =
|
||||
|
||||
for (let i = 0; i < 127; ++i) {
|
||||
result.push(
|
||||
<MenuItem value={i}>{Utility.midiNoteName(i)}</MenuItem>
|
||||
<MenuItem key={"k" + i} value={i}>{Utility.midiNoteName(i)}</MenuItem>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -188,6 +189,12 @@ const MidiBindingView =
|
||||
let port = this.props.uiPlugin.getControl(this.props.midiBinding.symbol);
|
||||
|
||||
if (!port) return MidiControlType.None;
|
||||
if (port.mod_momentaryOffByDefault || port.mod_momentaryOnByDefault) {
|
||||
return MidiControlType.MomentarySwitch;
|
||||
}
|
||||
if (port.trigger_property) {
|
||||
return MidiControlType.Trigger;
|
||||
}
|
||||
if (port.trigger_property) {
|
||||
return MidiControlType.Trigger;
|
||||
}
|
||||
@@ -230,7 +237,9 @@ const MidiBindingView =
|
||||
value={midiBinding.bindingType}
|
||||
>
|
||||
<MenuItem value={0}>None</MenuItem>
|
||||
{(controlType === MidiControlType.Toggle || controlType === MidiControlType.Trigger) && (
|
||||
{(controlType === MidiControlType.Toggle
|
||||
|| controlType === MidiControlType.Trigger
|
||||
|| controlType === MidiControlType.MomentarySwitch) && (
|
||||
<MenuItem value={1}>Note</MenuItem>
|
||||
)}
|
||||
<MenuItem value={2}>Control</MenuItem>
|
||||
|
||||
@@ -24,7 +24,7 @@ import { PiPedalModel, PiPedalModelFactory, ListenHandle } from './PiPedalModel'
|
||||
import Typography from '@mui/material/Typography';
|
||||
import { Theme } from '@mui/material/styles';
|
||||
import WithStyles from './WithStyles';
|
||||
import {createStyles} from './WithStyles';
|
||||
import { createStyles } from './WithStyles';
|
||||
|
||||
import { withStyles } from "tss-react/mui";
|
||||
import AppBar from '@mui/material/AppBar';
|
||||
@@ -34,7 +34,7 @@ import IconButton from '@mui/material/IconButton';
|
||||
import MidiBinding from './MidiBinding';
|
||||
import MidiBindingView from './MidiBindingView';
|
||||
import Snackbar from '@mui/material/Snackbar';
|
||||
import { UiPlugin,makeSplitUiPlugin } from './Lv2Plugin';
|
||||
import { PortGroup, UiPlugin, makeSplitUiPlugin } from './Lv2Plugin';
|
||||
import { css } from '@emotion/react';
|
||||
|
||||
const styles = (theme: Theme) => createStyles({
|
||||
@@ -54,6 +54,11 @@ const styles = (theme: Theme) => createStyles({
|
||||
pluginHead: css({
|
||||
borderTop: "1pt #DDD solid", paddingLeft: 22, paddingRight: 22
|
||||
}),
|
||||
groupHead: css({
|
||||
borderBottom: "1px solid " + theme.palette.divider,
|
||||
marginLeft: 0,
|
||||
marginBottom: 0
|
||||
}),
|
||||
bindingTd: css({
|
||||
verticalAlign: "top",
|
||||
paddingLeft: 12, paddingBottom: 8
|
||||
@@ -65,7 +70,7 @@ const styles = (theme: Theme) => createStyles({
|
||||
}),
|
||||
});
|
||||
|
||||
function not_null<T>(value: T | null) {
|
||||
function not_null<T>(value: T | null) {
|
||||
if (!value) throw Error("Unexpected null value");
|
||||
return value;
|
||||
}
|
||||
@@ -116,8 +121,7 @@ export const MidiBindingDialog =
|
||||
clearTimeout(this.listenTimeoutHandle);
|
||||
this.listenTimeoutHandle = undefined;
|
||||
}
|
||||
if (this.listenHandle)
|
||||
{
|
||||
if (this.listenHandle) {
|
||||
this.model.cancelListenForMidiEvent(this.listenHandle)
|
||||
this.listenHandle = undefined;
|
||||
}
|
||||
@@ -126,10 +130,9 @@ export const MidiBindingDialog =
|
||||
|
||||
}
|
||||
|
||||
handleListenSucceeded(instanceId: number, symbol: string, isNote: boolean, noteOrControl: number)
|
||||
{
|
||||
handleListenSucceeded(instanceId: number, symbol: string, isNote: boolean, noteOrControl: number) {
|
||||
this.cancelListenForControl();
|
||||
|
||||
|
||||
let pedalboard = this.model.pedalboard.get();
|
||||
let item = pedalboard.getItem(instanceId);
|
||||
if (!item) return;
|
||||
@@ -144,7 +147,7 @@ export const MidiBindingDialog =
|
||||
newBinding.control = noteOrControl;
|
||||
}
|
||||
|
||||
this.model.setMidiBinding(instanceId,newBinding);
|
||||
this.model.setMidiBinding(instanceId, newBinding);
|
||||
}
|
||||
|
||||
|
||||
@@ -157,9 +160,9 @@ export const MidiBindingDialog =
|
||||
|
||||
this.listenHandle = this.model.listenForMidiEvent(listenForControl,
|
||||
(isNote: boolean, noteOrControl: number) => {
|
||||
this.handleListenSucceeded(instanceId,symbol,isNote, noteOrControl);
|
||||
this.handleListenSucceeded(instanceId, symbol, isNote, noteOrControl);
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -190,6 +193,7 @@ export const MidiBindingDialog =
|
||||
|
||||
let pedalboard = this.model.pedalboard.get();
|
||||
let iter = pedalboard.itemsGenerator();
|
||||
let keyIx = 1;
|
||||
while (true) {
|
||||
let v = iter.next();
|
||||
if (v.done) break;
|
||||
@@ -197,45 +201,43 @@ export const MidiBindingDialog =
|
||||
|
||||
|
||||
let isSplit = item.uri === "uri://two-play/pipedal/pedalboard#Split";
|
||||
let plugin : UiPlugin | null = this.model.getUiPlugin(item.uri);
|
||||
if (plugin === null && isSplit)
|
||||
{
|
||||
let plugin: UiPlugin | null = this.model.getUiPlugin(item.uri);
|
||||
if (plugin === null && isSplit) {
|
||||
plugin = makeSplitUiPlugin();
|
||||
let splitType = item.getControlValue("splitType");
|
||||
not_null(plugin.getControl("splitType")).not_on_gui = true;
|
||||
switch (splitType)
|
||||
{
|
||||
case 0: // A/B
|
||||
not_null(plugin.getControl("select")).not_on_gui = false;
|
||||
not_null(plugin.getControl("mix")).not_on_gui = true;
|
||||
not_null(plugin.getControl("volL")).not_on_gui = true;
|
||||
not_null(plugin.getControl("panL")).not_on_gui = true;
|
||||
not_null(plugin.getControl("volR")).not_on_gui = true;
|
||||
not_null(plugin.getControl("panR")).not_on_gui = true;
|
||||
break;
|
||||
case 1: //mixer
|
||||
not_null(plugin.getControl("select")).not_on_gui = true;
|
||||
not_null(plugin.getControl("mix")).not_on_gui = false;
|
||||
not_null(plugin.getControl("volL")).not_on_gui = true;
|
||||
not_null(plugin.getControl("panL")).not_on_gui = true;
|
||||
not_null(plugin.getControl("volR")).not_on_gui = true;
|
||||
not_null(plugin.getControl("panR")).not_on_gui = true;
|
||||
break;
|
||||
case 2: // L/R
|
||||
not_null(plugin.getControl("select")).not_on_gui = true;
|
||||
not_null(plugin.getControl("mix")).not_on_gui = true;
|
||||
not_null(plugin.getControl("volL")).not_on_gui = false;
|
||||
not_null(plugin.getControl("panL")).not_on_gui = false;
|
||||
not_null(plugin.getControl("volR")).not_on_gui = false;
|
||||
not_null(plugin.getControl("panR")).not_on_gui = false;
|
||||
break;
|
||||
switch (splitType) {
|
||||
case 0: // A/B
|
||||
not_null(plugin.getControl("select")).not_on_gui = false;
|
||||
not_null(plugin.getControl("mix")).not_on_gui = true;
|
||||
not_null(plugin.getControl("volL")).not_on_gui = true;
|
||||
not_null(plugin.getControl("panL")).not_on_gui = true;
|
||||
not_null(plugin.getControl("volR")).not_on_gui = true;
|
||||
not_null(plugin.getControl("panR")).not_on_gui = true;
|
||||
break;
|
||||
case 1: //mixer
|
||||
not_null(plugin.getControl("select")).not_on_gui = true;
|
||||
not_null(plugin.getControl("mix")).not_on_gui = false;
|
||||
not_null(plugin.getControl("volL")).not_on_gui = true;
|
||||
not_null(plugin.getControl("panL")).not_on_gui = true;
|
||||
not_null(plugin.getControl("volR")).not_on_gui = true;
|
||||
not_null(plugin.getControl("panR")).not_on_gui = true;
|
||||
break;
|
||||
case 2: // L/R
|
||||
not_null(plugin.getControl("select")).not_on_gui = true;
|
||||
not_null(plugin.getControl("mix")).not_on_gui = true;
|
||||
not_null(plugin.getControl("volL")).not_on_gui = false;
|
||||
not_null(plugin.getControl("panL")).not_on_gui = false;
|
||||
not_null(plugin.getControl("volR")).not_on_gui = false;
|
||||
not_null(plugin.getControl("panR")).not_on_gui = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// xxx
|
||||
}
|
||||
if (plugin) {
|
||||
result.push(
|
||||
<tr>
|
||||
<tr key={"k" + keyIx++}>
|
||||
<td colSpan={2} className={classes.pluginHead}>
|
||||
<Typography variant="caption" color="textSecondary" noWrap>
|
||||
{plugin.name}
|
||||
@@ -243,10 +245,9 @@ export const MidiBindingDialog =
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
if (!isSplit)
|
||||
{
|
||||
if (!isSplit) {
|
||||
result.push(
|
||||
<tr>
|
||||
<tr key={"k" + keyIx++}>
|
||||
<td className={classes.nameTd}>
|
||||
<Typography noWrap style={{ verticalAlign: "center", height: 48 }}>
|
||||
Bypass
|
||||
@@ -256,8 +257,7 @@ export const MidiBindingDialog =
|
||||
<MidiBindingView instanceId={item.instanceId} midiBinding={item.getMidiBinding("__bypass")}
|
||||
uiPlugin={plugin}
|
||||
onListen={(instanceId: number, symbol: string, listenForControl: boolean) => {
|
||||
if (instanceId === -2)
|
||||
{
|
||||
if (instanceId === -2) {
|
||||
this.cancelListenForControl();
|
||||
} else {
|
||||
this.handleListenForControl(instanceId, symbol, listenForControl);
|
||||
@@ -271,21 +271,35 @@ export const MidiBindingDialog =
|
||||
);
|
||||
}
|
||||
|
||||
let lastPortGroup: PortGroup | null = null;
|
||||
for (let i = 0; i < plugin.controls.length; ++i) {
|
||||
let control = plugin.controls[i];
|
||||
if (control.isHidden())
|
||||
{
|
||||
if (!control.is_input) {
|
||||
continue;
|
||||
}
|
||||
if (!control.is_input)
|
||||
{
|
||||
continue;
|
||||
let portGroup = plugin.getPortGroupBySymbol(control.port_group);
|
||||
if (portGroup != lastPortGroup) {
|
||||
lastPortGroup = portGroup;
|
||||
if (portGroup != null) {
|
||||
result.push(
|
||||
<tr key={"k" + keyIx++}>
|
||||
<td colSpan={2} className={classes.nameTd} >
|
||||
<div className={classes.groupHead}>
|
||||
<Typography variant="caption" color="textSecondary" noWrap>
|
||||
{portGroup?.name}
|
||||
</Typography>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let symbol = control.symbol;
|
||||
result.push(
|
||||
<tr>
|
||||
<tr key={"k" + keyIx++}>
|
||||
<td className={classes.nameTd}>
|
||||
<Typography noWrap style={{ verticalAlign: "middle", maxWidth: 120 }} >
|
||||
<Typography noWrap style={{ verticalAlign: "middle", maxWidth: 120, marginLeft: portGroup ? 24:0 }} >
|
||||
{control.name}
|
||||
</Typography>
|
||||
</td>
|
||||
@@ -319,66 +333,66 @@ export const MidiBindingDialog =
|
||||
|
||||
render() {
|
||||
let props = this.props;
|
||||
let { open} = props;
|
||||
let { open } = props;
|
||||
const classes = withStyles.getClasses(props);
|
||||
if (!open) {
|
||||
return (<div />);
|
||||
}
|
||||
|
||||
return (
|
||||
<DialogEx tag="midiBindings" open={open} fullWidth onClose={this.handleClose} aria-labelledby="Rename-dialog-title"
|
||||
fullScreen={true}
|
||||
style={{userSelect: "none"}}
|
||||
onEnterKey={()=>{}}
|
||||
<DialogEx tag="midiBindings" open={open} fullWidth onClose={this.handleClose} aria-labelledby="Rename-dialog-title"
|
||||
fullScreen={true}
|
||||
style={{ userSelect: "none" }}
|
||||
onEnterKey={() => { }}
|
||||
|
||||
>
|
||||
<div style={{ display: "flex", flexDirection: "column", flexWrap: "nowrap", width: "100%", height: "100%", overflow: "hidden" }}>
|
||||
<div style={{ flex: "0 0 auto" }}>
|
||||
<AppBar className={classes.dialogAppBar} >
|
||||
<Toolbar>
|
||||
<IconButton
|
||||
edge="start"
|
||||
color="inherit"
|
||||
onClick={this.handleClose}
|
||||
aria-label="back"
|
||||
size="large">
|
||||
<ArrowBackIcon />
|
||||
</IconButton>
|
||||
<Typography noWrap variant="h6" className={classes.dialogTitle}>
|
||||
Preset MIDI Bindings
|
||||
</Typography>
|
||||
</Toolbar>
|
||||
</AppBar>
|
||||
</div>
|
||||
<div style={{ overflow: "auto", flex: "1 1 auto", width: "100%" }}>
|
||||
<table className={classes.pluginTable} >
|
||||
<colgroup>
|
||||
<col style={{ width: "auto" }} />
|
||||
<col style={{ width: "100%" }} />
|
||||
</colgroup>
|
||||
|
||||
<tbody>
|
||||
{this.generateTable()}
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div style={{ display: "flex", flexDirection: "column", flexWrap: "nowrap", width: "100%", height: "100%", overflow: "hidden" }}>
|
||||
<div style={{ flex: "0 0 auto" }}>
|
||||
<AppBar className={classes.dialogAppBar} >
|
||||
<Toolbar>
|
||||
<IconButton
|
||||
edge="start"
|
||||
color="inherit"
|
||||
onClick={this.handleClose}
|
||||
aria-label="back"
|
||||
size="large">
|
||||
<ArrowBackIcon />
|
||||
</IconButton>
|
||||
<Typography noWrap variant="h6" className={classes.dialogTitle}>
|
||||
Preset MIDI Bindings
|
||||
</Typography>
|
||||
</Toolbar>
|
||||
</AppBar>
|
||||
</div>
|
||||
<Snackbar
|
||||
anchorOrigin={{
|
||||
vertical: 'bottom',
|
||||
horizontal: 'left',
|
||||
}}
|
||||
open={this.state.listenSnackbarOpen}
|
||||
autoHideDuration={1500}
|
||||
onClose={() => this.setState({ listenSnackbarOpen: false })}
|
||||
message="Listening for MIDI input"
|
||||
/>
|
||||
<div style={{ overflow: "auto", flex: "1 1 auto", width: "100%" }}>
|
||||
<table className={classes.pluginTable} >
|
||||
<colgroup>
|
||||
<col style={{ width: "auto" }} />
|
||||
<col style={{ width: "100%" }} />
|
||||
</colgroup>
|
||||
|
||||
<tbody>
|
||||
{this.generateTable()}
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<Snackbar
|
||||
anchorOrigin={{
|
||||
vertical: 'bottom',
|
||||
horizontal: 'left',
|
||||
}}
|
||||
open={this.state.listenSnackbarOpen}
|
||||
autoHideDuration={1500}
|
||||
onClose={() => this.setState({ listenSnackbarOpen: false })}
|
||||
message="Listening for MIDI input"
|
||||
/>
|
||||
</DialogEx >
|
||||
);
|
||||
}
|
||||
},
|
||||
styles);
|
||||
styles);
|
||||
|
||||
|
||||
export default MidiBindingDialog;
|
||||
@@ -2297,12 +2297,12 @@ export class PiPedalModel //implements PiPedalModel
|
||||
private monitorPatchPropertyListeners: PatchPropertyListenerItem[] = [];
|
||||
|
||||
nextListenHandle = 1;
|
||||
listenForMidiEvent(listenForControlsOnly: boolean, onComplete: (isNote: boolean, noteOrControl: number) => void): ListenHandle {
|
||||
listenForMidiEvent(listenForControl: boolean, onComplete: (isNote: boolean, noteOrControl: number) => void): ListenHandle {
|
||||
let handle = this.nextListenHandle++;
|
||||
|
||||
this.midiListeners.push(new MidiEventListener(handle, onComplete));
|
||||
|
||||
this.webSocket?.send("listenForMidiEvent", { listenForControlsOnly: listenForControlsOnly, handle: handle });
|
||||
this.webSocket?.send("listenForMidiEvent", { listenForControls: listenForControl, handle: handle });
|
||||
return {
|
||||
_handle: handle
|
||||
};
|
||||
@@ -2388,6 +2388,16 @@ export class PiPedalModel //implements PiPedalModel
|
||||
this.webSocket?.send("cancelListenForMidiEvent", listenHandle._handle);
|
||||
}
|
||||
|
||||
downloadAudioFile(filePath: string) {
|
||||
let downloadUrl = this.varServerUrl + "downloadMediaFile?path=" + encodeURIComponent(filePath);
|
||||
|
||||
// download with no flashing temporary tab.
|
||||
let link = window.document.createElement("A") as HTMLLinkElement;
|
||||
link.href = downloadUrl;
|
||||
link.setAttribute("download", "");
|
||||
link.click();
|
||||
}
|
||||
|
||||
download(targetType: string, instanceId: number | string): void {
|
||||
if (instanceId === -1) return;
|
||||
let url = this.varServerUrl + targetType + "?id=" + instanceId;
|
||||
|
||||
@@ -21,8 +21,8 @@ import React, { TouchEvent, PointerEvent, ReactNode, Component, SyntheticEvent }
|
||||
import { css } from '@emotion/react';
|
||||
import Button from '@mui/material/Button';
|
||||
import { Theme } from '@mui/material/styles';
|
||||
import WithStyles, {withTheme} from './WithStyles';
|
||||
import {createStyles} from './WithStyles';
|
||||
import WithStyles, { withTheme } from './WithStyles';
|
||||
import { createStyles } from './WithStyles';
|
||||
|
||||
import { withStyles } from "tss-react/mui";
|
||||
import { UiControl, ScalePoint } from './Lv2Plugin';
|
||||
@@ -37,11 +37,17 @@ import DialIcon from './svg/fx_dial.svg?react';
|
||||
import { isDarkMode } from './DarkMode';
|
||||
import ControlTooltip from './ControlTooltip';
|
||||
|
||||
import PlayArrowIcon from '@mui/icons-material/PlayArrow';
|
||||
import StopIcon from '@mui/icons-material/Stop';
|
||||
import FiberManualRecordIcon from '@mui/icons-material/FiberManualRecord';
|
||||
|
||||
const MIN_ANGLE = -135;
|
||||
const MAX_ANGLE = 135;
|
||||
const FONT_SIZE = "0.8em";
|
||||
|
||||
|
||||
enum ButtonStyle { None, Trigger, Momentary, MomentaryOnByDefault }
|
||||
|
||||
|
||||
const SELECTED_OPACITY = 0.8;
|
||||
const DEFAULT_OPACITY = 0.6;
|
||||
@@ -53,6 +59,20 @@ const ULTRA_FINE_RANGE_SCALE = RANGE_SCALE * 50; // 12000 pixels to move from 0
|
||||
export const StandardItemSize = { width: 80, height: 140 }
|
||||
|
||||
|
||||
function androidEmoji(text: string) {
|
||||
// android chrome doesn't support these characters properly.
|
||||
if (text === "⏹") {
|
||||
return (<StopIcon fontSize={"medium"} />);
|
||||
}
|
||||
if (text === "⏺") {
|
||||
return (<FiberManualRecordIcon fontSize={"medium"} />)
|
||||
}
|
||||
if (text === "⏵")
|
||||
{
|
||||
return (<PlayArrowIcon fontSize={"medium"}/>);
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
export const pluginControlStyles = (theme: Theme) => createStyles({
|
||||
frame: css({
|
||||
@@ -115,12 +135,12 @@ const PluginControl =
|
||||
withTheme(withStyles(
|
||||
class extends Component<PluginControlProps, PluginControlState> {
|
||||
|
||||
frameRef: React.RefObject<HTMLDivElement|null>;
|
||||
imgRef: React.RefObject<SVGSVGElement|null>;
|
||||
inputRef: React.RefObject<HTMLInputElement|null>;
|
||||
selectRef: React.RefObject<HTMLSelectElement|null>;
|
||||
frameRef: React.RefObject<HTMLDivElement | null>;
|
||||
imgRef: React.RefObject<SVGSVGElement | null>;
|
||||
inputRef: React.RefObject<HTMLInputElement | null>;
|
||||
selectRef: React.RefObject<HTMLSelectElement | null>;
|
||||
|
||||
displayValueRef: React.RefObject<HTMLDivElement|null>;
|
||||
displayValueRef: React.RefObject<HTMLDivElement | null>;
|
||||
model: PiPedalModel;
|
||||
|
||||
|
||||
@@ -498,19 +518,50 @@ const PluginControl =
|
||||
this.isTap = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
handleTriggerMouseDown() {
|
||||
handleButtonMouseLeave(buttonStyle: ButtonStyle) {
|
||||
}
|
||||
handleButtonMouseDown(buttonStyle: ButtonStyle) {
|
||||
let uiControl = this.props.uiControl;
|
||||
if (uiControl) {
|
||||
let value = uiControl.max_value;
|
||||
if (uiControl.max_value === uiControl.default_value) {
|
||||
value = uiControl.min_value;
|
||||
switch (buttonStyle) {
|
||||
case ButtonStyle.Momentary:
|
||||
this.model.setPedalboardControl(this.props.instanceId, uiControl.symbol,uiControl.max_value);
|
||||
break;
|
||||
case ButtonStyle.MomentaryOnByDefault:
|
||||
this.model.setPedalboardControl(this.props.instanceId, uiControl.symbol,uiControl.min_value);
|
||||
break;
|
||||
case ButtonStyle.Trigger:
|
||||
{
|
||||
let value = uiControl.max_value;
|
||||
if (uiControl.max_value === uiControl.default_value) {
|
||||
value = uiControl.min_value;
|
||||
}
|
||||
this.model.sendPedalboardControlTrigger(this.props.instanceId, uiControl.symbol, value);
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
this.model.sendPedalboardControlTrigger(this.props.instanceId, uiControl.symbol, value);
|
||||
}
|
||||
}
|
||||
handleTriggerMouseUp() {
|
||||
// triggers are reset on the audio thread.
|
||||
handleButtonMouseUp(buttonStyle: ButtonStyle) {
|
||||
let uiControl = this.props.uiControl;
|
||||
if (uiControl) {
|
||||
switch (buttonStyle) {
|
||||
case ButtonStyle.Momentary:
|
||||
this.model.setPedalboardControl(this.props.instanceId, uiControl.symbol,uiControl.min_value);
|
||||
break;
|
||||
case ButtonStyle.MomentaryOnByDefault:
|
||||
this.model.setPedalboardControl(this.props.instanceId, uiControl.symbol,uiControl.max_value);
|
||||
break;
|
||||
case ButtonStyle.Trigger:
|
||||
{
|
||||
// trigger values are reset automatically.
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
previewInputValue(value: number, commitValue: boolean) {
|
||||
let range = this.valueToRange(value);
|
||||
@@ -657,8 +708,7 @@ const PluginControl =
|
||||
}
|
||||
range = Math.log(value / minValue) / Math.log(uiControl.max_value / minValue);
|
||||
if (!isFinite(range)) {
|
||||
if (range < 0)
|
||||
{
|
||||
if (range < 0) {
|
||||
range = 0;
|
||||
} else {
|
||||
range = 1.0;
|
||||
@@ -672,8 +722,7 @@ const PluginControl =
|
||||
} else {
|
||||
range = (value - uiControl.min_value) / (uiControl.max_value - uiControl.min_value);
|
||||
if (!isFinite(range)) {
|
||||
if (range < 0)
|
||||
{
|
||||
if (range < 0) {
|
||||
range = 0;
|
||||
} else {
|
||||
range = 1.0;
|
||||
@@ -760,14 +809,28 @@ const PluginControl =
|
||||
let isSelect = control.isSelect();
|
||||
let isAbSwitch = control.isAbToggle();
|
||||
let isOnOffSwitch = control.isOnOffSwitch();
|
||||
let isTrigger = control.isTrigger();
|
||||
|
||||
let isButton = false;
|
||||
let buttonStyle: ButtonStyle = ButtonStyle.None;
|
||||
if (control.isTrigger()) {
|
||||
isButton = true;
|
||||
buttonStyle = ButtonStyle.Trigger;
|
||||
}
|
||||
if (control.isMomentary()) {
|
||||
isButton = true;
|
||||
buttonStyle = ButtonStyle.Momentary;
|
||||
}
|
||||
if (control.isMomentaryOnByDefault()) {
|
||||
isButton = true;
|
||||
buttonStyle = ButtonStyle.MomentaryOnByDefault;
|
||||
}
|
||||
|
||||
if (isAbSwitch) {
|
||||
switchText = control.scale_points[0].value === value ? control.scale_points[0].label : control.scale_points[1].label;
|
||||
}
|
||||
|
||||
let item_width: number | undefined = isSelect ? 160 : 80;
|
||||
if (isTrigger) {
|
||||
if (isButton) {
|
||||
item_width = undefined;
|
||||
}
|
||||
|
||||
@@ -788,24 +851,38 @@ const PluginControl =
|
||||
<Typography variant="caption" display="block" noWrap style={{
|
||||
width: "100%",
|
||||
textAlign: isSelect ? "left" : "center"
|
||||
}}> {isTrigger ? "\u00A0" : control.name}</Typography>
|
||||
}}> {isButton ? "\u00A0" : control.name}</Typography>
|
||||
</ControlTooltip>
|
||||
</div>
|
||||
{/* CONTROL SECTION */}
|
||||
|
||||
<div className={classes.midSection}>
|
||||
|
||||
{isTrigger ?
|
||||
{isButton ?
|
||||
(
|
||||
control.name.length !== 1 ? (
|
||||
<Button variant="contained" color="primary" size="small"
|
||||
onMouseDown={
|
||||
(evt) => { this.handleTriggerMouseDown(); }
|
||||
onMouseDown={
|
||||
(evt) => { this.handleButtonMouseDown(buttonStyle); }
|
||||
}
|
||||
onMouseUp={
|
||||
(evt) => { this.handleButtonMouseUp(buttonStyle); }
|
||||
}
|
||||
onTouchStart={
|
||||
(evt) => { evt.preventDefault();
|
||||
this.handleButtonMouseDown(buttonStyle); }
|
||||
}
|
||||
onTouchEnd={
|
||||
(evt) => {
|
||||
evt.preventDefault();
|
||||
this.handleButtonMouseUp(buttonStyle);
|
||||
}
|
||||
onMouseUp={
|
||||
(evt) => { this.handleTriggerMouseUp(); }
|
||||
}
|
||||
style={{
|
||||
}
|
||||
onMouseLeave={(
|
||||
(evet) => { this.handleButtonMouseLeave(buttonStyle); }
|
||||
)}
|
||||
|
||||
style={{
|
||||
textTransform: "none",
|
||||
background: (isDarkMode() ? "#6750A4" : undefined),
|
||||
marginLeft: 8, marginRight: 8, minWidth: 60,
|
||||
@@ -820,11 +897,25 @@ const PluginControl =
|
||||
) : (
|
||||
<Button variant="contained" color="primary" size="small"
|
||||
onMouseDown={
|
||||
(evt) => { this.handleTriggerMouseDown(); }
|
||||
(evt) => { this.handleButtonMouseDown(buttonStyle); }
|
||||
}
|
||||
onMouseUp={
|
||||
(evt) => { this.handleTriggerMouseUp(); }
|
||||
(evt) => { this.handleButtonMouseUp(buttonStyle); }
|
||||
}
|
||||
onTouchStart={
|
||||
(evt) => { evt.preventDefault();
|
||||
this.handleButtonMouseDown(buttonStyle); }
|
||||
}
|
||||
onTouchEnd={
|
||||
(evt) => {
|
||||
evt.preventDefault();
|
||||
this.handleButtonMouseUp(buttonStyle);
|
||||
}
|
||||
}
|
||||
onMouseLeave={(
|
||||
(evet) => { this.handleButtonMouseLeave(buttonStyle); }
|
||||
)}
|
||||
|
||||
style={{
|
||||
textTransform: "none",
|
||||
background: (isDarkMode() ? "#6750A4" : undefined),
|
||||
@@ -839,7 +930,7 @@ const PluginControl =
|
||||
}}
|
||||
|
||||
>
|
||||
{control.name}
|
||||
{androidEmoji(control.name)}
|
||||
</Button>
|
||||
)
|
||||
)
|
||||
@@ -865,7 +956,7 @@ const PluginControl =
|
||||
|
||||
{/* LABEL/EDIT SECTION*/}
|
||||
<div className={classes.editSection} >
|
||||
{(!(isSelect || isOnOffSwitch || isTrigger)) &&
|
||||
{(!(isSelect || isOnOffSwitch || isButton)) &&
|
||||
(
|
||||
(isAbSwitch) ? (
|
||||
<Typography variant="caption" display="block" textAlign="center" noWrap style={{
|
||||
|
||||
@@ -155,6 +155,7 @@ const styles = (theme: Theme) => createStyles({
|
||||
paddingLeft: 30,
|
||||
paddingRight: 30,
|
||||
paddingTop: 8,
|
||||
|
||||
flex: "1 1 auto",
|
||||
display: "flex", flexDirection: "row", flexWrap: "wrap",
|
||||
justifyContent: "flex-start", alignItems: "flex_start",
|
||||
@@ -170,6 +171,7 @@ const styles = (theme: Theme) => createStyles({
|
||||
// See the spacer div added after all controls in render() with provides the same effect.
|
||||
display: "flex", flexDirection: "row", flexWrap: "nowrap",
|
||||
justifyContent: "flex-start", alignItems: "flex-start",
|
||||
|
||||
overflowX: "hidden",
|
||||
overflowY: "hidden",
|
||||
flex: "0 0 auto",
|
||||
@@ -208,7 +210,7 @@ const styles = (theme: Theme) => createStyles({
|
||||
marginBottom: 12,
|
||||
position: "relative",
|
||||
paddingLeft: 3,
|
||||
paddingRight: 0,
|
||||
paddingRight: 8,
|
||||
paddingTop: 0,
|
||||
paddingBottom: 0,
|
||||
border: "2pt #AAA solid",
|
||||
@@ -216,6 +218,7 @@ const styles = (theme: Theme) => createStyles({
|
||||
elevation: 12,
|
||||
display: "flex",
|
||||
flexDirection: "row", flexWrap: "wrap",
|
||||
|
||||
flex: "0 1 auto",
|
||||
}),
|
||||
portGroupLandscape: css({
|
||||
@@ -226,6 +229,7 @@ const styles = (theme: Theme) => createStyles({
|
||||
position: "relative",
|
||||
paddingLeft: 0,
|
||||
paddingRight: 0,
|
||||
|
||||
paddingTop: 0,
|
||||
paddingBottom: 0,
|
||||
border: "2pt #AAA solid",
|
||||
@@ -253,6 +257,7 @@ const styles = (theme: Theme) => createStyles({
|
||||
display: "flex",
|
||||
flexDirection: "row", flexWrap: "wrap",
|
||||
paddingTop: 6,
|
||||
rowGap: 16,
|
||||
paddingBottom: 8
|
||||
}),
|
||||
portGroupControlsLandscape: css({
|
||||
@@ -260,6 +265,7 @@ const styles = (theme: Theme) => createStyles({
|
||||
flexFlow: "row nowrap",
|
||||
width: "fit-content",
|
||||
paddingTop: 6,
|
||||
rowGap: 16,
|
||||
paddingBottom: 8
|
||||
})
|
||||
|
||||
@@ -779,6 +785,20 @@ const PluginControlView =
|
||||
onCancel={() => {
|
||||
this.setState({ showFileDialog: false });
|
||||
}}
|
||||
onApply={(fileProperty,selectedFile) => {
|
||||
this.model.setPatchProperty(
|
||||
this.props.instanceId,
|
||||
fileProperty.patchProperty,
|
||||
JsonAtom.Path(selectedFile)
|
||||
)
|
||||
.then(() => {
|
||||
|
||||
})
|
||||
.catch((error) => {
|
||||
this.model.showAlert("Unable to complete the operation. " + error);
|
||||
});
|
||||
|
||||
}}
|
||||
onOk={(fileProperty, selectedFile) => {
|
||||
|
||||
this.model.setPatchProperty(
|
||||
@@ -790,7 +810,7 @@ const PluginControlView =
|
||||
|
||||
})
|
||||
.catch((error) => {
|
||||
this.model.showAlert("Unable to complete the operation. Audio is not running." + error);
|
||||
this.model.showAlert("Unable to complete the operation. " + error);
|
||||
});
|
||||
this.setState({ showFileDialog: false });
|
||||
}
|
||||
|
||||
@@ -20,8 +20,7 @@
|
||||
import React from 'react';
|
||||
import { Theme } from '@mui/material/styles';
|
||||
import WithStyles from './WithStyles';
|
||||
import {createStyles} from './WithStyles';
|
||||
|
||||
import { createStyles } from './WithStyles';
|
||||
import { withStyles } from "tss-react/mui";
|
||||
import Button from '@mui/material/Button';
|
||||
import DialogEx from './DialogEx';
|
||||
@@ -34,7 +33,7 @@ import Typography from '@mui/material/Typography';
|
||||
import Grid from '@mui/material/Grid';
|
||||
import { PiPedalModelFactory } from "./PiPedalModel";
|
||||
import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined';
|
||||
import { UiPlugin, UiControl } from './Lv2Plugin';
|
||||
import { UiPlugin, PortGroup } from './Lv2Plugin';
|
||||
import PluginIcon from './PluginIcon';
|
||||
import { Remark } from 'react-remark';
|
||||
import { css } from '@emotion/react';
|
||||
@@ -56,6 +55,9 @@ const styles = (theme: Theme) => {
|
||||
icon: {
|
||||
fill: theme.palette.text.primary,
|
||||
opacity: 0.6
|
||||
},
|
||||
controlHeader: {
|
||||
borderBottom: "1px solid " + theme.palette.divider,
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -88,7 +90,7 @@ const PluginInfoDialogContent = withStyles(
|
||||
(theme: Theme) => ({
|
||||
root: {
|
||||
padding: theme.spacing(2),
|
||||
}
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
@@ -146,7 +148,8 @@ function ioDescription(plugin: UiPlugin): string {
|
||||
|
||||
// );
|
||||
// }
|
||||
function makeControls(controls: UiControl[]) {
|
||||
function makeControls(plugin: UiPlugin, controlHeadeClass: string) {
|
||||
let controls = plugin.controls;
|
||||
let hasComments = false;
|
||||
|
||||
for (let i = 0; i < controls.length; ++i) {
|
||||
@@ -156,14 +159,32 @@ function makeControls(controls: UiControl[]) {
|
||||
}
|
||||
}
|
||||
hasComments = true;
|
||||
let lastPortGroup: PortGroup | null = null;
|
||||
|
||||
if (hasComments) {
|
||||
let trs: React.ReactElement[] = [];
|
||||
for (let i = 0; i < controls.length; ++i) {
|
||||
let control = controls[i];
|
||||
if (!(control.not_on_gui) && control.is_input)
|
||||
if (!(control.not_on_gui) && control.is_input) {
|
||||
let portGroup = plugin.getPortGroupBySymbol(control.port_group);
|
||||
if (portGroup !== lastPortGroup) {
|
||||
if (portGroup !== null)
|
||||
{
|
||||
trs.push((
|
||||
<tr>
|
||||
<td className={controlHeadeClass} style={{ verticalAlign: "top", paddingTop: 8 }} colSpan={2}>
|
||||
<Typography variant="body2" style={{ whiteSpace: "nowrap" }}>
|
||||
{portGroup?.name ?? ""}
|
||||
</Typography>
|
||||
</td>
|
||||
</tr >
|
||||
));
|
||||
}
|
||||
lastPortGroup = portGroup;
|
||||
}
|
||||
trs.push((
|
||||
<tr>
|
||||
<td style={{ verticalAlign: "top" }}>
|
||||
<td style={{ verticalAlign: "top", paddingLeft: portGroup ? 24 : 0 }}>
|
||||
<Typography variant="body2" style={{ whiteSpace: "nowrap" }}>
|
||||
{control.name}
|
||||
</Typography>
|
||||
@@ -175,14 +196,14 @@ function makeControls(controls: UiControl[]) {
|
||||
</td>
|
||||
</tr >
|
||||
));
|
||||
|
||||
}
|
||||
}
|
||||
return (
|
||||
<table style={{ paddingLeft: "24px", verticalAlign: "top" }}>
|
||||
<table style={{ paddingLeft: "24px", verticalAlign: "top" }}><tbody>
|
||||
{
|
||||
trs
|
||||
}
|
||||
</table>
|
||||
</tbody></table>
|
||||
);
|
||||
|
||||
} else {
|
||||
@@ -290,7 +311,7 @@ const PluginInfoDialog = withStyles((props: PluginInfoProps) => {
|
||||
Controls:
|
||||
</Typography>
|
||||
{
|
||||
makeControls(plugin.controls)
|
||||
makeControls(plugin, classes.controlHeader)
|
||||
}
|
||||
{plugin.description.length > 0 && (
|
||||
<div>
|
||||
@@ -338,6 +359,6 @@ const PluginInfoDialog = withStyles((props: PluginInfoProps) => {
|
||||
</div >
|
||||
);
|
||||
},
|
||||
styles);
|
||||
styles);
|
||||
|
||||
export default PluginInfoDialog;
|
||||
|
||||
@@ -130,6 +130,7 @@ const PluginOutputControl =
|
||||
|
||||
private model: PiPedalModel;
|
||||
private vuRef: React.RefObject<HTMLDivElement|null>;
|
||||
private progressRef: React.RefObject<HTMLDivElement|null>;
|
||||
private dbVuRef: React.RefObject<HTMLDivElement|null>;
|
||||
private dbVuTelltaleRef: React.RefObject<HTMLDivElement|null>;
|
||||
private lampRef: React.RefObject<HTMLDivElement|null>;
|
||||
@@ -138,6 +139,7 @@ const PluginOutputControl =
|
||||
constructor(props: PluginOutputControlProps) {
|
||||
super(props);
|
||||
this.vuRef = React.createRef<HTMLDivElement>();
|
||||
this.progressRef = React.createRef<HTMLDivElement>();
|
||||
this.dbVuRef = React.createRef<HTMLDivElement>();
|
||||
this.dbVuTelltaleRef = React.createRef<HTMLDivElement>();
|
||||
this.lampRef = React.createRef<HTMLDivElement>();
|
||||
@@ -182,6 +184,7 @@ const PluginOutputControl =
|
||||
}
|
||||
}
|
||||
|
||||
private PROGRESS_WIDTH = 40-4;
|
||||
private VU_HEIGHT = 60 - 4;
|
||||
private DB_VU_HEIGHT = 60 - 4;
|
||||
private animationHandle: number | undefined = undefined;
|
||||
@@ -257,7 +260,23 @@ const PluginOutputControl =
|
||||
} else if (this.dbVuRef.current) {
|
||||
this.dbVuValue = value;
|
||||
this.requestDbVuAnimation();
|
||||
}
|
||||
} else if (this.progressRef.current) {
|
||||
let control = this.props.uiControl;
|
||||
let range = (value - control.min_value) / (control.max_value - control.min_value);
|
||||
let w = this.PROGRESS_WIDTH * range;
|
||||
|
||||
if (!this.animationHandle) {
|
||||
this.animationHandle = requestAnimationFrame(
|
||||
() => {
|
||||
if (this.progressRef.current) {
|
||||
this.progressRef.current.style.width = w + "px";
|
||||
}
|
||||
this.animationHandle = undefined;
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
else if (this.vuRef.current) {
|
||||
let control = this.props.uiControl;
|
||||
let range = (value - control.min_value) / (control.max_value - control.min_value);
|
||||
@@ -364,6 +383,43 @@ const PluginOutputControl =
|
||||
</div >
|
||||
|
||||
);
|
||||
} else if (control.isProgress()) {
|
||||
item_width = undefined;
|
||||
return (
|
||||
<div className={classes.controlFrame}
|
||||
style={{ width: item_width }}>
|
||||
{/* TITLE SECTION */}
|
||||
<div className={classes.titleSection}
|
||||
style={{ width: "100%" }}>
|
||||
<ControlTooltip uiControl={control}>
|
||||
<Typography variant="caption" display="block" style={{
|
||||
width: "100%",
|
||||
textAlign: "center"
|
||||
}}> {control.name === "" ? "\u00A0" : control.name}</Typography>
|
||||
</ControlTooltip>
|
||||
</div>
|
||||
{/* CONTROL SECTION */}
|
||||
|
||||
<div className={classes.midSection}
|
||||
style={{ flex: "1 1 1", display: "flex", justifyContent: "center", alignItems: "start", flexFlow: "row nowrap" }}>
|
||||
<div style={{ width: this.PROGRESS_WIDTH+2, height: 12, marginLeft: 8, marginRight: 8, background: "#181818", }}>
|
||||
<div style={{ height: 8, width: this.PROGRESS_WIDTH, overflow: "hidden", position: "absolute",
|
||||
margin: "1px 1px 1px 1px", background: "#282828" }}>
|
||||
<div ref={this.progressRef} style={{ height: 10, width: this.PROGRESS_WIDTH, position: "absolute", marginTop: 0, background: "#0C0" }} />
|
||||
<div style={{ height: 10, width: this.PROGRESS_WIDTH, position: "absolute",
|
||||
boxShadow: "inset 0px 2px 4px #000D", background: "transparent"
|
||||
}} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div className={classes.editSectionNoContent}>
|
||||
|
||||
</div>
|
||||
|
||||
</div >
|
||||
|
||||
);
|
||||
|
||||
} else if (control.isDbVu()) {
|
||||
item_width = undefined;
|
||||
@@ -407,7 +463,6 @@ const PluginOutputControl =
|
||||
);
|
||||
}
|
||||
else if (control.isVu()) {
|
||||
// yyx: convert this to a horizontal progress bar.
|
||||
item_width = undefined;
|
||||
return (
|
||||
<div className={classes.controlFrame} style={{ width: item_width}}>
|
||||
|
||||