diff --git a/docs/Configuring.md b/docs/Configuring.md
index 086dfd1..dc5db78 100644
--- a/docs/Configuring.md
+++ b/docs/Configuring.md
@@ -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
128
442/9.2ms
571/11.9ms
699/14.6ms
-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 Auto-Hotspot 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.
--------
diff --git a/docs/ReleaseNotes.md b/docs/ReleaseNotes.md
index bc2cc7c..8002ffa 100644
--- a/docs/ReleaseNotes.md
+++ b/docs/ReleaseNotes.md
@@ -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
diff --git a/lv2/aarch64/ToobAmp.lv2/CabIR.ttl b/lv2/aarch64/ToobAmp.lv2/CabIR.ttl
index d5dd122..208974c 100644
--- a/lv2/aarch64/ToobAmp.lv2/CabIR.ttl
+++ b/lv2/aarch64/ToobAmp.lv2/CabIR.ttl
@@ -93,7 +93,7 @@ cabir:impulseFile3
doap:license ;
doap:maintainer ;
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 ;
diff --git a/lv2/aarch64/ToobAmp.lv2/CabSim.ttl b/lv2/aarch64/ToobAmp.lv2/CabSim.ttl
index ecf7f81..89ad50a 100644
--- a/lv2/aarch64/ToobAmp.lv2/CabSim.ttl
+++ b/lv2/aarch64/ToobAmp.lv2/CabSim.ttl
@@ -22,6 +22,7 @@
@prefix urid: .
@prefix xsd: .
@prefix pipedal_ui: .
+@prefix pipedal_patch: .
@prefix toob: .
@prefix cabsim: .
@@ -49,13 +50,13 @@ toob:frequencyResponseVector
doap:license ;
doap:maintainer ;
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 """
diff --git a/lv2/aarch64/ToobAmp.lv2/ConvolutionReverb.ttl b/lv2/aarch64/ToobAmp.lv2/ConvolutionReverb.ttl
index d347d53..62264fd 100644
--- a/lv2/aarch64/ToobAmp.lv2/ConvolutionReverb.ttl
+++ b/lv2/aarch64/ToobAmp.lv2/ConvolutionReverb.ttl
@@ -53,7 +53,7 @@ toobimpulse:impulseFile
doap:license ;
doap:maintainer ;
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
diff --git a/lv2/aarch64/ToobAmp.lv2/ConvolutionReverbStereo.ttl b/lv2/aarch64/ToobAmp.lv2/ConvolutionReverbStereo.ttl
index 6f6ee24..94a55d7 100644
--- a/lv2/aarch64/ToobAmp.lv2/ConvolutionReverbStereo.ttl
+++ b/lv2/aarch64/ToobAmp.lv2/ConvolutionReverbStereo.ttl
@@ -51,7 +51,7 @@ toobimpulse:impulseFile
doap:license ;
doap:maintainer ;
lv2:minorVersion 0 ;
- lv2:microVersion 57 ;
+ lv2:microVersion 58 ;
rdfs:comment """
diff --git a/lv2/aarch64/ToobAmp.lv2/InputStage.ttl b/lv2/aarch64/ToobAmp.lv2/InputStage.ttl
index e1c1e74..1c7fb2e 100644
--- a/lv2/aarch64/ToobAmp.lv2/InputStage.ttl
+++ b/lv2/aarch64/ToobAmp.lv2/InputStage.ttl
@@ -24,6 +24,7 @@
@prefix pg: .
@prefix pipedal_ui: .
+@prefix pipedal_patch: .
@prefix toob: .
@prefix inputStage: .
@@ -65,16 +66,14 @@ inputStage:filterGroup
doap:license ;
doap:maintainer ;
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
- ;
- patch:readable
+ pipedal_patch:readable
;
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
- ;
.
diff --git a/lv2/aarch64/ToobAmp.lv2/PowerStage2.ttl b/lv2/aarch64/ToobAmp.lv2/PowerStage2.ttl
index f99f60b..d8b5246 100644
--- a/lv2/aarch64/ToobAmp.lv2/PowerStage2.ttl
+++ b/lv2/aarch64/ToobAmp.lv2/PowerStage2.ttl
@@ -25,6 +25,7 @@
@prefix modgui: .
@prefix pstage: .
+@prefix pipedal_patch: .
pstage:stage1
a param:ControlGroup ,
@@ -67,13 +68,13 @@ pstage:stage3
doap:license ;
doap:maintainer ;
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
;
rdfs:comment """
diff --git a/lv2/aarch64/ToobAmp.lv2/SpectrumAnalyzer.ttl b/lv2/aarch64/ToobAmp.lv2/SpectrumAnalyzer.ttl
index cc895f1..81cb244 100644
--- a/lv2/aarch64/ToobAmp.lv2/SpectrumAnalyzer.ttl
+++ b/lv2/aarch64/ToobAmp.lv2/SpectrumAnalyzer.ttl
@@ -13,6 +13,7 @@
@prefix mod: .
@prefix param: .
@prefix work: .
+@prefix pipedal_patch: .
@prefix atom: .
@prefix patch: .
@@ -49,16 +50,14 @@
;
uiext:ui ;
- patch:writable
- ;
- patch:readable
+ pipedal_patch:readable
;
doap:license ;
doap:maintainer ;
lv2:minorVersion 0 ;
- lv2:microVersion 57 ;
+ lv2:microVersion 58 ;
rdfs:comment "TooB spectrum analyzer" ;
mod:brand "TooB";
diff --git a/lv2/aarch64/ToobAmp.lv2/ToneStack.ttl b/lv2/aarch64/ToobAmp.lv2/ToneStack.ttl
index a150f92..956cb3f 100644
--- a/lv2/aarch64/ToobAmp.lv2/ToneStack.ttl
+++ b/lv2/aarch64/ToobAmp.lv2/ToneStack.ttl
@@ -23,6 +23,8 @@
@prefix xsd: .
@prefix pipedal_ui: .
+@prefix pipedal_patch: .
+
@prefix toob: .
@prefix tonestack: .
@@ -55,7 +57,7 @@ tonestack:eqGroup
doap:license ;
doap:maintainer ;
lv2:minorVersion 0 ;
- lv2:microVersion 57 ;
+ lv2:microVersion 58 ;
uiext: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;
diff --git a/lv2/aarch64/ToobAmp.lv2/ToobAmp.so b/lv2/aarch64/ToobAmp.lv2/ToobAmp.so
index e6e2914..a9407d4 100644
Binary files a/lv2/aarch64/ToobAmp.lv2/ToobAmp.so and b/lv2/aarch64/ToobAmp.lv2/ToobAmp.so differ
diff --git a/lv2/aarch64/ToobAmp.lv2/ToobAmpUI.so b/lv2/aarch64/ToobAmp.lv2/ToobAmpUI.so
index 6ccd10e..6eab916 100644
Binary files a/lv2/aarch64/ToobAmp.lv2/ToobAmpUI.so and b/lv2/aarch64/ToobAmp.lv2/ToobAmpUI.so differ
diff --git a/lv2/aarch64/ToobAmp.lv2/ToobChorus.ttl b/lv2/aarch64/ToobAmp.lv2/ToobChorus.ttl
index 7d7b0bf..55a70b7 100644
--- a/lv2/aarch64/ToobAmp.lv2/ToobChorus.ttl
+++ b/lv2/aarch64/ToobAmp.lv2/ToobChorus.ttl
@@ -40,7 +40,7 @@
doap:license ;
doap:maintainer ;
lv2:minorVersion 0 ;
- lv2:microVersion 57 ;
+ lv2:microVersion 58 ;
rdfs:comment """
Emulation of a Boss CE-2 Chorus.
diff --git a/lv2/aarch64/ToobAmp.lv2/ToobDelay.ttl b/lv2/aarch64/ToobAmp.lv2/ToobDelay.ttl
index 1faeb88..55b3647 100644
--- a/lv2/aarch64/ToobAmp.lv2/ToobDelay.ttl
+++ b/lv2/aarch64/ToobAmp.lv2/ToobDelay.ttl
@@ -41,7 +41,7 @@
doap:license ;
doap:maintainer ;
lv2:minorVersion 0 ;
- lv2:microVersion 57 ;
+ lv2:microVersion 58 ;
rdfs:comment """
A straightforward no-frills digital delay.
diff --git a/lv2/aarch64/ToobAmp.lv2/ToobFlanger.ttl b/lv2/aarch64/ToobAmp.lv2/ToobFlanger.ttl
index bce6f3c..a90af50 100644
--- a/lv2/aarch64/ToobAmp.lv2/ToobFlanger.ttl
+++ b/lv2/aarch64/ToobAmp.lv2/ToobFlanger.ttl
@@ -41,7 +41,7 @@
doap:license ;
doap:maintainer ;
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 ;
],
diff --git a/lv2/aarch64/ToobAmp.lv2/ToobFlangerStereo.ttl b/lv2/aarch64/ToobAmp.lv2/ToobFlangerStereo.ttl
index c291c3b..4c9fc37 100644
--- a/lv2/aarch64/ToobAmp.lv2/ToobFlangerStereo.ttl
+++ b/lv2/aarch64/ToobAmp.lv2/ToobFlangerStereo.ttl
@@ -41,7 +41,7 @@
doap:license ;
doap:maintainer ;
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";
diff --git a/lv2/aarch64/ToobAmp.lv2/ToobFreeverb.ttl b/lv2/aarch64/ToobAmp.lv2/ToobFreeverb.ttl
index 77575e2..2469862 100644
--- a/lv2/aarch64/ToobAmp.lv2/ToobFreeverb.ttl
+++ b/lv2/aarch64/ToobAmp.lv2/ToobFreeverb.ttl
@@ -41,7 +41,7 @@
doap:license ;
doap:maintainer ;
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.
diff --git a/lv2/aarch64/ToobAmp.lv2/ToobLooperFour.ttl b/lv2/aarch64/ToobAmp.lv2/ToobLooperFour.ttl
new file mode 100644
index 0000000..42284ce
--- /dev/null
+++ b/lv2/aarch64/ToobAmp.lv2/ToobLooperFour.ttl
@@ -0,0 +1,915 @@
+@prefix doap: .
+@prefix lv2: .
+@prefix rdfs: .
+@prefix rdf: .
+@prefix units: .
+@prefix urid: .
+@prefix atom: .
+@prefix midi: .
+@prefix uiext: .
+@prefix idpy: .
+@prefix foaf: .
+@prefix mod: .
+@prefix param: .
+@prefix work: .
+@prefix pg: .
+@prefix atom: .
+@prefix patch: .
+@prefix state: .
+@prefix urid: .
+@prefix xsd: .
+@prefix ui: .
+@prefix pprop: .
+@prefix pipedal_ui: .
+
+
+@prefix looperPrefix: .
+
+@prefix myprefix: .
+
+
+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" .
+
+
+
+
+ a foaf:Person ;
+ foaf:name "Robin Davies" ;
+ foaf:mbox ;
+ foaf:homepage .
+
+
+
+ a lv2:Plugin ,
+ lv2:UtilityPlugin ;
+ doap:name "TooB 4Looper (stereo)"
+ ;
+ doap:license ;
+ doap:maintainer ;
+ lv2:minorVersion 1 ;
+ lv2:microVersion 58 ;
+
+ ui: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
+ ]
+
+
+ ;
+
+ .
+
+
+
+
+ a ui:X11UI ;
+ lv2:binary ;
+
+ lv2:extensionData ui:resize ;
+ lv2:extensionData ui:idleInterface ;
+ lv2:requiredFeature ui:idleInterface ;
+.
+
+
diff --git a/lv2/aarch64/ToobAmp.lv2/ToobLooperOne.ttl b/lv2/aarch64/ToobAmp.lv2/ToobLooperOne.ttl
new file mode 100644
index 0000000..c1f349a
--- /dev/null
+++ b/lv2/aarch64/ToobAmp.lv2/ToobLooperOne.ttl
@@ -0,0 +1,606 @@
+@prefix doap: .
+@prefix lv2: .
+@prefix rdfs: .
+@prefix rdf: .
+@prefix units: .
+@prefix urid: .
+@prefix atom: .
+@prefix midi: .
+@prefix epp: .
+@prefix idpy: .
+@prefix foaf: .
+@prefix mod: .
+@prefix param: .
+@prefix work: .
+@prefix pg: .
+@prefix atom: .
+@prefix patch: .
+@prefix state: .
+@prefix urid: .
+@prefix xsd: .
+@prefix ui: .
+@prefix uiext: .
+@prefix pprop: .
+@prefix pipedal_ui: .
+
+@prefix myprefix: .
+
+
+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" .
+
+
+
+
+ a foaf:Person ;
+ foaf:name "Robin Davies" ;
+ foaf:mbox ;
+ foaf:homepage .
+
+
+
+ a lv2:Plugin ,
+ lv2:UtilityPlugin ;
+ doap:name "TooB One-Button Looper (stereo)"
+ ;
+
+
+ doap:license ;
+ doap:maintainer ;
+ lv2:minorVersion 1 ;
+ lv2:microVersion 58 ;
+
+ ui: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
+ ]
+
+
+ ;
+
+ .
+
+
+
+
+ a ui:X11UI ;
+ lv2:binary ;
+
+
+ lv2:extensionData ui:resize ;
+ lv2:extensionData ui:idleInterface ;
+ lv2:requiredFeature ui:idleInterface ;
+.
+
diff --git a/lv2/aarch64/ToobAmp.lv2/ToobLooperStereo.ttl b/lv2/aarch64/ToobAmp.lv2/ToobLooperStereo.ttl
new file mode 100644
index 0000000..d290636
--- /dev/null
+++ b/lv2/aarch64/ToobAmp.lv2/ToobLooperStereo.ttl
@@ -0,0 +1,726 @@
+@prefix doap: .
+@prefix lv2: .
+@prefix rdfs: .
+@prefix rdf: .
+@prefix units: .
+@prefix urid: .
+@prefix atom: .
+@prefix midi: .
+@prefix epp: .
+@prefix uiext: .
+@prefix idpy: .
+@prefix foaf: .
+@prefix mod: .
+@prefix param: .
+@prefix work: .
+@prefix pg: .
+@prefix atom: .
+@prefix patch: .
+@prefix state: .
+@prefix urid: .
+@prefix xsd: .
+@prefix ui: .
+@prefix pprop: .
+@prefix pipedal_ui: .
+
+
+@prefix looperPrefix: .
+
+@prefix myprefix: .
+
+
+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" .
+
+
+
+
+ a foaf:Person ;
+ foaf:name "Robin Davies" ;
+ foaf:mbox ;
+ foaf:homepage .
+
+
+
+ a lv2:Plugin ,
+ lv2:UtilityPlugin ;
+ doap:name "TooB 4Looper (stereo)"
+ ;
+ doap:license ;
+ doap:maintainer ;
+ lv2:minorVersion 1 ;
+ lv2:microVersion 57 ;
+
+ ui: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
+ ]
+
+
+ ;
+
+ .
+
+
+
+
+ a ui:X11UI ;
+ lv2:binary <.so>;
+
+ lv2:extensionData ui:resize ;
+ lv2:extensionData ui:idleInterface ;
+ lv2:requiredFeature ui:idleInterface ;
+.
+
+
diff --git a/lv2/aarch64/ToobAmp.lv2/ToobML.ttl b/lv2/aarch64/ToobAmp.lv2/ToobML.ttl
index 25dce24..08a7d62 100644
--- a/lv2/aarch64/ToobAmp.lv2/ToobML.ttl
+++ b/lv2/aarch64/ToobAmp.lv2/ToobML.ttl
@@ -15,6 +15,8 @@
@prefix work: .
@prefix pg: .
@prefix pipedal_ui: .
+@prefix pipedal_patch: .
+
@prefix toob: .
@prefix atom: .
@@ -65,7 +67,7 @@ toobml:sagGroup
doap:license ;
doap:maintainer ;
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
;
diff --git a/lv2/aarch64/ToobAmp.lv2/ToobNeuralAmpModeler.ttl b/lv2/aarch64/ToobAmp.lv2/ToobNeuralAmpModeler.ttl
index 57c7b2b..a015dc9 100644
--- a/lv2/aarch64/ToobAmp.lv2/ToobNeuralAmpModeler.ttl
+++ b/lv2/aarch64/ToobAmp.lv2/ToobNeuralAmpModeler.ttl
@@ -61,7 +61,7 @@ toobNam:eqGroup
doap:license ;
doap:maintainer ;
lv2:minorVersion 0 ;
- lv2:microVersion 57 ;
+ lv2:microVersion 58 ;
rdfs:comment """
A port of Steven Atkinson's Neural Amp Modeler to LV2.
diff --git a/lv2/aarch64/ToobAmp.lv2/ToobRecordMono.ttl b/lv2/aarch64/ToobAmp.lv2/ToobRecordMono.ttl
new file mode 100644
index 0000000..2560393
--- /dev/null
+++ b/lv2/aarch64/ToobAmp.lv2/ToobRecordMono.ttl
@@ -0,0 +1,266 @@
+@prefix doap: .
+@prefix lv2: .
+@prefix rdf: .
+@prefix rdfs: .
+@prefix units: .
+@prefix urid: .
+@prefix atom: .
+@prefix midi: .
+@prefix epp: .
+@prefix uiext: .
+@prefix idpy: .
+@prefix foaf: .
+@prefix mod: .
+@prefix param: .
+@prefix work: .
+@prefix pg: .
+@prefix atom: .
+@prefix patch: .
+@prefix rdfs: .
+@prefix state: .
+@prefix urid: .
+@prefix xsd: .
+@prefix ui: .
+@prefix pprop: .
+@prefix pipedal_ui: .
+
+
+@prefix recordPrefix: .
+
+@prefix myprefix: .
+
+
+
+ a foaf:Person ;
+ foaf:name "Robin Davies" ;
+ foaf:mbox ;
+ foaf:homepage .
+
+recordPrefix:audioFile
+ a lv2:Parameter;
+ rdfs:label "File";
+ mod:fileTypes "audiorecording,audio";
+ rdfs:range atom:Path;
+ lv2:index 6
+ .
+
+
+ a lv2:Plugin ,
+ lv2:UtilityPlugin ;
+ doap:name "TooB Record Input (mono)"
+ ;
+ doap:license ;
+ doap:maintainer ;
+ lv2:minorVersion 1 ;
+ lv2:microVersion 58 ;
+
+ ui: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"
+ ]
+ .
+
+
+ a ui:X11UI ;
+ lv2:binary ;
+ lv2:extensionData ui:resize ;
+ lv2:extensionData ui:idleInterface ;
+ lv2:requiredFeature ui:idleInterface ;
+ ui:portNotification [
+ ui:plugin ;
+ lv2:symbol "controlOut" ;
+ ];
+.
+
+
diff --git a/lv2/aarch64/ToobAmp.lv2/ToobRecordStereo.ttl b/lv2/aarch64/ToobAmp.lv2/ToobRecordStereo.ttl
new file mode 100644
index 0000000..1ef7ef3
--- /dev/null
+++ b/lv2/aarch64/ToobAmp.lv2/ToobRecordStereo.ttl
@@ -0,0 +1,325 @@
+@prefix doap: .
+@prefix lv2: .
+@prefix rdf: .
+@prefix rdfs: .
+@prefix units: .
+@prefix urid: .
+@prefix atom: .
+@prefix midi: .
+@prefix epp: .
+@prefix uiext: .
+@prefix idpy: .
+@prefix foaf: .
+@prefix mod: .
+@prefix param: .
+@prefix work: .
+@prefix pg: .
+@prefix atom: .
+@prefix patch: .
+@prefix rdfs: .
+@prefix state: .
+@prefix urid: .
+@prefix xsd: .
+@prefix ui: .
+@prefix pprop: .
+@prefix pipedal_ui: .
+
+@prefix recordPrefix: .
+@prefix myprefix: .
+
+
+
+ a foaf:Person ;
+ foaf:name "Robin Davies" ;
+ foaf:mbox ;
+ foaf:homepage .
+
+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" .
+
+
+
+
+
+ a lv2:Plugin ,
+ lv2:UtilityPlugin ;
+ doap:name "TooB Record Input (stereo)"
+ ;
+ doap:license ;
+ doap:maintainer ;
+ lv2:minorVersion 1 ;
+ lv2:microVersion 58 ;
+
+ ui: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
+
+ ]
+ .
+
+
+
+ a ui:X11UI ;
+ lv2:binary ;
+ lv2:extensionData ui:resize ;
+ lv2:extensionData ui:idleInterface ;
+ lv2:requiredFeature ui:idleInterface ;
+.
+
+
diff --git a/lv2/aarch64/ToobAmp.lv2/ToobTuner.ttl b/lv2/aarch64/ToobAmp.lv2/ToobTuner.ttl
index 3f47c08..1f8cc18 100644
--- a/lv2/aarch64/ToobAmp.lv2/ToobTuner.ttl
+++ b/lv2/aarch64/ToobAmp.lv2/ToobTuner.ttl
@@ -40,7 +40,7 @@
doap:license ;
doap:maintainer ;
lv2:minorVersion 0 ;
- lv2:microVersion 57 ;
+ lv2:microVersion 58 ;
rdfs:comment """
TooB Tuner is a chromatic guitar tuner.
""" ;
diff --git a/lv2/aarch64/ToobAmp.lv2/manifest.ttl b/lv2/aarch64/ToobAmp.lv2/manifest.ttl
index 63afba4..16a8335 100644
--- a/lv2/aarch64/ToobAmp.lv2/manifest.ttl
+++ b/lv2/aarch64/ToobAmp.lv2/manifest.ttl
@@ -71,6 +71,25 @@
lv2:binary ;
rdfs:seeAlso .
+ a lv2:Plugin ;
+ lv2:binary ;
+ rdfs:seeAlso .
+
+
+ a lv2:Plugin ;
+ lv2:binary ;
+ rdfs:seeAlso .
+
+ a lv2:Plugin ;
+ lv2:binary ;
+ rdfs:seeAlso .
+
+ a lv2:Plugin ;
+ lv2:binary ;
+ rdfs:seeAlso .
+
+
+
tpset:toob-flanger-preset-0
a pset:Preset ;
diff --git a/lv2/aarch64/ToobAmp.lv2/resources/LooperFourLogo.svg b/lv2/aarch64/ToobAmp.lv2/resources/LooperFourLogo.svg
new file mode 100644
index 0000000..f644803
--- /dev/null
+++ b/lv2/aarch64/ToobAmp.lv2/resources/LooperFourLogo.svg
@@ -0,0 +1,108 @@
+
+
+
+