diff --git a/data/presets/AudioFileProcessor/Erazor.xpf b/data/presets/AudioFileProcessor/Erazor.xpf
index c448829fad8..4b55b2d52f3 100644
--- a/data/presets/AudioFileProcessor/Erazor.xpf
+++ b/data/presets/AudioFileProcessor/Erazor.xpf
@@ -16,7 +16,7 @@
-
+
@@ -28,7 +28,7 @@
-
+
@@ -42,7 +42,7 @@
-
+
diff --git a/data/presets/AudioFileProcessor/SString.xpf b/data/presets/AudioFileProcessor/SString.xpf
index 6e5214b0dea..6ade93d1dbf 100644
--- a/data/presets/AudioFileProcessor/SString.xpf
+++ b/data/presets/AudioFileProcessor/SString.xpf
@@ -16,7 +16,7 @@
-
+
@@ -28,11 +28,11 @@
-
+
-
+
@@ -48,7 +48,7 @@
-
+
diff --git a/data/presets/AudioFileProcessor/orion.xpf b/data/presets/AudioFileProcessor/orion.xpf
index 0b11e00cf29..767c0cb24e1 100644
--- a/data/presets/AudioFileProcessor/orion.xpf
+++ b/data/presets/AudioFileProcessor/orion.xpf
@@ -16,7 +16,7 @@
-
+
@@ -32,7 +32,7 @@
-
+
@@ -44,7 +44,7 @@
-
+
diff --git a/data/presets/BitInvader/alien_strings.xpf b/data/presets/BitInvader/alien_strings.xpf
index 938b4be36db..6201150fcf0 100644
--- a/data/presets/BitInvader/alien_strings.xpf
+++ b/data/presets/BitInvader/alien_strings.xpf
@@ -14,7 +14,7 @@
-
+
diff --git a/data/presets/BitInvader/drama.xpf b/data/presets/BitInvader/drama.xpf
index d0ca7ed45b1..f5b4d564d8b 100644
--- a/data/presets/BitInvader/drama.xpf
+++ b/data/presets/BitInvader/drama.xpf
@@ -14,7 +14,7 @@
-
+
diff --git a/data/presets/BitInvader/invaders_must_die.xpf b/data/presets/BitInvader/invaders_must_die.xpf
index bbdbbbbfe7f..6a5dda6b70a 100644
--- a/data/presets/BitInvader/invaders_must_die.xpf
+++ b/data/presets/BitInvader/invaders_must_die.xpf
@@ -16,7 +16,7 @@
-
+
@@ -28,7 +28,7 @@
-
+
diff --git a/data/presets/BitInvader/pluck.xpf b/data/presets/BitInvader/pluck.xpf
index b71b696c1dc..b2c56766c85 100644
--- a/data/presets/BitInvader/pluck.xpf
+++ b/data/presets/BitInvader/pluck.xpf
@@ -14,7 +14,7 @@
-
+
diff --git a/data/presets/Kicker/Clap dry.xpf b/data/presets/Kicker/Clap dry.xpf
index 05bc0a8003a..abc6b6c048a 100644
--- a/data/presets/Kicker/Clap dry.xpf
+++ b/data/presets/Kicker/Clap dry.xpf
@@ -16,7 +16,7 @@
-
+
@@ -34,7 +34,7 @@
-
+
diff --git a/data/presets/Kicker/Clap.xpf b/data/presets/Kicker/Clap.xpf
index 66cac9a9149..b3a23dd8b99 100644
--- a/data/presets/Kicker/Clap.xpf
+++ b/data/presets/Kicker/Clap.xpf
@@ -16,7 +16,7 @@
-
+
@@ -34,7 +34,7 @@
-
+
diff --git a/data/presets/Kicker/SnareMarch.xpf b/data/presets/Kicker/SnareMarch.xpf
index 563f3384356..04a44fc3f76 100644
--- a/data/presets/Kicker/SnareMarch.xpf
+++ b/data/presets/Kicker/SnareMarch.xpf
@@ -16,7 +16,7 @@
-
+
@@ -34,7 +34,7 @@
-
+
@@ -46,7 +46,7 @@
-
+
@@ -71,7 +71,7 @@
-
+
@@ -104,7 +104,7 @@
-
+
@@ -137,7 +137,7 @@
-
+
diff --git a/data/presets/LB302/AcidLead.xpf b/data/presets/LB302/AcidLead.xpf
index af7be34fcf9..ec127a54c8c 100644
--- a/data/presets/LB302/AcidLead.xpf
+++ b/data/presets/LB302/AcidLead.xpf
@@ -16,7 +16,7 @@
-
+
diff --git a/data/presets/LB302/AngryLead.xpf b/data/presets/LB302/AngryLead.xpf
index 1ad94ea1bb9..b3665f7cffe 100644
--- a/data/presets/LB302/AngryLead.xpf
+++ b/data/presets/LB302/AngryLead.xpf
@@ -16,7 +16,7 @@
-
+
diff --git a/data/presets/LB302/STrash.xpf b/data/presets/LB302/STrash.xpf
index c6d3cf48b0f..c8a1ad712a5 100644
--- a/data/presets/LB302/STrash.xpf
+++ b/data/presets/LB302/STrash.xpf
@@ -8,18 +8,18 @@
-
+
-
+
-
+
diff --git a/data/presets/Monstro/Growl.xpf b/data/presets/Monstro/Growl.xpf
index d21804885cf..de115bdaaf5 100644
--- a/data/presets/Monstro/Growl.xpf
+++ b/data/presets/Monstro/Growl.xpf
@@ -16,7 +16,7 @@
-
+
@@ -34,7 +34,7 @@
-
+
@@ -44,11 +44,11 @@
-
+
-
+
@@ -62,7 +62,7 @@
-
+
@@ -74,7 +74,7 @@
-
+
diff --git a/data/presets/Monstro/HorrorLead.xpf b/data/presets/Monstro/HorrorLead.xpf
index fbe2639bc4f..cb2cafbfa20 100644
--- a/data/presets/Monstro/HorrorLead.xpf
+++ b/data/presets/Monstro/HorrorLead.xpf
@@ -16,7 +16,7 @@
-
+
@@ -28,7 +28,7 @@
-
+
@@ -42,7 +42,7 @@
-
+
diff --git a/data/presets/Monstro/Phat.xpf b/data/presets/Monstro/Phat.xpf
index ec572d73354..f2c0b9fe0f1 100644
--- a/data/presets/Monstro/Phat.xpf
+++ b/data/presets/Monstro/Phat.xpf
@@ -16,7 +16,7 @@
-
+
diff --git a/data/presets/Monstro/ScaryBell.xpf b/data/presets/Monstro/ScaryBell.xpf
index 034521ad426..c441c19e39c 100644
--- a/data/presets/Monstro/ScaryBell.xpf
+++ b/data/presets/Monstro/ScaryBell.xpf
@@ -16,7 +16,7 @@
-
+
@@ -28,7 +28,7 @@
-
+
diff --git a/data/presets/Nescaline/Detune_lead.xpf b/data/presets/Nescaline/Detune_lead.xpf
index 94173d6909d..29f2a82dde6 100644
--- a/data/presets/Nescaline/Detune_lead.xpf
+++ b/data/presets/Nescaline/Detune_lead.xpf
@@ -16,7 +16,7 @@
-
+
diff --git a/data/presets/Nescaline/Fireball_flick.xpf b/data/presets/Nescaline/Fireball_flick.xpf
index c2ce19aaaee..a84d7075c67 100644
--- a/data/presets/Nescaline/Fireball_flick.xpf
+++ b/data/presets/Nescaline/Fireball_flick.xpf
@@ -16,7 +16,7 @@
-
+
diff --git a/data/presets/OpulenZ/Bagpipe.xpf b/data/presets/OpulenZ/Bagpipe.xpf
index 41a80c1e312..aedf62c50b3 100644
--- a/data/presets/OpulenZ/Bagpipe.xpf
+++ b/data/presets/OpulenZ/Bagpipe.xpf
@@ -16,7 +16,7 @@
-
+
diff --git a/data/presets/OpulenZ/Combo_organ.xpf b/data/presets/OpulenZ/Combo_organ.xpf
index 457c3f31866..7828ba50233 100644
--- a/data/presets/OpulenZ/Combo_organ.xpf
+++ b/data/presets/OpulenZ/Combo_organ.xpf
@@ -16,7 +16,7 @@
-
+
diff --git a/data/presets/OpulenZ/Funky.xpf b/data/presets/OpulenZ/Funky.xpf
index 5394d54dbc8..df323a99938 100644
--- a/data/presets/OpulenZ/Funky.xpf
+++ b/data/presets/OpulenZ/Funky.xpf
@@ -16,7 +16,7 @@
-
+
diff --git a/data/presets/OpulenZ/Harp.xpf b/data/presets/OpulenZ/Harp.xpf
index c78e4e8964c..c5a894669de 100644
--- a/data/presets/OpulenZ/Harp.xpf
+++ b/data/presets/OpulenZ/Harp.xpf
@@ -16,7 +16,7 @@
-
+
diff --git a/data/presets/OpulenZ/Organ_leslie.xpf b/data/presets/OpulenZ/Organ_leslie.xpf
index 6d1bfbe77ea..57ccd784591 100644
--- a/data/presets/OpulenZ/Organ_leslie.xpf
+++ b/data/presets/OpulenZ/Organ_leslie.xpf
@@ -16,7 +16,7 @@
-
+
diff --git a/data/presets/OpulenZ/Square.xpf b/data/presets/OpulenZ/Square.xpf
index 349debf6bc5..6a5109d9497 100644
--- a/data/presets/OpulenZ/Square.xpf
+++ b/data/presets/OpulenZ/Square.xpf
@@ -16,7 +16,7 @@
-
+
diff --git a/data/presets/Organic/Pwnage.xpf b/data/presets/Organic/Pwnage.xpf
index 39aac12e749..48874af108f 100644
--- a/data/presets/Organic/Pwnage.xpf
+++ b/data/presets/Organic/Pwnage.xpf
@@ -16,7 +16,7 @@
-
+
@@ -38,7 +38,7 @@
-
+
@@ -66,7 +66,7 @@
-
+
@@ -80,7 +80,7 @@
-
+
@@ -98,7 +98,7 @@
-
+
@@ -112,7 +112,7 @@
-
+
diff --git a/data/presets/Organic/Rubberband.xpf b/data/presets/Organic/Rubberband.xpf
index 2e65f8c6ee2..da4a56f56d3 100644
--- a/data/presets/Organic/Rubberband.xpf
+++ b/data/presets/Organic/Rubberband.xpf
@@ -16,7 +16,7 @@
-
+
diff --git a/data/presets/SID/CheesyGuitar.xpf b/data/presets/SID/CheesyGuitar.xpf
index 5e5e2e348a8..cea9adab870 100644
--- a/data/presets/SID/CheesyGuitar.xpf
+++ b/data/presets/SID/CheesyGuitar.xpf
@@ -16,7 +16,7 @@
-
+
@@ -25,7 +25,7 @@
-
+
diff --git a/data/presets/SID/MadMind.xpf b/data/presets/SID/MadMind.xpf
index a5c2d2bf6b7..910786f87a5 100644
--- a/data/presets/SID/MadMind.xpf
+++ b/data/presets/SID/MadMind.xpf
@@ -16,7 +16,7 @@
-
+
@@ -25,7 +25,7 @@
-
+
@@ -39,7 +39,7 @@
-
+
diff --git a/data/presets/SID/Overdrive.xpf b/data/presets/SID/Overdrive.xpf
index fcfa8a86333..c947de3c2bb 100644
--- a/data/presets/SID/Overdrive.xpf
+++ b/data/presets/SID/Overdrive.xpf
@@ -16,7 +16,7 @@
-
+
@@ -25,7 +25,7 @@
-
+
@@ -39,7 +39,7 @@
-
+
diff --git a/data/presets/TripleOscillator/Bell.xpf b/data/presets/TripleOscillator/Bell.xpf
index 181462ac99d..6681d9094e2 100644
--- a/data/presets/TripleOscillator/Bell.xpf
+++ b/data/presets/TripleOscillator/Bell.xpf
@@ -16,7 +16,7 @@
-
+
diff --git a/data/presets/TripleOscillator/BrokenToy.xpf b/data/presets/TripleOscillator/BrokenToy.xpf
index b12a57e8c7c..5ad1e3c1a6d 100644
--- a/data/presets/TripleOscillator/BrokenToy.xpf
+++ b/data/presets/TripleOscillator/BrokenToy.xpf
@@ -16,7 +16,7 @@
-
+
diff --git a/data/presets/TripleOscillator/CryingPads.xpf b/data/presets/TripleOscillator/CryingPads.xpf
index 47ec11889f5..99976ed298d 100644
--- a/data/presets/TripleOscillator/CryingPads.xpf
+++ b/data/presets/TripleOscillator/CryingPads.xpf
@@ -16,7 +16,7 @@
-
+
diff --git a/data/presets/TripleOscillator/DetunedGhost.xpf b/data/presets/TripleOscillator/DetunedGhost.xpf
index e72a6e365f5..5a98f06202a 100644
--- a/data/presets/TripleOscillator/DetunedGhost.xpf
+++ b/data/presets/TripleOscillator/DetunedGhost.xpf
@@ -18,7 +18,7 @@
-
+
diff --git a/data/presets/TripleOscillator/DirtyReece.xpf b/data/presets/TripleOscillator/DirtyReece.xpf
index 095c3e66525..96d15f7be43 100644
--- a/data/presets/TripleOscillator/DirtyReece.xpf
+++ b/data/presets/TripleOscillator/DirtyReece.xpf
@@ -16,7 +16,7 @@
-
+
@@ -36,7 +36,7 @@
-
+
@@ -51,7 +51,7 @@
-
+
@@ -63,7 +63,7 @@
-
+
diff --git a/data/presets/TripleOscillator/Drums_HardKick.xpf b/data/presets/TripleOscillator/Drums_HardKick.xpf
index 104c4066e4b..4be935391b5 100644
--- a/data/presets/TripleOscillator/Drums_HardKick.xpf
+++ b/data/presets/TripleOscillator/Drums_HardKick.xpf
@@ -16,7 +16,7 @@
-
+
@@ -38,7 +38,7 @@
-
+
@@ -52,7 +52,7 @@
-
+
@@ -70,7 +70,7 @@
-
+
@@ -88,7 +88,7 @@
-
+
diff --git a/data/presets/TripleOscillator/Drums_Kick.xpf b/data/presets/TripleOscillator/Drums_Kick.xpf
index 30c8284e6a5..b65e9d18c11 100644
--- a/data/presets/TripleOscillator/Drums_Kick.xpf
+++ b/data/presets/TripleOscillator/Drums_Kick.xpf
@@ -16,7 +16,7 @@
-
+
diff --git a/data/presets/TripleOscillator/Drums_Snare.xpf b/data/presets/TripleOscillator/Drums_Snare.xpf
index 62f6c55dbd3..40d6d6ae74d 100644
--- a/data/presets/TripleOscillator/Drums_Snare.xpf
+++ b/data/presets/TripleOscillator/Drums_Snare.xpf
@@ -16,7 +16,7 @@
-
+
diff --git a/data/presets/TripleOscillator/E-Organ2.xpf b/data/presets/TripleOscillator/E-Organ2.xpf
index cc96f9e76f7..e2a50c10aec 100644
--- a/data/presets/TripleOscillator/E-Organ2.xpf
+++ b/data/presets/TripleOscillator/E-Organ2.xpf
@@ -16,7 +16,7 @@
-
+
diff --git a/data/presets/TripleOscillator/ElectricOboe.xpf b/data/presets/TripleOscillator/ElectricOboe.xpf
index 70035a87f25..474e8553492 100644
--- a/data/presets/TripleOscillator/ElectricOboe.xpf
+++ b/data/presets/TripleOscillator/ElectricOboe.xpf
@@ -16,7 +16,7 @@
-
+
@@ -28,7 +28,7 @@
-
+
diff --git a/data/presets/TripleOscillator/Erazzor.xpf b/data/presets/TripleOscillator/Erazzor.xpf
index 3f9762190cd..fb1389d5606 100644
--- a/data/presets/TripleOscillator/Erazzor.xpf
+++ b/data/presets/TripleOscillator/Erazzor.xpf
@@ -16,7 +16,7 @@
-
+
@@ -26,7 +26,7 @@
-
+
@@ -36,7 +36,7 @@
-
+
@@ -64,7 +64,7 @@
-
+
@@ -80,7 +80,7 @@
-
+
@@ -92,7 +92,7 @@
-
+
@@ -110,7 +110,7 @@
-
+
diff --git a/data/presets/TripleOscillator/FuzzyAnalogBass.xpf b/data/presets/TripleOscillator/FuzzyAnalogBass.xpf
index 82c3f72e536..13ff3d369c8 100644
--- a/data/presets/TripleOscillator/FuzzyAnalogBass.xpf
+++ b/data/presets/TripleOscillator/FuzzyAnalogBass.xpf
@@ -17,7 +17,7 @@
-
+
diff --git a/data/presets/TripleOscillator/Garfunkel.xpf b/data/presets/TripleOscillator/Garfunkel.xpf
index 0e3ba9a2471..bad7bd9b498 100644
--- a/data/presets/TripleOscillator/Garfunkel.xpf
+++ b/data/presets/TripleOscillator/Garfunkel.xpf
@@ -16,7 +16,7 @@
-
+
@@ -25,7 +25,7 @@
-
+
@@ -39,7 +39,7 @@
-
+
@@ -51,7 +51,7 @@
-
+
diff --git a/data/presets/TripleOscillator/GhostBoy.xpf b/data/presets/TripleOscillator/GhostBoy.xpf
index 90ea1fceae2..2062c2d3281 100644
--- a/data/presets/TripleOscillator/GhostBoy.xpf
+++ b/data/presets/TripleOscillator/GhostBoy.xpf
@@ -16,7 +16,7 @@
-
+
@@ -28,7 +28,7 @@
-
+
@@ -46,7 +46,7 @@
-
+
diff --git a/data/presets/TripleOscillator/OldComputerGames.xpf b/data/presets/TripleOscillator/OldComputerGames.xpf
index c19b3e3525e..f3dded4c428 100644
--- a/data/presets/TripleOscillator/OldComputerGames.xpf
+++ b/data/presets/TripleOscillator/OldComputerGames.xpf
@@ -16,7 +16,7 @@
-
+
@@ -32,7 +32,7 @@
-
+
@@ -50,7 +50,7 @@
-
+
@@ -61,7 +61,7 @@
-
+
diff --git a/data/presets/TripleOscillator/PM-FMstring.xpf b/data/presets/TripleOscillator/PM-FMstring.xpf
index 485a570f666..f55be6ded04 100644
--- a/data/presets/TripleOscillator/PM-FMstring.xpf
+++ b/data/presets/TripleOscillator/PM-FMstring.xpf
@@ -16,7 +16,7 @@
-
+
diff --git a/data/presets/TripleOscillator/PMFMFTWbass.xpf b/data/presets/TripleOscillator/PMFMFTWbass.xpf
index 62ce53ab5f3..a48e131f9f6 100644
--- a/data/presets/TripleOscillator/PMFMFTWbass.xpf
+++ b/data/presets/TripleOscillator/PMFMFTWbass.xpf
@@ -16,7 +16,7 @@
-
+
@@ -28,7 +28,7 @@
-
+
diff --git a/data/presets/TripleOscillator/PMbass.xpf b/data/presets/TripleOscillator/PMbass.xpf
index 9c0f062c9f2..85765a6fc97 100644
--- a/data/presets/TripleOscillator/PMbass.xpf
+++ b/data/presets/TripleOscillator/PMbass.xpf
@@ -16,11 +16,11 @@
-
+
-
+
@@ -36,7 +36,7 @@
-
+
@@ -52,7 +52,7 @@
-
+
@@ -62,7 +62,7 @@
-
+
diff --git a/data/presets/TripleOscillator/PercussiveBass.xpf b/data/presets/TripleOscillator/PercussiveBass.xpf
index c9ebd118a7b..555fa03f0a7 100644
--- a/data/presets/TripleOscillator/PercussiveBass.xpf
+++ b/data/presets/TripleOscillator/PercussiveBass.xpf
@@ -16,7 +16,7 @@
-
+
diff --git a/data/presets/TripleOscillator/Play-some-rock.xpf b/data/presets/TripleOscillator/Play-some-rock.xpf
index 0faeb71e3e9..1b404430f5a 100644
--- a/data/presets/TripleOscillator/Play-some-rock.xpf
+++ b/data/presets/TripleOscillator/Play-some-rock.xpf
@@ -16,7 +16,7 @@
-
+
diff --git a/data/presets/TripleOscillator/PowerStrings.xpf b/data/presets/TripleOscillator/PowerStrings.xpf
index 0fdbd6a56ec..e4bc5315ff4 100644
--- a/data/presets/TripleOscillator/PowerStrings.xpf
+++ b/data/presets/TripleOscillator/PowerStrings.xpf
@@ -16,7 +16,7 @@
-
+
@@ -28,7 +28,7 @@
-
+
diff --git a/data/presets/TripleOscillator/SEGuitar.xpf b/data/presets/TripleOscillator/SEGuitar.xpf
index 3f9445ca354..20118004a6f 100644
--- a/data/presets/TripleOscillator/SEGuitar.xpf
+++ b/data/presets/TripleOscillator/SEGuitar.xpf
@@ -16,7 +16,7 @@
-
+
@@ -26,7 +26,7 @@
-
+
@@ -36,7 +36,7 @@
-
+
@@ -64,7 +64,7 @@
-
+
@@ -80,7 +80,7 @@
-
+
@@ -92,7 +92,7 @@
-
+
diff --git a/data/presets/TripleOscillator/SquarePing.xpf b/data/presets/TripleOscillator/SquarePing.xpf
index 4ce7483f4d7..47cd035666a 100644
--- a/data/presets/TripleOscillator/SquarePing.xpf
+++ b/data/presets/TripleOscillator/SquarePing.xpf
@@ -16,7 +16,7 @@
-
+
diff --git a/data/presets/TripleOscillator/SuperSawLead.xpf b/data/presets/TripleOscillator/SuperSawLead.xpf
index 2e082e645b5..72ef40dee6d 100644
--- a/data/presets/TripleOscillator/SuperSawLead.xpf
+++ b/data/presets/TripleOscillator/SuperSawLead.xpf
@@ -16,7 +16,7 @@
-
+
@@ -34,7 +34,7 @@
-
+
diff --git a/data/presets/TripleOscillator/Supernova.xpf b/data/presets/TripleOscillator/Supernova.xpf
index 9c76dd9de72..0abf3028901 100644
--- a/data/presets/TripleOscillator/Supernova.xpf
+++ b/data/presets/TripleOscillator/Supernova.xpf
@@ -16,11 +16,11 @@
-
+
-
+
@@ -36,7 +36,7 @@
-
+
@@ -52,14 +52,14 @@
-
+
-
+
@@ -77,7 +77,7 @@
-
+
@@ -86,7 +86,7 @@
-
+
diff --git a/data/presets/TripleOscillator/TINTNpad.xpf b/data/presets/TripleOscillator/TINTNpad.xpf
index 8f2c1e90d92..11e289cccd5 100644
--- a/data/presets/TripleOscillator/TINTNpad.xpf
+++ b/data/presets/TripleOscillator/TINTNpad.xpf
@@ -16,7 +16,7 @@
-
+
@@ -28,7 +28,7 @@
-
+
diff --git a/data/presets/TripleOscillator/WarmStack.xpf b/data/presets/TripleOscillator/WarmStack.xpf
index 6b0855e39f9..da6bd95e391 100644
--- a/data/presets/TripleOscillator/WarmStack.xpf
+++ b/data/presets/TripleOscillator/WarmStack.xpf
@@ -16,7 +16,7 @@
-
+
@@ -30,7 +30,7 @@
-
+
@@ -44,7 +44,7 @@
-
+
diff --git a/data/presets/Watsyn/Epic_lead.xpf b/data/presets/Watsyn/Epic_lead.xpf
index a45472ca12a..7cf78392123 100644
--- a/data/presets/Watsyn/Epic_lead.xpf
+++ b/data/presets/Watsyn/Epic_lead.xpf
@@ -16,15 +16,15 @@
-
+
-
+
-
+
diff --git a/data/presets/Watsyn/Pulse.xpf b/data/presets/Watsyn/Pulse.xpf
index 14d58bcd532..0ff99987ef1 100644
--- a/data/presets/Watsyn/Pulse.xpf
+++ b/data/presets/Watsyn/Pulse.xpf
@@ -16,7 +16,7 @@
-
+
diff --git a/data/presets/Xpressive/Dream.xpf b/data/presets/Xpressive/Dream.xpf
index 3eb20cf6084..9ddc66a76f5 100644
--- a/data/presets/Xpressive/Dream.xpf
+++ b/data/presets/Xpressive/Dream.xpf
@@ -16,7 +16,7 @@
-
+
diff --git a/data/projects/demos/StrictProduction-DearJonDoe.mmp b/data/projects/demos/StrictProduction-DearJonDoe.mmp
index 06ea96d9ffd..1e69ab51fcb 100644
--- a/data/projects/demos/StrictProduction-DearJonDoe.mmp
+++ b/data/projects/demos/StrictProduction-DearJonDoe.mmp
@@ -21,7 +21,7 @@
-
+
@@ -94,7 +94,7 @@
-
+
@@ -317,7 +317,7 @@
-
+
diff --git a/data/projects/shorties/Crunk(Demo).mmp b/data/projects/shorties/Crunk(Demo).mmp
index f40a5aafb82..3f791b4b3c4 100644
--- a/data/projects/shorties/Crunk(Demo).mmp
+++ b/data/projects/shorties/Crunk(Demo).mmp
@@ -66,7 +66,7 @@
-
+
@@ -131,7 +131,7 @@
-
+
diff --git a/include/Effect.h b/include/Effect.h
index 7eb911701a0..3c6a6e37d50 100644
--- a/include/Effect.h
+++ b/include/Effect.h
@@ -26,10 +26,12 @@
#ifndef LMMS_EFFECT_H
#define LMMS_EFFECT_H
-#include "Plugin.h"
-#include "Engine.h"
+#include
+
#include "AudioEngine.h"
#include "AutomatableModel.h"
+#include "Engine.h"
+#include "Plugin.h"
#include "TempoSyncKnobModel.h"
namespace lmms
@@ -66,16 +68,6 @@ class LMMS_EXPORT Effect : public Plugin
//! Returns true if audio was processed and should continue being processed
bool processAudioBuffer(SampleFrame* buf, const fpp_t frames);
- inline ch_cnt_t processorCount() const
- {
- return m_processors;
- }
-
- inline void setProcessorCount( ch_cnt_t _processors )
- {
- m_processors = _processors;
- }
-
inline bool isOkay() const
{
return m_okay;
@@ -92,14 +84,15 @@ class LMMS_EXPORT Effect : public Plugin
return m_running;
}
- inline void startRunning()
- {
- m_bufferCount = 0;
- m_running = true;
+ void startRunning()
+ {
+ m_quietBufferCount = 0;
+ m_running = true;
}
- inline void stopRunning()
+ void stopRunning()
{
+ m_quietBufferCount = 0;
m_running = false;
}
@@ -124,27 +117,6 @@ class LMMS_EXPORT Effect : public Plugin
return 1.0f - m_wetDryModel.value();
}
- inline float gate() const
- {
- const float level = m_gateModel.value();
- return level*level * m_processors;
- }
-
- inline f_cnt_t bufferCount() const
- {
- return m_bufferCount;
- }
-
- inline void resetBufferCount()
- {
- m_bufferCount = 0;
- }
-
- inline void incrementBufferCount()
- {
- ++m_bufferCount;
- }
-
inline bool dontRun() const
{
return m_noRun;
@@ -160,6 +132,11 @@ class LMMS_EXPORT Effect : public Plugin
return &m_autoQuitModel;
}
+ bool autoQuitEnabled() const
+ {
+ return m_autoQuitEnabled;
+ }
+
EffectChain * effectChain() const
{
return m_parent;
@@ -227,11 +204,11 @@ class LMMS_EXPORT Effect : public Plugin
private:
/**
- If the setting "Keep effects running even without input" is disabled,
- after "decay" ms of a signal below "gate", the effect is turned off
- and won't be processed again until it receives new audio input
- */
- void checkGate(double outSum);
+ * If auto-quit is enabled ("Keep effects running even without input" setting is disabled),
+ * after "decay" ms of the output buffer remaining below the silence threshold, the effect is
+ * turned off and won't be processed again until it receives new audio input.
+ */
+ void handleAutoQuit(std::span output);
EffectChain * m_parent;
@@ -240,19 +217,18 @@ class LMMS_EXPORT Effect : public Plugin
SampleFrame* _dst_buf, sample_rate_t _dst_sr,
const f_cnt_t _frames );
- ch_cnt_t m_processors;
-
bool m_okay;
bool m_noRun;
bool m_running;
- f_cnt_t m_bufferCount;
+
+ //! The number of consecutive periods where output buffers remain below the silence threshold
+ f_cnt_t m_quietBufferCount = 0;
BoolModel m_enabledModel;
FloatModel m_wetDryModel;
- FloatModel m_gateModel;
TempoSyncKnobModel m_autoQuitModel;
-
- bool m_autoQuitDisabled;
+
+ bool m_autoQuitEnabled = false;
SRC_DATA m_srcData[2];
SRC_STATE * m_srcState[2];
diff --git a/include/EffectView.h b/include/EffectView.h
index 805e4a4279c..cd45b735e77 100644
--- a/include/EffectView.h
+++ b/include/EffectView.h
@@ -92,7 +92,6 @@ public slots:
LedCheckBox * m_bypass;
Knob * m_wetDry;
TempoSyncKnob * m_autoQuit;
- Knob * m_gate;
QMdiSubWindow * m_subWindow;
EffectControlDialog * m_controlView;
diff --git a/plugins/LadspaEffect/LadspaEffect.cpp b/plugins/LadspaEffect/LadspaEffect.cpp
index eebe6938cad..ff6a184747a 100644
--- a/plugins/LadspaEffect/LadspaEffect.cpp
+++ b/plugins/LadspaEffect/LadspaEffect.cpp
@@ -280,7 +280,7 @@ void LadspaEffect::pluginInstantiation()
// Calculate how many processing units are needed.
int effect_channels = manager->getDescription( m_key )->inputChannels;
- setProcessorCount(DEFAULT_CHANNELS / effect_channels);
+ m_processors = DEFAULT_CHANNELS / effect_channels;
// get inPlaceBroken property
m_inPlaceBroken = manager->isInplaceBroken( m_key );
diff --git a/plugins/LadspaEffect/LadspaEffect.h b/plugins/LadspaEffect/LadspaEffect.h
index 0cfa186821f..7d2f73baf59 100644
--- a/plugins/LadspaEffect/LadspaEffect.h
+++ b/plugins/LadspaEffect/LadspaEffect.h
@@ -61,6 +61,10 @@ class LadspaEffect : public Effect
return m_portControls;
}
+ ch_cnt_t processorCount() const
+ {
+ return m_processors;
+ }
private slots:
void changeSampleRate();
@@ -87,7 +91,8 @@ private slots:
QVector m_ports;
multi_proc_t m_portControls;
-} ;
+ ch_cnt_t m_processors = 1;
+};
} // namespace lmms
diff --git a/src/core/Effect.cpp b/src/core/Effect.cpp
index 37133d4d5dd..979237ea82a 100644
--- a/src/core/Effect.cpp
+++ b/src/core/Effect.cpp
@@ -43,27 +43,19 @@ Effect::Effect( const Plugin::Descriptor * _desc,
const Descriptor::SubPluginFeatures::Key * _key ) :
Plugin( _desc, _parent, _key ),
m_parent( nullptr ),
- m_processors( 1 ),
m_okay( true ),
m_noRun( false ),
m_running( false ),
- m_bufferCount( 0 ),
m_enabledModel( true, this, tr( "Effect enabled" ) ),
m_wetDryModel( 1.0f, -1.0f, 1.0f, 0.01f, this, tr( "Wet/Dry mix" ) ),
- m_gateModel( 0.0f, 0.0f, 1.0f, 0.01f, this, tr( "Gate" ) ),
m_autoQuitModel( 1.0f, 1.0f, 8000.0f, 100.0f, 1.0f, this, tr( "Decay" ) ),
- m_autoQuitDisabled( false )
+ m_autoQuitEnabled(ConfigManager::inst()->value("ui", "disableautoquit", "1").toInt() == 0)
{
m_wetDryModel.setCenterValue(0);
m_srcState[0] = m_srcState[1] = nullptr;
reinitSRC();
- if( ConfigManager::inst()->value( "ui", "disableautoquit").toInt() )
- {
- m_autoQuitDisabled = true;
- }
-
// Call the virtual method onEnabledChanged so that effects can react to changes,
// e.g. by resetting state.
connect(&m_enabledModel, &BoolModel::dataChanged, [this] { onEnabledChanged(); });
@@ -91,7 +83,6 @@ void Effect::saveSettings( QDomDocument & _doc, QDomElement & _this )
m_enabledModel.saveSettings( _doc, _this, "on" );
m_wetDryModel.saveSettings( _doc, _this, "wet" );
m_autoQuitModel.saveSettings( _doc, _this, "autoquit" );
- m_gateModel.saveSettings( _doc, _this, "gate" );
controls()->saveState( _doc, _this );
}
@@ -103,7 +94,6 @@ void Effect::loadSettings( const QDomElement & _this )
m_enabledModel.loadSettings( _this, "on" );
m_wetDryModel.loadSettings( _this, "wet" );
m_autoQuitModel.loadSettings( _this, "autoquit" );
- m_gateModel.loadSettings( _this, "gate" );
QDomNode node = _this.firstChild();
while( !node.isNull() )
@@ -136,16 +126,8 @@ bool Effect::processAudioBuffer(SampleFrame* buf, const fpp_t frames)
case ProcessStatus::Continue:
break;
case ProcessStatus::ContinueIfNotQuiet:
- {
- double outSum = 0.0;
- for (std::size_t idx = 0; idx < frames; ++idx)
- {
- outSum += buf[idx].sumOfSquaredAmplitudes();
- }
-
- checkGate(outSum / frames);
+ handleAutoQuit({buf, frames});
break;
- }
case ProcessStatus::Sleep:
return false;
default:
@@ -181,27 +163,55 @@ Effect * Effect::instantiate( const QString& pluginName,
-void Effect::checkGate(double outSum)
+void Effect::handleAutoQuit(std::span output)
{
- if( m_autoQuitDisabled )
+ if (!m_autoQuitEnabled)
{
return;
}
- // Check whether we need to continue processing input. Restart the
+ /*
+ * In the past, the RMS was calculated then compared with a threshold of 10^(-10).
+ * Now we use a different algorithm to determine whether a buffer is non-quiet, so
+ * a new threshold is needed for the best compatibility. The following is how it's derived.
+ *
+ * Old method:
+ * RMS = average (L^2 + R^2) across stereo buffer.
+ * RMS threshold = 10^(-10)
+ *
+ * So for a single channel, it would be:
+ * RMS/2 = average M^2 across single channel buffer.
+ * RMS/2 threshold = 5^(-11)
+ *
+ * The new algorithm for determining whether a buffer is non-silent compares M with the threshold,
+ * not M^2, so the square root of M^2's threshold should give us the most compatible threshold for
+ * the new algorithm:
+ *
+ * (RMS/2)^0.5 = (5^(-11))^0.5 = 0.0001431 (approx.)
+ *
+ * In practice though, the exact value shouldn't really matter so long as it's sufficiently small.
+ */
+ static constexpr auto threshold = 0.0001431f;
+
+ // Check whether we need to continue processing input. Restart the
// counter if the threshold has been exceeded.
- if (outSum - gate() <= F_EPSILON)
+
+ for (const SampleFrame& frame : output)
{
- incrementBufferCount();
- if( bufferCount() > timeout() )
+ const auto abs = frame.abs();
+ if (abs.left() >= threshold || abs.right() >= threshold)
{
- stopRunning();
- resetBufferCount();
+ // The output buffer is not quiet
+ m_quietBufferCount = 0;
+ return;
}
}
- else
+
+ // The output buffer is quiet, so check if auto-quit should be activated yet
+ if (++m_quietBufferCount > timeout())
{
- resetBufferCount();
+ // Activate auto-quit
+ stopRunning();
}
}
diff --git a/src/gui/EffectView.cpp b/src/gui/EffectView.cpp
index a77fc1d967b..428035b9564 100644
--- a/src/gui/EffectView.cpp
+++ b/src/gui/EffectView.cpp
@@ -71,16 +71,9 @@ EffectView::EffectView( Effect * _model, QWidget * _parent ) :
m_autoQuit = new TempoSyncKnob(KnobType::Bright26, tr("DECAY"), this, Knob::LabelRendering::LegacyFixedFontSize);
m_autoQuit->move( 78 - m_autoQuit->width() / 2, 5 );
- m_autoQuit->setEnabled( isEnabled && !effect()->m_autoQuitDisabled );
+ m_autoQuit->setEnabled(isEnabled && effect()->autoQuitEnabled());
m_autoQuit->setHintText( tr( "Time:" ), "ms" );
-
- m_gate = new Knob(KnobType::Bright26, tr("GATE"), this, Knob::LabelRendering::LegacyFixedFontSize);
- m_gate->move( 116 - m_gate->width() / 2, 5 );
- m_gate->setEnabled( isEnabled && !effect()->m_autoQuitDisabled );
- m_gate->setHintText( tr( "Gate:" ), "" );
-
-
setModel( _model );
if( effect()->controls()->controlCount() > 0 )
@@ -275,7 +268,6 @@ void EffectView::modelChanged()
m_bypass->setModel( &effect()->m_enabledModel );
m_wetDry->setModel( &effect()->m_wetDryModel );
m_autoQuit->setModel( &effect()->m_autoQuitModel );
- m_gate->setModel( &effect()->m_gateModel );
}
} // namespace lmms::gui