[SCM] calf/master: Distortion extracted, Enhancer, new tubes, recoloring in .rc

js at users.alioth.debian.org js at users.alioth.debian.org
Tue May 7 15:39:42 UTC 2013


The following commit has been merged in the master branch:
commit 18b3c7b6a75634067992bed49a6fc8392e361f2c
Author: Markus Schmidt <schmidt at boomshop.net>
Date:   Fri Nov 6 05:39:16 2009 +0100

    Distortion extracted, Enhancer, new tubes, recoloring in .rc

diff --git a/gui/calf.rc b/gui/calf.rc
index ffa7924..5e93ec9 100644
--- a/gui/calf.rc
+++ b/gui/calf.rc
@@ -156,7 +156,7 @@ style "clearlooks-button"
 		{
 			function		= BOX
 			detail			= "buttondefault"
-			recolorable		= TRUE
+			recolorable		= FALSE
 			file			= "button_normal.png"
 			border			= {6, 24, 6, 6}
 			stretch			= TRUE
@@ -165,7 +165,7 @@ style "clearlooks-button"
 		{
 			function		= BOX
 			state			= PRELIGHT
-			recolorable		= TRUE
+			recolorable		= FALSE
 			file			= "button_prelight.png"
 			border			= {6, 24, 6, 6}
 			stretch			= TRUE
@@ -230,7 +230,7 @@ style "clearlooks-button-norm"
 		image
 		{
 			function		= VLINE
-			recolorable		= TRUE
+			recolorable		= FALSE
 			file			= "vline.png"
 			border			= { 1, 1, 0, 0 }
 			stretch			= TRUE
@@ -238,7 +238,7 @@ style "clearlooks-button-norm"
 		image
 		{
 			function		= HLINE
-			recolorable		= TRUE
+			recolorable		= FALSE
 			file			= "hline.png"
 			border			= { 0, 0, 1, 1	}
 			stretch			= TRUE
@@ -277,7 +277,7 @@ style "clearlooks-notebook"
 		image
 		{
 			function		= EXTENSION
-			recolorable		= TRUE
+			recolorable		= FALSE
 			state			= ACTIVE
 			file			= "tab_bottom_normal.png"
 			border			= { 24, 24, 0, 19 }
@@ -287,7 +287,7 @@ style "clearlooks-notebook"
 		image
 		{
 			function		= EXTENSION
-			recolorable		= TRUE
+			recolorable		= FALSE
 			state			= ACTIVE
 			file			= "tab_top_normal.png"
 			border			= { 24, 24, 19, 0 }
@@ -297,7 +297,7 @@ style "clearlooks-notebook"
 		image
 		{
 			function		= EXTENSION
-			recolorable		= TRUE
+			recolorable		= FALSE
 			state			= ACTIVE
 			file			= "tab_left_normal.png"
 			border			= { 19, 0, 24, 24 }
@@ -307,7 +307,7 @@ style "clearlooks-notebook"
 		image
 		{
 			function		= EXTENSION
-			recolorable		= TRUE
+			recolorable		= FALSE
 			state			= ACTIVE
 			file			= "tab_right_normal.png"
 			border			= { 0, 19, 24, 24 }
@@ -317,7 +317,7 @@ style "clearlooks-notebook"
 		image
 		{
 			function		= EXTENSION
-			recolorable		= TRUE
+			recolorable		= FALSE
 			file			= "tab_top_prelight.png"
 			border			= { 24, 24, 19, 0 }
 			stretch			= TRUE
@@ -326,7 +326,7 @@ style "clearlooks-notebook"
 		image
 		{
 			function		= EXTENSION
-			recolorable		= TRUE
+			recolorable		= FALSE
 			file			= "tab_bottom_prelight.png"
 			border			= { 24, 24, 0, 19 }
 			stretch			= TRUE
@@ -335,7 +335,7 @@ style "clearlooks-notebook"
 		image
 		{
 			function		= EXTENSION
-			recolorable		= TRUE
+			recolorable		= FALSE
 			file			= "tab_left_prelight.png"
 			border			= { 19, 0, 24, 24 }
 			stretch			= TRUE
@@ -344,7 +344,7 @@ style "clearlooks-notebook"
 		image
 		{
 			function		= EXTENSION
-			recolorable		= TRUE
+			recolorable		= FALSE
 			file			= "tab_right_prelight.png"
 			border			= { 0, 19, 24, 24 }
 			stretch			= TRUE
@@ -354,7 +354,7 @@ style "clearlooks-notebook"
 		image
 		{
 			function		= BOX_GAP
-			recolorable		= TRUE
+			recolorable		= FALSE
 			file			= "notebook_top.png"
 			border			= { 21, 21, 21, 21 }
 			stretch			= TRUE
@@ -363,7 +363,7 @@ style "clearlooks-notebook"
 		image
 		{
 			function		= BOX_GAP
-			recolorable		= TRUE
+			recolorable		= FALSE
 			file			= "notebook_bottom.png"
 			border			= { 21, 21, 21, 21 }
 			stretch			= TRUE
@@ -372,7 +372,7 @@ style "clearlooks-notebook"
 		image
 		{
 			function		= BOX_GAP
-			recolorable		= TRUE
+			recolorable		= FALSE
 			file			= "notebook_left.png"
 			border			= { 21, 21, 21, 21 }
 			stretch			= TRUE
@@ -381,7 +381,7 @@ style "clearlooks-notebook"
 		image
 		{
 			function		= BOX_GAP
-			recolorable		= TRUE
+			recolorable		= FALSE
 			file			= "notebook_right.png"
 			border			= { 21, 21, 21, 21 }
 			stretch			= TRUE
@@ -392,7 +392,7 @@ style "clearlooks-notebook"
 		image
 		{
 			function		= BOX_GAP
-			recolorable		= TRUE
+			recolorable		= FALSE
 			file			= "notebook.png"
 			border			= { 21, 21, 21, 21 }
 			stretch			= TRUE
@@ -544,7 +544,7 @@ style "clearlooks-combobox"
 		image
 		{
 			function		= BOX
-			recolorable		= TRUE
+			recolorable		= FALSE
 			state			= PRELIGHT
 			file			= "button_default.png"
 			border			= {8, 24, 6, 6}
@@ -553,7 +553,7 @@ style "clearlooks-combobox"
 		image
 		{
 			function		= BOX
-			recolorable		= TRUE
+			recolorable		= FALSE
 			state			= NORMAL
 			file			= "button_default.png"
 			border			= {8, 24, 6, 6}
@@ -563,7 +563,7 @@ style "clearlooks-combobox"
 		image
 		{
 			function		= BOX
-			recolorable		= TRUE
+			recolorable		= FALSE
 			state			= ACTIVE
 			file			= "button_default.png"
 			border			= {8, 24, 6, 6}
@@ -572,7 +572,7 @@ style "clearlooks-combobox"
 		image
 		{
 			function		= BOX
-			recolorable		= TRUE
+			recolorable		= FALSE
 			state			= INSENSITIVE
 			file			= "button_default.png"
 			border			= {8, 24, 6, 6}
@@ -582,23 +582,23 @@ style "clearlooks-combobox"
 		{
 			function		= TAB
 			state			= INSENSITIVE
-			recolorable		= TRUE
-			overlay_file		= "led.png"
+			recolorable		= FALSE
+			overlay_file		= "led_inactive.png"
 			overlay_stretch		= FALSE
 		}
 		image
 		{
 			function		= TAB
-			recolorable		= TRUE
+			recolorable		= FALSE
 			state			= NORMAL
-			overlay_file		= "led.png"
+			overlay_file		= "led_normal.png"
 			overlay_border		= { 3, 3, 2, 2 }
 			overlay_stretch		= FALSE
 		}
 		image
 		{
 			function		= TAB
-			recolorable		= TRUE
+			recolorable		= FALSE
 			state			= ACTIVE
 			overlay_file		= "led_prelight.png"
 			overlay_border		= { 3, 3, 2, 2 }
@@ -607,7 +607,7 @@ style "clearlooks-combobox"
 		image
 		{
 			function		= TAB
-			recolorable		= TRUE
+			recolorable		= FALSE
 			state			= PRELIGHT
 			overlay_file		= "led_prelight.png"
 			overlay_border		= { 3, 3, 2, 2 }
@@ -616,7 +616,7 @@ style "clearlooks-combobox"
 		image
 		{
 			function		= VLINE
-			recolorable		= TRUE
+			recolorable		= FALSE
 			file			= "vline.png"
 			border			= { 1, 1, 0, 0 }
 			stretch			= TRUE
@@ -624,7 +624,7 @@ style "clearlooks-combobox"
 		image
 		{
 			function		= HLINE
-			recolorable		= TRUE
+			recolorable		= FALSE
 			file			= "hline.png"
 			border			= { 0, 0, 1, 1	}
 			stretch			= TRUE
@@ -659,7 +659,7 @@ style "clearlooks-spinbutton" = "clearlooks-default"
 			function		= BOX
 			state 			= NORMAL
 			detail			= "spinbutton_up"
-			recolorable		= TRUE
+			recolorable		= FALSE
 			file			= "spin_up_normal.png"
 			border			= { 6, 4, 4, 3 }
 			stretch			= TRUE
@@ -671,7 +671,7 @@ style "clearlooks-spinbutton" = "clearlooks-default"
 			function		= BOX
 			state 			= PRELIGHT
 			detail			= "spinbutton_up"
-			recolorable		= TRUE
+			recolorable		= FALSE
 			file			= "spin_up_prelight.png"
 			border			= { 6, 4, 4, 3 }
 			stretch			= TRUE
@@ -683,7 +683,7 @@ style "clearlooks-spinbutton" = "clearlooks-default"
 			function		= BOX
 			state 			= INSENSITIVE
 			detail			= "spinbutton_up"
-			recolorable		= TRUE
+			recolorable		= FALSE
 			file			= "spin_up_inactive.png"
 			border			= { 6, 4, 4, 3 }
 			stretch			= TRUE
@@ -695,7 +695,7 @@ style "clearlooks-spinbutton" = "clearlooks-default"
 			function		= BOX
 			state 			= ACTIVE
 			detail			= "spinbutton_up"
-			recolorable		= TRUE
+			recolorable		= FALSE
 			file			= "spin_up_active.png"
 			border			= { 6, 4, 4, 3 }
 			stretch			= TRUE
@@ -708,7 +708,7 @@ style "clearlooks-spinbutton" = "clearlooks-default"
 			function		= BOX
 			state 			= NORMAL
 			detail			= "spinbutton_down"
-			recolorable		= TRUE
+			recolorable		= FALSE
 			file			= "spin_down_normal.png"
 			border			= { 6, 4, 3, 3 }
 			stretch			= TRUE
@@ -720,7 +720,7 @@ style "clearlooks-spinbutton" = "clearlooks-default"
 			function		= BOX
 			state 			= PRELIGHT
 			detail			= "spinbutton_down"
-			recolorable		= TRUE
+			recolorable		= FALSE
 			file			= "spin_down_prelight.png"
 			border			= { 6, 4, 3, 3 }
 			stretch			= TRUE
@@ -732,7 +732,7 @@ style "clearlooks-spinbutton" = "clearlooks-default"
 			function		= BOX
 			state 			= INSENSITIVE
 			detail			= "spinbutton_down"
-			recolorable		= TRUE
+			recolorable		= FALSE
 			file			= "spin_down_inactive.png"
 			border			= { 6, 4, 3, 3 }
 			stretch			= TRUE
@@ -744,7 +744,7 @@ style "clearlooks-spinbutton" = "clearlooks-default"
 			function		= BOX
 			state 			= ACTIVE
 			detail			= "spinbutton_down"
-			recolorable		= TRUE
+			recolorable		= FALSE
 			file			= "spin_down_active.png"
 			border			= { 6, 4, 3, 3 }
 			stretch			= TRUE
@@ -767,7 +767,7 @@ style "clearlooks-scale"
 		image
 		{
 			function		= BOX
-			recolorable		= TRUE
+			recolorable		= FALSE
 			detail			= "trough"
 			file			= "trough-horizontal.png"
 			border			= { 20, 20, 0, 0 }
@@ -777,7 +777,7 @@ style "clearlooks-scale"
 		image
 		{
 			function		= BOX
-			recolorable		= TRUE
+			recolorable		= FALSE
 			detail			= "trough"
 			file			= "trough-vertical.png"
 			border			= { 0, 0, 20, 20 }
@@ -788,7 +788,7 @@ style "clearlooks-scale"
 		image
 		{
 			function		= SLIDER
-			recolorable		= TRUE
+			recolorable		= FALSE
 			state			= NORMAL
 			file			= "null.png"
 			border			= { 0, 0, 0, 0 }
@@ -800,7 +800,7 @@ style "clearlooks-scale"
 		image
 		{
 			function		= SLIDER
-			recolorable		= TRUE
+			recolorable		= FALSE
 			state			= PRELIGHT
 			file			= "null.png"
 			border			= { 0, 0, 0, 0 }
@@ -812,7 +812,7 @@ style "clearlooks-scale"
 		image
 		{
 			function		= SLIDER
-			recolorable		= TRUE
+			recolorable		= FALSE
 			state			= INSENSITIVE
 			file			= "null.png"
 			border			= { 0, 0, 0, 0 }
@@ -824,7 +824,7 @@ style "clearlooks-scale"
 		image
 		{
 			function		= SLIDER
-			recolorable		= TRUE
+			recolorable		= FALSE
 			state			= NORMAL
 			file			= "null.png"
 			border			= { 0, 0, 0, 0 }
@@ -836,7 +836,7 @@ style "clearlooks-scale"
 		image
 		{
 			function		= SLIDER
-			recolorable		= TRUE
+			recolorable		= FALSE
 			state			= PRELIGHT
 			file			= "null.png"
 			border			= { 0, 0, 0, 0 }
@@ -848,7 +848,7 @@ style "clearlooks-scale"
 		image
 		{
 			function		= SLIDER
-			recolorable		= TRUE
+			recolorable		= FALSE
 			state			= INSENSITIVE
 			file			= "null.png"
 			border			= { 0, 0, 0, 0 }
@@ -873,7 +873,7 @@ style "clearlooks-hscale"
 		image
 		{
 			function		= BOX
-			recolorable		= TRUE
+			recolorable		= FALSE
 			detail			= "trough"
 			file			= "trough-horizontal.png"
 			border			= { 20, 20, 0, 0 }
@@ -883,7 +883,7 @@ style "clearlooks-hscale"
 		image
 		{
 			function		= BOX
-			recolorable		= TRUE
+			recolorable		= FALSE
 			detail			= "trough"
 			file			= "trough-vertical.png"
 			border			= { 0, 0, 20, 20 }
@@ -894,7 +894,7 @@ style "clearlooks-hscale"
 		image
 		{
 			function		= SLIDER
-			recolorable		= TRUE
+			recolorable		= FALSE
 			state			= NORMAL
 			file			= "null.png"
 			border			= { 0, 0, 0, 0 }
@@ -906,7 +906,7 @@ style "clearlooks-hscale"
 		image
 		{
 			function		= SLIDER
-			recolorable		= TRUE
+			recolorable		= FALSE
 			state			= PRELIGHT
 			file			= "null.png"
 			border			= { 0, 0, 0, 0 }
@@ -918,7 +918,7 @@ style "clearlooks-hscale"
 		image
 		{
 			function		= SLIDER
-			recolorable		= TRUE
+			recolorable		= FALSE
 			state			= INSENSITIVE
 			file			= "null.png"
 			border			= { 0, 0, 0, 0 }
@@ -930,7 +930,7 @@ style "clearlooks-hscale"
 		image
 		{
 			function		= SLIDER
-			recolorable		= TRUE
+			recolorable		= FALSE
 			state			= NORMAL
 			file			= "null.png"
 			border			= { 0, 0, 0, 0 }
@@ -942,7 +942,7 @@ style "clearlooks-hscale"
 		image
 		{
 			function		= SLIDER
-			recolorable		= TRUE
+			recolorable		= FALSE
 			state			= PRELIGHT
 			file			= "null.png"
 			border			= { 0, 0, 0, 0 }
@@ -954,7 +954,7 @@ style "clearlooks-hscale"
 		image
 		{
 			function		= SLIDER
-			recolorable		= TRUE
+			recolorable		= FALSE
 			state			= INSENSITIVE
 			file			= "null.png"
 			border			= { 0, 0, 0, 0 }
@@ -979,7 +979,7 @@ style "clearlooks-vscale"
 		image
 		{
 			function		= BOX
-			recolorable		= TRUE
+			recolorable		= FALSE
 			detail			= "trough"
 			file			= "trough-horizontal.png"
 			border			= { 20, 20, 0, 0 }
@@ -989,7 +989,7 @@ style "clearlooks-vscale"
 		image
 		{
 			function		= BOX
-			recolorable		= TRUE
+			recolorable		= FALSE
 			detail			= "trough"
 			file			= "trough-vertical.png"
 			border			= { 0, 0, 20, 20 }
@@ -1000,7 +1000,7 @@ style "clearlooks-vscale"
 		image
 		{
 			function		= SLIDER
-			recolorable		= TRUE
+			recolorable		= FALSE
 			state			= NORMAL
 			file			= "null.png"
 			border			= { 0, 0, 0, 0 }
@@ -1012,7 +1012,7 @@ style "clearlooks-vscale"
 		image
 		{
 			function		= SLIDER
-			recolorable		= TRUE
+			recolorable		= FALSE
 			state			= PRELIGHT
 			file			= "null.png"
 			border			= { 0, 0, 0, 0 }
@@ -1024,7 +1024,7 @@ style "clearlooks-vscale"
 		image
 		{
 			function		= SLIDER
-			recolorable		= TRUE
+			recolorable		= FALSE
 			state			= INSENSITIVE
 			file			= "null.png"
 			border			= { 0, 0, 0, 0 }
@@ -1036,7 +1036,7 @@ style "clearlooks-vscale"
 		image
 		{
 			function		= SLIDER
-			recolorable		= TRUE
+			recolorable		= FALSE
 			state			= NORMAL
 			file			= "null.png"
 			border			= { 0, 0, 0, 0 }
@@ -1048,7 +1048,7 @@ style "clearlooks-vscale"
 		image
 		{
 			function		= SLIDER
-			recolorable		= TRUE
+			recolorable		= FALSE
 			state			= PRELIGHT
 			file			= "null.png"
 			border			= { 0, 0, 0, 0 }
@@ -1060,7 +1060,7 @@ style "clearlooks-vscale"
 		image
 		{
 			function		= SLIDER
-			recolorable		= TRUE
+			recolorable		= FALSE
 			state			= INSENSITIVE
 			file			= "null.png"
 			border			= { 0, 0, 0, 0 }
@@ -1151,7 +1151,7 @@ style "menu-separator" = "menu"
   	image
 		{
 			function		= VLINE
-			recolorable		= TRUE
+			recolorable		= FALSE
 			file			= "vline.png"
 			border			= { 0, 0, 0, 0 }
 			stretch			= TRUE
@@ -1159,7 +1159,7 @@ style "menu-separator" = "menu"
 		image
 		{
 			function		= HLINE
-			recolorable		= TRUE
+			recolorable		= FALSE
 			file			= "hline.png"
 			border			= { 0, 0, 0, 0	}
 			stretch			= TRUE
@@ -1245,7 +1245,7 @@ style "scrollbar" = "default"
     image 
     {
       function			= BOX
-      recolorable		= TRUE
+      recolorable		= FALSE
       detail			= "trough"
       file				= "background_black.png"
       stretch			= FALSE
@@ -1254,7 +1254,7 @@ style "scrollbar" = "default"
     image 
     {
       function			= BOX
-      recolorable		= TRUE
+      recolorable		= FALSE
       detail			= "trough"
       file				= "background_black.png"
       stretch			= TRUE
@@ -1267,7 +1267,7 @@ style "scrollbar" = "default"
   image 
     {
       function			= SLIDER
-      recolorable		= TRUE
+      recolorable		= FALSE
       state           		= NORMAL
       file				= "scroller-horiz.png" 
       border			= { 24,29,1,1 }
@@ -1283,7 +1283,7 @@ style "scrollbar" = "default"
   image 
     {
       function			= SLIDER
-      recolorable		= TRUE
+      recolorable		= FALSE
       state           		= ACTIVE
       shadow			= IN
       file				= "scroller-horiz.png" 
@@ -1299,7 +1299,7 @@ style "scrollbar" = "default"
     image 
     {
       function			= SLIDER
-      recolorable		= TRUE
+      recolorable		= FALSE
       state           		= PRELIGHT
       file				= "scroller-horiz-prelight.png" 
       border			= { 24,29,1,1 }
@@ -1313,7 +1313,7 @@ style "scrollbar" = "default"
     image 
     {
       function			= SLIDER
-      recolorable		= TRUE
+      recolorable		= FALSE
       state           		= INSENSITIVE
       file				= "scroller-horiz-insens.png"
       border			= { 24,29,1,1 }
@@ -1330,7 +1330,7 @@ style "scrollbar" = "default"
  image 
     {
       function			= SLIDER
-      recolorable		= TRUE
+      recolorable		= FALSE
       state           		= NORMAL
       file				= "scroller-vert.png" 
       border			= { 1,1,24,29 }
@@ -1345,7 +1345,7 @@ style "scrollbar" = "default"
    image 
     {
       function			= SLIDER
-      recolorable		= TRUE
+      recolorable		= FALSE
       state           		= ACTIVE
       shadow			= IN
       file				= "scroller-vert.png" 
@@ -1361,7 +1361,7 @@ style "scrollbar" = "default"
     image 
     {
       function			= SLIDER
-      recolorable		= TRUE
+      recolorable		= FALSE
       state           		= PRELIGHT
       file				= "scroller-vert-prelight.png" 
       border			= { 1,1,24,29} 
@@ -1375,7 +1375,7 @@ style "scrollbar" = "default"
     image 
     {
       function			= SLIDER
-      recolorable		= TRUE
+      recolorable		= FALSE
       state           		= INSENSITIVE
       file				= "scroller-vert-insens.png"
       border			= { 1,1,24,29 }
@@ -1395,7 +1395,7 @@ style "scrollbar" = "default"
     image 
     {
       function			= STEPPER
-      recolorable		= TRUE
+      recolorable		= FALSE
       state				= NORMAL
       file				= "screw2.png"
       #border			= { 12, 2, 2, 9 }
@@ -1405,7 +1405,7 @@ style "scrollbar" = "default"
  image 
     {
       function			= STEPPER
-      recolorable		= TRUE
+      recolorable		= FALSE
       state				= PRELIGHT
       file				= "screw2.png"
       #border			= { 12, 2, 2, 9 }
@@ -1415,7 +1415,7 @@ style "scrollbar" = "default"
  image 
     {
       function			= STEPPER
-      recolorable		= TRUE
+      recolorable		= FALSE
       state				= ACTIVE
       file				= "screw2.png"
       #border			= { 12, 2, 2, 9 }
@@ -1425,7 +1425,7 @@ style "scrollbar" = "default"
  image 
     {
       function			= STEPPER
-      recolorable		= TRUE
+      recolorable		= FALSE
       state				= INSENSITIVE
       file				= "screw2.png"
       #border			= { 12, 2, 2, 9 }
@@ -1439,7 +1439,7 @@ style "scrollbar" = "default"
     image 
     {
       function			= STEPPER
-      recolorable		= TRUE
+      recolorable		= FALSE
       state				= NORMAL
       file				= "screw1.png"
       #border			= { 12, 2, 10, 2 }
@@ -1449,7 +1449,7 @@ style "scrollbar" = "default"
  image 
     {
       function			= STEPPER
-      recolorable		= TRUE
+      recolorable		= FALSE
       state				= PRELIGHT
       file				= "screw1.png"
       #border			= { 12, 2, 10, 2 }
@@ -1459,7 +1459,7 @@ style "scrollbar" = "default"
  image 
     {
       function			= STEPPER
-      recolorable		= TRUE
+      recolorable		= FALSE
       state				= ACTIVE
       file				= "screw1.png"
       #border			= { 12, 2, 10, 2 }
@@ -1469,7 +1469,7 @@ style "scrollbar" = "default"
  image 
     {
       function			= STEPPER
-      recolorable		= TRUE
+      recolorable		= FALSE
       state				= INSENSITIVE
       file				= "screw1.png"
       #border			= { 12, 2, 10, 2 }
@@ -1482,7 +1482,7 @@ style "scrollbar" = "default"
     image 
     {
       function			= STEPPER
-      recolorable		= TRUE
+      recolorable		= FALSE
       state				= NORMAL
       file				= "screw2.png"
       #border			= { 2, 9, 2, 13 }
@@ -1492,7 +1492,7 @@ style "scrollbar" = "default"
  image 
     {
       function			= STEPPER
-      recolorable		= TRUE
+      recolorable		= FALSE
       state				= PRELIGHT
       file				= "screw2.png"
       #border			= { 2, 9, 2, 13 }
@@ -1502,7 +1502,7 @@ style "scrollbar" = "default"
  image 
     {
       function			= STEPPER
-      recolorable		= TRUE
+      recolorable		= FALSE
       state				= ACTIVE
       file				= "screw2.png"
       #border			= { 2, 9, 2, 13 }
@@ -1512,7 +1512,7 @@ style "scrollbar" = "default"
  image 
     {
       function			= STEPPER
-      recolorable		= TRUE
+      recolorable		= FALSE
       state				= INSENSITIVE
       file				= "screw2.png"
       #border			= { 2, 9, 2, 13 }
@@ -1526,7 +1526,7 @@ style "scrollbar" = "default"
     image 
     {
       function			= STEPPER
-      recolorable		= TRUE
+      recolorable		= FALSE
       state				= NORMAL
       file				= "screw1.png"
       #border			= { 2, 9, 2, 13 }
@@ -1536,7 +1536,7 @@ style "scrollbar" = "default"
   image 
     {
       function			= STEPPER
-      recolorable		= TRUE
+      recolorable		= FALSE
       state				= PRELIGHT
       file				= "screw1.png"
       #border			= { 2, 9, 2, 13 }
@@ -1546,7 +1546,7 @@ style "scrollbar" = "default"
   image 
     {
       function			= STEPPER
-      recolorable		= TRUE
+      recolorable		= FALSE
       state				= ACTIVE
       file				= "screw1.png"
       #border			= { 2, 9, 2, 13 }
@@ -1556,7 +1556,7 @@ style "scrollbar" = "default"
   image 
     {
       function			= STEPPER
-      recolorable		= TRUE
+      recolorable		= FALSE
       state				= INSENSITIVE
       file				= "screw1.png"
       #border			= { 2, 9, 2, 13 }
diff --git a/gui/gui-compressor.xml b/gui/gui-compressor.xml
index 30bef42..0f9cdcc 100644
--- a/gui/gui-compressor.xml
+++ b/gui/gui-compressor.xml
@@ -1,97 +1,97 @@
-<table rows="2" cols="4" spacing="10">
-    <vbox attach-x="0" attach-y="0" expand="0" fill="0" pad-x="7" pad-y="7" spacing="3" >
-        <label param="bypass" expand="0" fill="0" />
-        <align><toggle param="bypass" shrink="1" size="2"/></align>
+<hbox spacing="10">
+
+    <vbox spacing="20" expand="0" fill="0">
+        <vbox attach-x="0" attach-y="0" expand="0" fill="0" pad-x="7" pad-y="7" spacing="7" >
+            <label param="bypass" expand="0" fill="0" />
+            <align><toggle param="bypass" shrink="1" size="2"/></align>
+        </vbox>
+        <vbox attach-x="0" attach-y="1" expand="0" fill="0" pad-y="20" pad-x="7">
+            <label param="level_in" expand="0" fill="0" expand-y="0" fill-y="0" />
+            <knob param="level_in" size="5" expand="1" fill="1" />
+            <value param="level_in" />
+        </vbox>
     </vbox>
-    <vbox attach-x="0" attach-y="1" expand="0" fill="0" pad-y="20" pad-x="7">
-        <label param="input" expand="0" fill="0" expand-y="0" fill-y="0" />
-        <knob param="input" size="4" expand="1" fill="1" />
-        <value param="input" />
+
+    <vbox spacing="5">
+        <frame label="Compressor">
+            <vbox spacing="5">
+                <table expand="0" fill="0" rows="3" cols="3">
+                    <label param="meter_in" expand-x="0" fill-x="0" attach-x="0" attach-y="0" />
+                    <vumeter param="meter_in" mode="0" hold="1.5" falloff="2.5" attach-x="1" attach-y="0" expand-x="1" fill-x="1" />
+                    <led param="clip_in" mode="0" expand-x="0" fill-x="0" attach-x="2" attach-y="0" />
+                    
+                    <label param="meter_out" expand-x="0" fill-x="0" attach-x="0" attach-y="1" />
+                    <vumeter param="meter_out" mode="0" hold="1.5" falloff="2.5" attach-x="1" attach-y="1" expand-x="1" fill-x="1" />
+                    <led param="clip_out" mode="1" expand-x="0" fill-x="0" attach-x="2" attach-y="1" />
+                    
+                    <label param="compression" expand-x="0" fill-x="0" attach-x="0" attach-y="2" />
+                    <vumeter param="compression" mode="2" hold="1.5" expand-x="1" fill-x="1" attach-x="1" attach-y="2" attach-w="2" />
+                </table>
+                
+                <table expand="1" rows="2" cols="3" homogeneous="1">
+                    <vbox expand="0" attach-x="0" attach-y="0">
+                        <label param="attack" />
+                        <knob param="attack" />
+                        <value param="attack" />
+                    </vbox>
+                    <vbox expand="0" attach-x="1" attach-y="0">
+                        <label param="release" />
+                        <knob param="release" />
+                        <value param="release" />
+                    </vbox>
+                    <vbox expand="0" attach-x="2" attach-y="0">
+                        <label param="knee" />
+                        <knob param="knee" />
+                        <value param="knee" />
+                    </vbox>
+                    <vbox expand="0" attach-x="0" attach-y="1">
+                        <label param="ratio" />
+                        <knob param="ratio" />
+                        <value param="ratio" />
+                    </vbox>
+                    <vbox expand="0" attach-x="1" attach-y="1">
+                        <label param="threshold" />
+                        <knob param="threshold"/>
+                        <value param="threshold" />
+                    </vbox>
+                    <vbox expand="0" attach-x="2" attach-y="1">
+                        <label param="makeup" />
+                        <knob param="makeup" />
+                        <value param="makeup" />
+                    </vbox>
+                </table>
+            </vbox>
+        </frame>
+        <frame label="Options">
+            <vbox spacing="10" pad-x="5" fill-y="0" expand-y="0">
+                <vbox expand="1" expand-y="0" expand-x="1" fill-x="1">
+                    <label param="stereo_link" expand-y="0" fill-y="0"/>
+                    <align>
+                        <hbox expand="0" fill-y="0" expand-x="1" fill-x="1">
+                            <radio param="stereo_link" value="Average" expand-x="1" fill-x="1"/>
+                            <radio param="stereo_link" value="Maximum" expand-x="1" fill-x="1"/>
+                        </hbox>
+                    </align>
+                </vbox>
+                <vbox expand="1" expand-y="0">
+                    <label param="detection" expand-y="0" fill-y="0" expand-x="1" fill-x="1"/>
+                    <align>
+                        <hbox expand="0" fill-y="0" expand-x="1" fill-x="1" >
+                            <radio param="detection" value="RMS" expand-x="1" fill-x="1"/>
+                            <radio param="detection" value="Peak" expand-x="1" fill-x="1"/>
+                        </hbox>
+                    </align>
+                </vbox>
+            </vbox>
+        </frame>
     </vbox>
     
-    <table attach-x="1" attach-y="0" expand-y="0" fill-y="0" expand-x="1" spacing="1" rows="3" cols="2">
-        <vbox expand-x="1" fill-x="1"  expand="0" fill="0" attach-x="0" attach-y="0">
-            <label param="peak" />
-            <vumeter param="peak" mode="0" hold="1.5" falloff="2.5" shrink-y="0" />
-        </vbox>
-        <vbox shrink-x="1" expand-x="0" fill-x="0" expand-y="0" fill-y="0" expand="0" fill="0" attach-x="1" attach-y="0">
-            <label param="clip" expand="0" fill="0" />
-            <led param="clip" mode="1" expand="0" fill="0" />
-        </vbox>
-        <vumeter param="compression" mode="2" hold="1.5" attach-x="0" attach-y="1" attach-w="2" expand="0" fill="0" expand-x="1" fill-x="1"/>
-        <label param="compression" attach-y="2" attach-x="0" expand-x="1" fill-x="1" expand="0" fill="0" />
-    </table>
     
-    <table attach-x="1" attach-y="1" expand="1" rows="2" cols="3" homogeneous="1" pad-x="0" pad-y="6">
-        <vbox expand="0" attach-x="0" attach-y="0">
-            <label param="attack" />
-            <knob param="attack" />
-            <value param="attack" />
-        </vbox>
-        <vbox expand="0" attach-x="1" attach-y="0">
-            <label param="release" />
-            <knob param="release" />
-            <value param="release" />
-        </vbox>
-        <vbox expand="0" attach-x="2" attach-y="0">
-            <label param="knee" />
-            <knob param="knee" />
-            <value param="knee" />
-        </vbox>
-        <vbox expand="0" attach-x="0" attach-y="1">
-            <label param="ratio" />
-            <knob param="ratio" />
-            <value param="ratio" />
+      <frame label="Compression">
+        <vbox >
+            <if cond="directlink">
+                <line-graph refresh="1" width="340" height="340" param="compression" square="1" expand="1" fill="1"/>
+            </if>
         </vbox>
-        <vbox expand="0" attach-x="1" attach-y="1">
-            <label param="threshold" />
-            <knob param="threshold"/>
-            <value param="threshold" />
-        </vbox>
-        <vbox expand="0" attach-x="2" attach-y="1">
-            <label param="makeup" />
-            <knob param="makeup" />
-            <value param="makeup" />
-        </vbox>
-    </table>
-    
-    <if cond="directlink">
-      <frame attach-x="2" attach-y="0" attach-h="2" label="Compression" pad-x="10">
-        <line-graph refresh="1" width="220" height="220" param="compression" square="1" expand-y="1" fill-y="1"/>
       </frame>
-    </if>
-    
-    <frame attach-x="3" attach-y="0" attach-h="2" label="Options">
-      <vbox>
-      <vbox expand="1" pad-x="5">
-          <vbox expand="0">
-              <label param="aweighting"/>
-              <align>
-                  <combo param="aweighting"/>
-              </align>
-          </vbox>
-      </vbox>
-      <vbox spacing="10" pad-x="5" fill-y="0" expand-y="0">
-    	  <vbox expand="1" expand-y="0" expand-x="1" fill-x="1">
-            <label param="stereo_link" expand-y="0" fill-y="0"/>
-            <align>
-                <hbox expand="0" fill-y="0" expand-x="1" fill-x="1">
-                    <radio param="stereo_link" value="Average" expand-x="1" fill-x="1"/>
-                    <radio param="stereo_link" value="Maximum" expand-x="1" fill-x="1"/>
-                </hbox>
-            </align>
-        </vbox>
-        <vbox expand="1" expand-y="0">
-        	<label param="detection" expand-y="0" fill-y="0" expand-x="1" fill-x="1"/>
-            <align>
-                <hbox expand="0" fill-y="0" expand-x="1" fill-x="1" >
-                    <radio param="detection" value="RMS" expand-x="1" fill-x="1"/>
-                    <radio param="detection" value="Peak" expand-x="1" fill-x="1"/>
-                </hbox>
-            </align>
-        </vbox>
-      </vbox>
-      </vbox>
-    </frame>
-    
-</table>
+</hbox>
diff --git a/gui/gui-deesser.xml b/gui/gui-deesser.xml
index 621d623..59ba5ee 100644
--- a/gui/gui-deesser.xml
+++ b/gui/gui-deesser.xml
@@ -67,7 +67,7 @@
                 </vbox>
                 <vbox fill="0" expand="0">
                     <label param="f1_level" />
-                    <knob param="f1_level" />
+                    <knob param="f1_level" type="1" />
                     <value param="f1_level" />
                 </vbox>
                 <vbox fill="0" expand="0">
@@ -77,7 +77,7 @@
                 </vbox>
                 <vbox fill="0" expand="0">
                     <label param="f2_level" />
-                    <knob param="f2_level" />
+                    <knob param="f2_level" type="1" />
                     <value param="f2_level" />
                 </vbox>
                 <vbox fill="0" expand="0">
diff --git a/gui/gui-enhancer.xml b/gui/gui-enhancer.xml
new file mode 100644
index 0000000..20695ae
--- /dev/null
+++ b/gui/gui-enhancer.xml
@@ -0,0 +1,57 @@
+<vbox spacing="10">
+    <table rows="4" cols="7">
+        <label param="bypass" attach-x="0" attach-y="0" expand-x="0" fill-x="0" />
+        <toggle param="bypass" attach-x="0" attach-y="1" attach-h="2" expand-x="0" fill-x="0" />
+        
+        <label param="level_in" attach-x="1" attach-y="0" expand-x="0" fill-x="0" />
+        <knob param="level_in" attach-x="1" attach-y="1" attach-h="2" expand-x="0" fill-x="0" />
+        <value param="level_in" attach-x="1" attach-y="3" expand-x="0" fill-x="0" />
+        
+        <label param="meter_in" attach-x="2" attach-y="0" expand-x="1" fill-x="1" />
+        <vumeter param="meter_in" hold="1.5" falloff="2.5" attach-x="2" attach-y="1" expand-x="1" fill-x="1" />
+        <vumeter param="meter_out" hold="1.5" falloff="2.5" attach-x="2" attach-y="2" expand-x="1" fill-x="1" />
+        <label param="meter_out" attach-x="2" attach-y="3" expand-x="1" fill-x="1" />
+        
+        <label param="clip_in" attach-x="3" attach-y="0" expand-x="0" fill-x="0" />
+        <led param="clip_in" attach-x="3" attach-y="1" expand-x="0" fill-x="0" />
+        <led param="clip_out" mode="1" attach-x="3" attach-y="2" expand-x="0" fill-x="0" />
+        <label param="clip_out" attach-x="3" attach-y="3" expand-x="0" fill-x="0" />
+        
+        <label param="amount" attach-x="4" attach-y="0" expand-x="0" fill-x="0" />
+        <knob param="amount" attach-x="4" attach-y="1" attach-h="2" expand-x="0" fill-x="0" />
+        <value param="amount" attach-x="4" attach-y="3" expand-x="0" fill-x="0" />
+        
+        <label param="level_out" attach-x="5" attach-y="0" expand-x="0" fill-x="0" />
+        <knob param="level_out" attach-x="5" attach-y="1" attach-h="2" expand-x="0" fill-x="0" />
+        <value param="level_out" attach-x="5" attach-y="3" expand-x="0" fill-x="0" />
+        
+        <label param="listen" attach-x="6" attach-y="0" expand-x="0" fill-x="0" />
+        <toggle param="listen" attach-x="6" attach-y="1" attach-h="2" expand-x="0" fill-x="0" />
+    </table>
+    <frame label="Enhancer">
+        <hbox spacing="25">
+            <vbox>
+                <label param="drive" />
+                <knob param="drive" size="5" />
+                <value param="drive" />
+            </vbox>
+            
+            <vbox spacing="5">
+                <label param="blend" />
+                <hscale param="blend" />
+                <hbox>
+                    <label align-x="0.0" text="2nd" />
+                    <label align-x="1.0" text="3rd" />
+                </hbox>
+                <label param="meter_drive" />
+                <vumeter param="meter_drive" hold="1.5" falloff="2.5" />
+            </vbox>
+            
+            <vbox>
+                <label param="freq" />
+                <knob param="freq" size="5" />
+                <value param="freq" />
+            </vbox>
+        </hbox>
+    </frame>
+</vbox>
diff --git a/gui/gui-equalizer12band.xml b/gui/gui-equalizer12band.xml
index 7ac8380..5d8cc37 100644
--- a/gui/gui-equalizer12band.xml
+++ b/gui/gui-equalizer12band.xml
@@ -53,7 +53,7 @@
                 </vbox>
                 <vbox attach-x="0" attach-y="1">
                     <label param="ls_level" />
-                    <knob param="ls_level" />
+                    <knob param="ls_level" type="1" />
                     <value param="ls_level" />
                 </vbox>
                 <vbox attach-x="0" attach-y="2">
@@ -91,7 +91,7 @@
                 <value param="p1_freq" />
             </vbox>
             <vbox attach-x="1" attach-y="2">
-                <knob param="p1_level" />
+                <knob param="p1_level" type="1" />
                 <value param="p1_level" />
             </vbox>
             <vbox attach-x="1" attach-y="3">
@@ -106,7 +106,7 @@
                 <value param="p2_freq" />
             </vbox>
             <vbox attach-x="2" attach-y="2">
-                <knob param="p2_level" />
+                <knob param="p2_level" type="1" />
                 <value param="p2_level" />
             </vbox>
             <vbox attach-x="2" attach-y="3">
@@ -121,7 +121,7 @@
                 <value param="p3_freq" />
             </vbox>
             <vbox attach-x="3" attach-y="2">
-                <knob param="p3_level" />
+                <knob param="p3_level" type="1" />
                 <value param="p3_level" />
             </vbox>
             <vbox attach-x="3" attach-y="3">
@@ -136,7 +136,7 @@
                 <value param="p4_freq" />
             </vbox>
             <vbox attach-x="4" attach-y="2">
-                <knob param="p4_level" />
+                <knob param="p4_level" type="1" />
                 <value param="p4_level" />
             </vbox>
             <vbox attach-x="4" attach-y="3">
@@ -151,7 +151,7 @@
                 <value param="p5_freq" />
             </vbox>
             <vbox attach-x="5" attach-y="2">
-                <knob param="p5_level" />
+                <knob param="p5_level" type="1" />
                 <value param="p5_level" />
             </vbox>
             <vbox attach-x="5" attach-y="3">
@@ -166,7 +166,7 @@
                 <value param="p6_freq" />
             </vbox>
             <vbox attach-x="6" attach-y="2">
-                <knob param="p6_level" />
+                <knob param="p6_level" type="1" />
                 <value param="p6_level" />
             </vbox>
             <vbox attach-x="6" attach-y="3">
@@ -181,7 +181,7 @@
                 <value param="p7_freq" />
             </vbox>
             <vbox attach-x="7" attach-y="2">
-                <knob param="p7_level" />
+                <knob param="p7_level" type="1" />
                 <value param="p7_level" />
             </vbox>
             <vbox attach-x="7" attach-y="3">
@@ -196,7 +196,7 @@
                 <value param="p8_freq" />
             </vbox>
             <vbox attach-x="8" attach-y="2">
-                <knob param="p8_level" />
+                <knob param="p8_level" type="1" />
                 <value param="p8_level" />
             </vbox>
             <vbox attach-x="8" attach-y="3">
@@ -258,7 +258,7 @@
                 </vbox>
                 <vbox attach-x="0" attach-y="1">
                     <label param="hs_level" />
-                    <knob param="hs_level" />
+                    <knob param="hs_level" type="1" />
                     <value param="hs_level" />
                 </vbox>
                 <vbox attach-x="0" attach-y="2">
diff --git a/gui/gui-equalizer5band.xml b/gui/gui-equalizer5band.xml
index 4d41df9..862f6cc 100644
--- a/gui/gui-equalizer5band.xml
+++ b/gui/gui-equalizer5band.xml
@@ -30,7 +30,7 @@
                 </vbox>
                 <vbox attach-x="1" attach-y="0">
                     <label param="ls_level" />
-                    <knob param="ls_level" />
+                    <knob param="ls_level" type="1" />
                     <value param="ls_level" />
                 </vbox>
                 <vbox attach-x="1" attach-y="1" fill-y="0">
@@ -57,7 +57,7 @@
                 </vbox>
                 <vbox attach-x="1" attach-y="0">
                     <label param="p1_level" />
-                    <knob param="p1_level" />
+                    <knob param="p1_level" type="1" />
                     <value param="p1_level" />
                 </vbox>
                 <vbox attach-x="0" attach-y="1">
@@ -80,7 +80,7 @@
                 </vbox>
                 <vbox attach-x="1" attach-y="0">
                     <label param="p2_level" />
-                    <knob param="p2_level" />
+                    <knob param="p2_level" type="1" />
                     <value param="p2_level" />
                 </vbox>
                 <vbox attach-x="0" attach-y="1">
@@ -103,7 +103,7 @@
                 </vbox>
                 <vbox attach-x="1" attach-y="0">
                     <label param="p3_level" />
-                    <knob param="p3_level" />
+                    <knob param="p3_level" type="1" />
                     <value param="p3_level" />
                 </vbox>
                 <vbox attach-x="0" attach-y="1">
@@ -146,7 +146,7 @@
                 </vbox>
                 <vbox attach-x="1" attach-y="0">
                     <label param="hs_level" />
-                    <knob param="hs_level" />
+                    <knob param="hs_level" type="1" />
                     <value param="hs_level" />
                 </vbox>
                 <vbox attach-x="1" attach-y="1" fill-y="0">
diff --git a/gui/gui-equalizer8band.xml b/gui/gui-equalizer8band.xml
index 0091d8d..ce44d78 100644
--- a/gui/gui-equalizer8band.xml
+++ b/gui/gui-equalizer8band.xml
@@ -53,7 +53,7 @@
                 </vbox>
                 <vbox attach-x="0" attach-y="1">
                     <label param="ls_level" />
-                    <knob param="ls_level" />
+                    <knob param="ls_level" type="1" />
                     <value param="ls_level" />
                 </vbox>
                 <vbox attach-x="0" attach-y="2">
@@ -87,7 +87,7 @@
                 <value param="p1_freq" />
             </vbox>
             <vbox attach-x="1" attach-y="2">
-                <knob param="p1_level" />
+                <knob param="p1_level" type="1" />
                 <value param="p1_level" />
             </vbox>
             <vbox attach-x="1" attach-y="3">
@@ -102,7 +102,7 @@
                 <value param="p2_freq" />
             </vbox>
             <vbox attach-x="2" attach-y="2">
-                <knob param="p2_level" />
+                <knob param="p2_level" type="1" />
                 <value param="p2_level" />
             </vbox>
             <vbox attach-x="2" attach-y="3">
@@ -117,7 +117,7 @@
                 <value param="p3_freq" />
             </vbox>
             <vbox attach-x="3" attach-y="2">
-                <knob param="p3_level" />
+                <knob param="p3_level" type="1" />
                 <value param="p3_level" />
             </vbox>
             <vbox attach-x="3" attach-y="3">
@@ -132,7 +132,7 @@
                 <value param="p4_freq" />
             </vbox>
             <vbox attach-x="4" attach-y="2">
-                <knob param="p4_level" />
+                <knob param="p4_level" type="1" />
                 <value param="p4_level" />
             </vbox>
             <vbox attach-x="4" attach-y="3">
@@ -194,7 +194,7 @@
                 </vbox>
                 <vbox attach-x="0" attach-y="1">
                     <label param="hs_level" />
-                    <knob param="hs_level" />
+                    <knob param="hs_level" type="1" />
                     <value param="hs_level" />
                 </vbox>
                 <vbox attach-x="0" attach-y="2">
diff --git a/gui/gui-saturator.xml b/gui/gui-saturator.xml
new file mode 100644
index 0000000..a995233
--- /dev/null
+++ b/gui/gui-saturator.xml
@@ -0,0 +1,104 @@
+<vbox>
+    <hbox spacing="20">
+        <table rows="7" cols="5">
+            <label param="bypass" attach-x="0" attach-y="0" expand-x="0" fill-x="0" />
+            <toggle param="bypass" attach-x="0" attach-y="1" attach-h="2" expand-x="0" fill-x="0" />
+            
+            <label param="level_in" attach-x="1" attach-y="0" expand-x="0" fill-x="0" />
+            <knob param="level_in" attach-x="1" attach-y="1" attach-h="2" expand-x="0" fill-x="0" />
+            <value param="level_in" attach-x="1" attach-y="3" expand-x="0" fill-x="0" />
+            
+            <label param="meter_in" attach-x="2" attach-y="0" expand-x="1" fill-x="1" />
+            <vumeter param="meter_in" hold="1.5" falloff="2.5" attach-x="2" attach-y="1" expand-x="1" fill-x="1" />
+            <vumeter param="meter_out" hold="1.5" falloff="2.5" attach-x="2" attach-y="2" expand-x="1" fill-x="1" />
+            <label param="meter_out" attach-x="2" attach-y="3" expand-x="1" fill-x="1" />
+            
+            <label param="clip_in" attach-x="3" attach-y="0" expand-x="0" fill-x="0" />
+            <led param="clip_in" attach-x="3" attach-y="1" expand-x="0" fill-x="0" />
+            <led param="clip_out" mode="1" attach-x="3" attach-y="2" expand-x="0" fill-x="0" />
+            <label param="clip_out" attach-x="3" attach-y="3" expand-x="0" fill-x="0" />
+            
+            <label param="level_out" attach-x="4" attach-y="0" expand-x="0" fill-x="0" />
+            <knob param="level_out" attach-x="4" attach-y="1" attach-h="2" expand-x="0" fill-x="0" />
+            <value param="level_out" attach-x="4" attach-y="3" expand-x="0" fill-x="0" />
+            
+            <hbox attach-x="0" attach-y="4" attach-h="3" attach-w="4">
+                <label text="Tape" />
+                <hscale param="blend" />
+                <label text="Tube" />
+            </hbox>
+            
+            <label param="mix" attach-x="4" attach-y="4" expand-x="0" fill-x="0" />
+            <knob param="mix" attach-x="4" attach-y="5" expand-x="0" fill-x="0" />
+            <value param="mix" attach-x="4" attach-y="6" expand-x="0" fill-x="0" />
+            
+        </table>
+        <hbox spacing="30" expand="0" fill="0">
+            <vbox>
+                <label />
+                <vbox spacing="5" expand="0">
+                    <label param="drive" />
+                    <knob param="drive" size="5" />
+                    <value param="drive" />
+                </vbox>
+                <label />
+            </vbox>
+            <vbox expand="0" fill="0">
+                <label />
+                <tube param="meter_drive" size="2" direction="2" expand="0" fill="0" />
+                <label />
+            </vbox>
+        </hbox>
+    </hbox>
+
+    <hbox spacing="8">
+        <frame label="Pre">
+            <hbox homogeneous="1">
+                <vbox>
+                    <label param="hp_pre_freq" />
+                    <knob param="hp_pre_freq" />
+                    <value param="hp_pre_freq" />
+                </vbox>
+                <vbox>
+                    <label param="lp_pre_freq" />
+                    <knob param="lp_pre_freq" />
+                    <value param="lp_pre_freq" />
+                </vbox>
+            </hbox>
+        </frame>
+        <frame label="Tone">
+            <hbox homogeneous="1">
+                <vbox>
+                    <label param="p_freq" attach-x="0" attach-y="0" />
+                    <knob param="p_freq" attach-x="1" attach-y="0" />
+                    <value param="p_freq" attach-x="2" attach-y="0" />
+                </vbox>
+                <vbox>
+                    <label param="p_level" attach-x="0" attach-y="1" />
+                    <knob param="p_level" attach-x="1" attach-y="0" type="1" />
+                    <value param="p_level" attach-x="2" attach-y="1" />
+                </vbox>
+                <vbox>
+                    <label param="p_q" attach-x="0" attach-y="2" />
+                    <knob param="p_q" attach-x="1" attach-y="2" />
+                    <value param="p_q" attach-x="2" attach-y="2" />
+                </vbox>
+            </hbox>
+        </frame>
+        <frame label="Post">
+            <hbox homogeneous="1">
+                <vbox>
+                    <label param="hp_post_freq" />
+                    <knob param="hp_post_freq" />
+                    <value param="hp_post_freq" />
+                </vbox>
+                <vbox>
+                    <label param="lp_post_freq" />
+                    <knob param="lp_post_freq" />
+                    <value param="lp_post_freq" />
+                </vbox>
+            </hbox>
+        </frame>
+    </hbox>
+</vbox>
+        
diff --git a/gui/gui-sidechaincompressor.xml b/gui/gui-sidechaincompressor.xml
index c9ba341..eb72b55 100644
--- a/gui/gui-sidechaincompressor.xml
+++ b/gui/gui-sidechaincompressor.xml
@@ -127,7 +127,7 @@
                         </vbox>
                         <vbox>
                             <label param="f1_level" />
-                            <knob param="f1_level" size="2" />
+                            <knob param="f1_level" type="1" size="2" />
                             <value param="f1_level" />
                         </vbox>
                     </hbox>
@@ -148,7 +148,7 @@
                         </vbox>
                         <vbox>
                             <label param="f2_level" />
-                            <knob param="f2_level" size="2" />
+                            <knob param="f2_level" type="1" size="2" />
                             <value param="f2_level" />
                         </vbox>
                     </hbox>
diff --git a/gui/tubeH1.png b/gui/tubeH1.png
index c215797..343e7c4 100644
Binary files a/gui/tubeH1.png and b/gui/tubeH1.png differ
diff --git a/gui/tubeH2.png b/gui/tubeH2.png
index 1b646c4..69d6e41 100644
Binary files a/gui/tubeH2.png and b/gui/tubeH2.png differ
diff --git a/gui/tubeV1.png b/gui/tubeV1.png
index 13219ca..ed4de66 100644
Binary files a/gui/tubeV1.png and b/gui/tubeV1.png differ
diff --git a/gui/tubeV2.png b/gui/tubeV2.png
index 71e00ad..a178395 100644
Binary files a/gui/tubeV2.png and b/gui/tubeV2.png differ
diff --git a/src/benchmark.cpp b/src/benchmark.cpp
index ffaa1ad..64c0ff1 100644
--- a/src/benchmark.cpp
+++ b/src/benchmark.cpp
@@ -297,7 +297,6 @@ void get_default_effect_params<calf_plugins::compressor_audio_module>(float para
     params[mod::param_detection] = 0;
     params[mod::param_knee] = 40000;
     params[mod::param_bypass] = 0;
-    params[mod::param_aweighting] = 1;
     sr = 44100;
 }
 
diff --git a/src/calf/giface.h b/src/calf/giface.h
index 56305bc..92cb1f9 100644
--- a/src/calf/giface.h
+++ b/src/calf/giface.h
@@ -306,6 +306,10 @@ struct plugin_metadata_iface
     virtual int get_input_count()=0;
     /// @return number of audio outputs
     virtual int get_output_count()=0;
+    /// @return number of optional inputs
+    virtual int get_inputs_optional()=0;
+    /// @return number of optional outputs
+    virtual int get_outputs_optional()=0;
     /// @return true if plugin can work in hard-realtime conditions
     virtual bool is_rt_capable()=0;
     /// @return true if plugin has MIDI input
@@ -489,6 +493,8 @@ public:
     const char *get_label() { return Metadata::impl_get_label(); } 
     int get_input_count() { return Metadata::in_count; }
     int get_output_count() { return Metadata::out_count; }
+    int get_inputs_optional() { return Metadata::ins_optional; }
+    int get_outputs_optional() { return Metadata::outs_optional; }
     int get_param_count() { return Metadata::param_count; }
     bool get_midi() { return Metadata::support_midi; }
     bool requires_midi() { return Metadata::require_midi; }
@@ -528,6 +534,8 @@ public:
     const char *get_label() { return impl->get_label(); } 
     int get_input_count() { return impl->get_input_count(); }
     int get_output_count() { return impl->get_output_count(); }
+    int get_inputs_optional() { return impl->get_inputs_optional(); }
+    int get_outputs_optional() { return impl->get_outputs_optional(); }
     int get_param_count() { return impl->get_param_count(); }
     bool get_midi() { return impl->get_midi(); }
     bool requires_midi() { return impl->requires_midi(); }
diff --git a/src/calf/metadata.h b/src/calf/metadata.h
index c959e19..6eb4887 100644
--- a/src/calf/metadata.h
+++ b/src/calf/metadata.h
@@ -31,21 +31,21 @@ struct flanger_metadata: public plugin_metadata<flanger_metadata>
 {
 public:
     enum { par_delay, par_depth, par_rate, par_fb, par_stereo, par_reset, par_amount, par_dryamount, param_count };
-    enum { in_count = 2, out_count = 2, support_midi = false, require_midi = false, rt_capable = true };
+    enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true };
     PLUGIN_NAME_ID_LABEL("flanger", "flanger", "Flanger")
 };
 
 struct phaser_metadata: public plugin_metadata<phaser_metadata>
 {
     enum { par_freq, par_depth, par_rate, par_fb, par_stages, par_stereo, par_reset, par_amount, par_dryamount, param_count };
-    enum { in_count = 2, out_count = 2, support_midi = false, require_midi = false, rt_capable = true };
+    enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true };
     PLUGIN_NAME_ID_LABEL("phaser", "phaser", "Phaser")
 };
 
 struct filter_metadata: public plugin_metadata<filter_metadata>
 {
     enum { par_cutoff, par_resonance, par_mode, par_inertia, param_count };
-    enum { in_count = 2, out_count = 2, rt_capable = true, require_midi = false, support_midi = false };
+    enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, rt_capable = true, require_midi = false, support_midi = false };
     PLUGIN_NAME_ID_LABEL("filter", "filter", "Filter")
     /// do not export mode and inertia as CVs, as those are settings and not parameters
     bool is_cv(int param_no) { return param_no != par_mode && param_no != par_inertia; }
@@ -55,7 +55,7 @@ struct filter_metadata: public plugin_metadata<filter_metadata>
 struct filterclavier_metadata: public plugin_metadata<filterclavier_metadata>
 {
     enum { par_transpose, par_detune, par_max_resonance, par_mode, par_inertia,  param_count };
-    enum { in_count = 2, out_count = 2, rt_capable = true, require_midi = true, support_midi = true };
+    enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, rt_capable = true, require_midi = true, support_midi = true };
     PLUGIN_NAME_ID_LABEL("filterclavier", "filterclavier", "Filterclavier")
     /// do not export mode and inertia as CVs, as those are settings and not parameters
     bool is_cv(int param_no) { return param_no != par_mode && param_no != par_inertia; }
@@ -64,14 +64,14 @@ struct filterclavier_metadata: public plugin_metadata<filterclavier_metadata>
 struct reverb_metadata: public plugin_metadata<reverb_metadata>
 {
     enum { par_clip, par_meter_wet, par_meter_out, par_decay, par_hfdamp, par_roomsize, par_diffusion, par_amount, par_dry, par_predelay, par_basscut, par_treblecut, param_count };
-    enum { in_count = 2, out_count = 2, support_midi = false, require_midi = false, rt_capable = true };
+    enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true };
     PLUGIN_NAME_ID_LABEL("reverb", "reverb", "Reverb")
 };
 
 struct vintage_delay_metadata: public plugin_metadata<vintage_delay_metadata>
 {
     enum { par_bpm, par_divide, par_time_l, par_time_r, par_feedback, par_amount, par_mixmode, par_medium, par_dryamount, param_count };
-    enum { in_count = 2, out_count = 2, rt_capable = true, support_midi = false, require_midi = false };
+    enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, rt_capable = true, support_midi = false, require_midi = false };
     PLUGIN_NAME_ID_LABEL("vintage_delay", "vintagedelay", "Vintage Delay")
 };
 
@@ -79,7 +79,7 @@ struct rotary_speaker_metadata: public plugin_metadata<rotary_speaker_metadata>
 {
 public:
     enum { par_speed, par_spacing, par_shift, par_moddepth, par_treblespeed, par_bassspeed, par_micdistance, par_reflection, par_meter_l, par_meter_h, param_count };
-    enum { in_count = 2, out_count = 2, support_midi = true, require_midi = false, rt_capable = true };
+    enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = true, require_midi = false, rt_capable = true };
     PLUGIN_NAME_ID_LABEL("rotary_speaker", "rotaryspeaker", "Rotary Speaker")
 };
 
@@ -88,7 +88,7 @@ struct multichorus_metadata: public plugin_metadata<multichorus_metadata>
 {
 public:    
     enum { par_delay, par_depth, par_rate, par_stereo, par_voices, par_vphase, par_amount, par_dryamount, par_freq, par_freq2, par_q, par_overlap, param_count };
-    enum { in_count = 2, out_count = 2, rt_capable = true, support_midi = false, require_midi = false };
+    enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, rt_capable = true, support_midi = false, require_midi = false };
     PLUGIN_NAME_ID_LABEL("multichorus", "multichorus", "Multi Chorus")
 };
 
@@ -101,7 +101,7 @@ struct monosynth_metadata: public plugin_metadata<monosynth_metadata>
         par_keyfollow, par_legato, par_portamento, par_vel2filter, par_vel2amp, par_master, par_pwhlrange, 
         par_lforate, par_lfodelay, par_lfofilter, par_lfopitch, par_lfopw, par_mwhl_lfo, par_scaledetune,
         param_count };
-    enum { in_count = 0, out_count = 2, support_midi = true, require_midi = true, rt_capable = true };
+    enum { in_count = 0, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = true, require_midi = true, rt_capable = true };
     enum { step_size = 64, step_shift = 6 };
     enum {
         modsrc_none,
@@ -128,18 +128,20 @@ struct monosynth_metadata: public plugin_metadata<monosynth_metadata>
 };
 
 /// Thor's compressor - metadata
+/// Added some meters and stripped the weighting part
 struct compressor_metadata: public plugin_metadata<compressor_metadata>
 {
-    enum { in_count = 2, out_count = 2, support_midi = false, require_midi = false, rt_capable = true };
-    enum { param_threshold, param_ratio, param_attack, param_release, param_makeup, param_knee, param_detection, param_stereo_link, param_aweighting, param_compression, param_peak, param_clip, param_bypass, param_input,// param_freq, param_bw, 
-        param_count };
+    enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true };
+    enum { param_bypass, param_level_in, param_meter_in, param_meter_out, param_clip_in, param_clip_out,
+           param_threshold, param_ratio, param_attack, param_release, param_makeup, param_knee, param_detection, param_stereo_link, param_compression, 
+           param_count };
     PLUGIN_NAME_ID_LABEL("compressor", "compressor", "Compressor")
 };
 
 /// Markus's sidechain compressor - metadata
 struct sidechaincompressor_metadata: public plugin_metadata<sidechaincompressor_metadata>
 {
-    enum { in_count = 2, out_count = 2, support_midi = false, require_midi = false, rt_capable = true };
+    enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true };
     enum { param_bypass, param_level_in, param_meter_in, param_meter_out, param_clip_in, param_clip_out,
            param_threshold, param_ratio, param_attack, param_release, param_makeup, param_knee, param_detection, param_stereo_link, param_compression, 
            param_sc_mode, param_f1_freq, param_f2_freq, param_f1_level, param_f2_level,
@@ -150,7 +152,7 @@ struct sidechaincompressor_metadata: public plugin_metadata<sidechaincompressor_
 /// Markus's multibandcompressor - metadata
 struct multibandcompressor_metadata: public plugin_metadata<multibandcompressor_metadata>
 {
-    enum { in_count = 2, out_count = 2, support_midi = false, require_midi = false, rt_capable = true };
+    enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true };
     enum { param_bypass, param_level_in, param_level_out, param_meter_inL, param_meter_inR,
            param_meter_outL, param_meter_outR, param_clip_inL, param_clip_inR, param_clip_outL, param_clip_outR,
            param_freq0, param_freq1, param_freq2,
@@ -171,7 +173,7 @@ struct multibandcompressor_metadata: public plugin_metadata<multibandcompressor_
 /// Markus's deesser - metadata
 struct deesser_metadata: public plugin_metadata<deesser_metadata>
 {
-    enum { in_count = 2, out_count = 2, support_midi = false, require_midi = false, rt_capable = true };
+    enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true };
     enum { param_bypass, param_detected, param_compression, param_detected_led, param_clip_out,
            param_detection, param_mode,
            param_threshold, param_ratio, param_laxity, param_makeup,
@@ -183,7 +185,7 @@ struct deesser_metadata: public plugin_metadata<deesser_metadata>
 /// Markus's 5-band EQ - metadata
 struct equalizer5band_metadata: public plugin_metadata<equalizer5band_metadata>
 {
-    enum { in_count = 2, out_count = 2, support_midi = false, require_midi = false, rt_capable = true };
+    enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true };
     enum { param_bypass, param_level_in, param_level_out, param_meter_in,
            param_meter_out, param_clip_in, param_clip_out,
            param_ls_active, param_ls_level, param_ls_freq,
@@ -197,7 +199,7 @@ struct equalizer5band_metadata: public plugin_metadata<equalizer5band_metadata>
 /// Markus's 8-band EQ - metadata
 struct equalizer8band_metadata: public plugin_metadata<equalizer8band_metadata>
 {
-    enum { in_count = 2, out_count = 2, support_midi = false, require_midi = false, rt_capable = true };
+    enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true };
     enum { param_bypass, param_level_in, param_level_out, param_meter_inL, param_meter_inR,
            param_meter_outL, param_meter_outR, param_clip_inL, param_clip_inR, param_clip_outL, param_clip_outR,
            param_hp_active, param_hp_freq, param_hp_mode,
@@ -214,7 +216,7 @@ struct equalizer8band_metadata: public plugin_metadata<equalizer8band_metadata>
 /// Markus's 12-band EQ - metadata
 struct equalizer12band_metadata: public plugin_metadata<equalizer12band_metadata>
 {
-    enum { in_count = 2, out_count = 2, support_midi = false, require_midi = false, rt_capable = true };
+    enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true };
     enum { param_bypass, param_level_in, param_level_out, param_meter_inL, param_meter_inR,
            param_meter_outL, param_meter_outR, param_clip_inL, param_clip_inR, param_clip_outL, param_clip_outR,
            param_hp_active, param_hp_freq, param_hp_mode,
@@ -232,7 +234,25 @@ struct equalizer12band_metadata: public plugin_metadata<equalizer12band_metadata
            param_count };
     PLUGIN_NAME_ID_LABEL("equalizer12band", "equalizer12band", "Equalizer 12 Band")
 };
-
+/// Markus's Saturator - metadata
+struct saturator_metadata: public plugin_metadata<saturator_metadata>
+{
+    enum { in_count = 2, out_count = 2, ins_optional = 1, outs_optional = 1, support_midi = false, require_midi = false, rt_capable = true };
+    enum { param_bypass, param_level_in, param_level_out, param_mix, param_meter_in,
+           param_meter_out, param_clip_in, param_clip_out, param_drive, param_blend, param_meter_drive,
+           param_lp_pre_freq, param_hp_pre_freq, param_lp_post_freq, param_hp_post_freq,
+           param_p_freq, param_p_level, param_p_q, param_count };
+    PLUGIN_NAME_ID_LABEL("saturator", "saturator", "Saturator")
+};
+/// Markus's Enhancer - metadata
+struct enhancer_metadata: public plugin_metadata<enhancer_metadata>
+{
+    enum { in_count = 2, out_count = 2, ins_optional = 1, outs_optional = 1, support_midi = false, require_midi = false, rt_capable = true };
+    enum { param_bypass, param_level_in, param_level_out, param_amount, param_meter_in,
+           param_meter_out, param_clip_in, param_clip_out, param_drive, param_blend, param_meter_drive,
+           param_freq, param_listen, param_count };
+    PLUGIN_NAME_ID_LABEL("enhancer", "enhancer", "Enhancer")
+};
 /// Organ - enums for parameter IDs etc. (this mess is caused by organ split between plugin and generic class - which was
 /// a bad design decision and should be sorted out some day) XXXKF @todo
 struct organ_enums
@@ -319,7 +339,7 @@ struct organ_enums
 /// Organ - metadata
 struct organ_metadata: public organ_enums, public plugin_metadata<organ_metadata>
 {
-    enum { in_count = 0, out_count = 2, support_midi = true, require_midi = true, rt_capable = true };
+    enum { in_count = 0, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = true, require_midi = true, rt_capable = true };
     PLUGIN_NAME_ID_LABEL("organ", "organ", "Organ")
     plugin_command_info *get_commands();
     const char **get_default_configure_vars();
@@ -329,7 +349,7 @@ struct organ_metadata: public organ_enums, public plugin_metadata<organ_metadata
 struct fluidsynth_metadata: public plugin_metadata<fluidsynth_metadata>
 {
     enum { par_master, par_soundfont, par_interpolation, par_reverb, par_chorus, param_count };
-    enum { in_count = 0, out_count = 2, support_midi = true, require_midi = true, rt_capable = false };
+    enum { in_count = 0, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = true, require_midi = true, rt_capable = false };
     PLUGIN_NAME_ID_LABEL("fluidsynth", "fluidsynth", "Fluidsynth")
     const char **get_default_configure_vars();
 };
@@ -399,7 +419,7 @@ struct wavetable_metadata: public plugin_metadata<wavetable_metadata>
         par_eg3attack, par_eg3decay, par_eg3sustain, par_eg3fade, par_eg3release, par_eg3velscl,
         par_pwhlrange, 
         param_count };
-    enum { in_count = 0, out_count = 2, support_midi = true, require_midi = true, rt_capable = true };
+    enum { in_count = 0, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = true, require_midi = true, rt_capable = true };
     enum { step_size = 64 };
     PLUGIN_NAME_ID_LABEL("wavetable", "wavetable", "Wavetable")
 };
diff --git a/src/calf/modulelist.h b/src/calf/modulelist.h
index 83c123c..c9d36d1 100644
--- a/src/calf/modulelist.h
+++ b/src/calf/modulelist.h
@@ -16,6 +16,8 @@
     PER_MODULE_ITEM(equalizer5band, false, "equalizer5band")
     PER_MODULE_ITEM(equalizer8band, false, "equalizer8band")
     PER_MODULE_ITEM(equalizer12band, false, "equalizer12band")
+    PER_MODULE_ITEM(saturator, false, "saturator")
+    PER_MODULE_ITEM(enhancer, false, "enhancer")
 #ifdef ENABLE_EXPERIMENTAL
     PER_MODULE_ITEM(fluidsynth, true, "fluidsynth")
     PER_MODULE_ITEM(wavetable, true, "wavetable")
diff --git a/src/calf/modules.h b/src/calf/modules.h
index 1907572..e64b937 100644
--- a/src/calf/modules.h
+++ b/src/calf/modules.h
@@ -846,82 +846,6 @@ public:
     bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context);
 };
 
-class compressor_audio_module: public audio_module<compressor_metadata>, public line_graph_iface {
-private:
-    float linSlope, peak, detected, kneeSqrt, kneeStart, linKneeStart, kneeStop, threshold, ratio, knee, makeup, compressedKneeStop, adjKneeStart;
-    float old_threshold, old_ratio, old_knee, old_makeup, old_bypass;
-    int last_generation;
-    uint32_t clip;
-    aweighter awL, awR;
-    biquad_d2<float> bpL, bpR;
-public:
-    float *ins[in_count];
-    float *outs[out_count];
-    float *params[param_count];
-    uint32_t srate;
-    bool is_active;
-    compressor_audio_module();
-    void activate();
-    void deactivate();
-    uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask);
-    
-    inline float output_level(float slope) {
-        return slope * output_gain(slope, false) * makeup;
-    }
-    
-    inline float output_gain(float linSlope, bool rms) {
-         if(linSlope > (rms ? adjKneeStart : linKneeStart)) {
-            float slope = log(linSlope);
-            if(rms) slope *= 0.5f;
-
-            float gain = 0.f;
-            float delta = 0.f;
-            if(IS_FAKE_INFINITY(ratio)) {
-                gain = threshold;
-                delta = 0.f;
-            } else {
-                gain = (slope - threshold) / ratio + threshold;
-                delta = 1.f / ratio;
-            }
-            
-            if(knee > 1.f && slope < kneeStop) {
-                gain = hermite_interpolation(slope, kneeStart, kneeStop, kneeStart, compressedKneeStop, 1.f, delta);
-            }
-            
-            return exp(gain - slope);
-        }
-
-        return 1.f;
-    }
-
-    void set_sample_rate(uint32_t sr);
-    
-    virtual bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context);
-    virtual bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context);
-    virtual bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context);
-
-    virtual int  get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline)
-    {
-        subindex_graph = 0;
-        subindex_dot = 0;
-        subindex_gridline = generation ? INT_MAX : 0;
-
-        if (fabs(threshold-old_threshold) + fabs(ratio - old_ratio) + fabs(knee - old_knee) + fabs( makeup - old_makeup) + fabs( *params[param_bypass] - old_bypass) > 0.01f)
-        {
-            old_threshold = threshold;
-            old_ratio = ratio;
-            old_knee = knee;
-            old_makeup = makeup;
-            old_bypass = *params[param_bypass];
-            last_generation++;
-        }
-
-        if (generation == last_generation)
-            subindex_graph = 2;
-        return last_generation;
-    }
-};
-
 class gain_reduction_audio_module {
 private:
     float linSlope, detected, kneeSqrt, kneeStart, linKneeStart, kneeStop;
@@ -949,6 +873,32 @@ public:
     virtual int  get_changed_offsets(int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline);
 };
 
+/// Compressor by Thor
+class compressor_audio_module: public audio_module<compressor_metadata>, public line_graph_iface  {
+private:
+    uint32_t clip_in, clip_out;
+    float meter_in, meter_out;
+    gain_reduction_audio_module compressor;
+public:
+    typedef std::complex<double> cfloat;
+    float *ins[in_count];
+    float *outs[out_count];
+    float *params[param_count];
+    uint32_t srate;
+    bool is_active;
+    volatile int last_generation, last_calculated_generation;
+    compressor_audio_module();
+    void activate();
+    void deactivate();
+    void params_changed();
+    void set_sample_rate(uint32_t sr);
+    uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask);
+    bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context);
+    bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context);
+    bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context);
+    int  get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline);
+};
+
 /// Sidecain Compressor by Markus Schmidt (based on Thor's compressor and Krzysztof's filters)
 class sidechaincompressor_audio_module: public audio_module<sidechaincompressor_metadata>, public frequency_response_line_graph  {
 private:
@@ -1267,13 +1217,9 @@ public:
 /// Equalizer 5 Band by Markus Schmidt (based on Krzysztof's filters)
 class equalizer5band_audio_module: public audio_module<equalizer5band_metadata>, public frequency_response_line_graph  {
 private:
-    float hp_mode_old, hp_freq_old;
-    float lp_mode_old, lp_freq_old;
     float ls_level_old, ls_freq_old;
     float hs_level_old, hs_freq_old;
     float p_level_old[3], p_freq_old[3], p_q_old[3];
-    float hp_mode_old1, hp_freq_old1, hp_active_old1;
-    float lp_mode_old1, lp_freq_old1, lp_active_old1;
     float ls_level_old1, ls_freq_old1, ls_active_old1;
     float hs_level_old1, hs_freq_old1, hs_active_old1;
     float p_level_old1[3], p_freq_old1[3], p_q_old1[3], p_active_old1[3];
@@ -1310,6 +1256,93 @@ public:
     int  get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline);
 };
 
+class distortion_audio_module {
+private:
+    float blend_old, drive_old;
+    float meter;
+    float rdrive, rbdr, kpa, kpb, kna, knb, ap, an, imr, kc, srct, sq, pwrq;
+    float prev_med, prev_out;
+public:
+    uint32_t srate;
+    bool is_active;
+    distortion_audio_module();
+    void activate();
+    void deactivate();
+    void set_params(float blend, float drive);
+    void set_sample_rate(uint32_t sr);
+    float process(float in);
+    float get_distortion_level();
+    static inline float
+    // NOTICE!! These routines are implemented for testing purposes only!
+    // They're taken from TAP Plugins and will act as a placeholder until
+    // Krzysztof's distrotion routine is ready!
+    M(float x) {
+
+        if ((x > 0.000000001f) || (x < -0.000000001f))
+            return x;
+        else
+            return 0.0f;
+    }
+
+    static inline float
+    D(float x) {
+
+        if (x > 0.000000001f)
+            return sqrt(x);
+        else if (x < -0.000000001f)
+            return sqrt(-x);
+        else
+            return 0.0f;
+    }
+};
+
+/// Saturator by Markus Schmidt (based on Krzysztof's filters and distortion algorythm)
+class saturator_audio_module: public audio_module<saturator_metadata> {
+private:
+    float hp_pre_freq_old, lp_pre_freq_old;
+    float hp_post_freq_old, lp_post_freq_old;
+    float p_level_old, p_freq_old, p_q_old;
+    uint32_t clip_in, clip_out;
+    float meter_in, meter_out, meter_drive;
+    biquad_d2<float> lp[2][4], hp[2][4];
+    biquad_d2<float> p[2];
+    distortion_audio_module dist[2];
+public:
+    float *ins[in_count];
+    float *outs[out_count];
+    float *params[param_count];
+    uint32_t srate;
+    bool is_active;
+    saturator_audio_module();
+    void activate();
+    void deactivate();
+    void params_changed();
+    void set_sample_rate(uint32_t sr);
+    uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask);
+};
+
+/// Enhancer by Markus Schmidt (based on Krzysztof's filters and distortion algorythm)
+class enhancer_audio_module: public audio_module<enhancer_metadata> {
+private:
+    float freq_old;
+    uint32_t clip_in, clip_out;
+    float meter_in, meter_out, meter_drive;
+    biquad_d2<float> hp[2][4];
+    distortion_audio_module dist[2];
+public:
+    float *ins[in_count];
+    float *outs[out_count];
+    float *params[param_count];
+    uint32_t srate;
+    bool is_active;
+    enhancer_audio_module();
+    void activate();
+    void deactivate();
+    void params_changed();
+    void set_sample_rate(uint32_t sr);
+    uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask);
+};
+
 /// Filterclavier --- MIDI controlled filter by Hans Baier
 class filterclavier_audio_module: 
         public audio_module<filterclavier_metadata>, 
diff --git a/src/custom_ctl.cpp b/src/custom_ctl.cpp
index 4ddf32c..6620284 100644
--- a/src/custom_ctl.cpp
+++ b/src/custom_ctl.cpp
@@ -972,21 +972,24 @@ static inline float endless(float value)
         return fmod(1.f - fmod(1.f - value, 1.f), 1.f);
 }
 
-static inline float deadzone(float value, float incr, float scale)
+static inline float deadzone(GtkWidget *widget, float value, float incr, float scale)
 {
-    float dzw = 2 / scale;
-    if (value >= 0.5 + dzw)
-        value += dzw;
-    if (value < 0.5 - dzw)
-        value -= dzw;
-
-    value += incr;
-
-    if (value >= (0.5 - dzw) && value <= (0.5 + dzw))
-        return 0.5;
-    if (value < 0.5)
-        return value + dzw;
-    return value - dzw;
+    CalfKnob *self = CALF_KNOB(widget);
+    float dz = 20 / scale;
+    if(self->last_dz < 0.f) {
+        self -> last_dz = value + incr;
+    } else if (self->last_dz > 1.f) {
+        self->last_dz = 1.f;
+    } else {
+        self->last_dz += incr;
+    }
+    if(self->last_dz > 0.5 + dz) {
+        return std::min(0.5 + (self->last_dz - 0.5 - dz) * 0.5 / (0.5 - dz), (double)1);
+    }
+    if(self->last_dz < 0.5 - dz) {
+        return std::max(self->last_dz * 0.5 / (0.5 - dz), (double)0);
+    }
+    return 0.5;
 }
 
 static gboolean
@@ -1008,7 +1011,7 @@ calf_knob_pointer_motion (GtkWidget *widget, GdkEventMotion *event)
         else
         if (self->knob_type == 1)
         {
-            gtk_range_set_value(GTK_RANGE(widget), deadzone(gtk_range_get_value(GTK_RANGE(widget)), -(event->y - self->last_y) / (scale * sens), (scale * sens)));
+            gtk_range_set_value(GTK_RANGE(widget), deadzone(GTK_WIDGET(widget), gtk_range_get_value(GTK_RANGE(widget)), -(event->y - self->last_y) / (scale * sens), (scale * sens)));
         }
         else
         {
@@ -1057,6 +1060,7 @@ calf_knob_init (CalfKnob *self)
     GTK_WIDGET_SET_FLAGS (GTK_WIDGET(self), GTK_CAN_FOCUS);
     widget->requisition.width = 40;
     widget->requisition.height = 40;
+    self->last_dz = -1.f;
 }
 
 GtkWidget *
@@ -1398,14 +1402,14 @@ calf_tube_expose (GtkWidget *widget, GdkEventExpose *event)
     switch(self->direction) {
         case 1:
             // vertical
-            cairo_arc(c, ox + sx * 0.5, oy + sy * 0.3, sx, 0, 2 * M_PI);
-            pat = cairo_pattern_create_radial (ox + sx * 0.5, oy + sy * 0.3, 3, ox + sx * 0.5, oy + sy * 0.3, sx);
+            cairo_arc(c, ox + sx * 0.5, oy + sy * 0.2, sx, 0, 2 * M_PI);
+            pat = cairo_pattern_create_radial (ox + sx * 0.5, oy + sy * 0.2, 3, ox + sx * 0.5, oy + sy * 0.2, sx);
             break;
         default:
         case 2:
             // horizontal
-            cairo_arc(c, ox + sx * 0.7, oy + sy * 0.5, sy, 0, 2 * M_PI);
-            pat = cairo_pattern_create_radial (ox + sx * 0.7, oy + sy * 0.5, 3, ox + sx * 0.7, oy + sy * 0.5, sy);
+            cairo_arc(c, ox + sx * 0.8, oy + sy * 0.5, sy, 0, 2 * M_PI);
+            pat = cairo_pattern_create_radial (ox + sx * 0.8, oy + sy * 0.5, 3, ox + sx * 0.8, oy + sy * 0.5, sy);
             break;
     }
     cairo_pattern_add_color_stop_rgba (pat, 0,    1,    1,    1,    value);
@@ -1418,14 +1422,14 @@ calf_tube_expose (GtkWidget *widget, GdkEventExpose *event)
     switch(self->direction) {
         case 1:
             // vertical
-            cairo_arc(c, ox + sx * 0.5, oy + sy * 0.8, sx / 2, 0, 2 * M_PI);
-            pat = cairo_pattern_create_radial (ox + sx * 0.5, oy + sy * 0.8, 2, ox + sx * 0.5, oy + sy * 0.8, sx / 2);
+            cairo_arc(c, ox + sx * 0.5, oy + sy * 0.75, sx / 2, 0, 2 * M_PI);
+            pat = cairo_pattern_create_radial (ox + sx * 0.5, oy + sy * 0.75, 2, ox + sx * 0.5, oy + sy * 0.75, sx / 2);
             break;
         default:
         case 2:
             // horizontal
-            cairo_arc(c, ox + sx / 5, oy + sy * 0.5, sy / 2, 0, 2 * M_PI);
-            pat = cairo_pattern_create_radial (ox + sx / 5, oy + sy * 0.5, 2, ox + sx / 5, oy + sy * 0.5, sy / 2);
+            cairo_arc(c, ox + sx * 0.25, oy + sy * 0.5, sy / 2, 0, 2 * M_PI);
+            pat = cairo_pattern_create_radial (ox + sx * 0.25, oy + sy * 0.5, 2, ox + sx * 0.25, oy + sy * 0.5, sy / 2);
             break;
     }
     cairo_pattern_add_color_stop_rgba (pat, 0,    1,    1,    1,    value);
@@ -1434,7 +1438,7 @@ calf_tube_expose (GtkWidget *widget, GdkEventExpose *event)
     cairo_pattern_add_color_stop_rgba (pat, 1,    0.0, 0.2,  0.7,  0);
     cairo_set_source (c, pat);
     cairo_fill(c);
-    
+    cairo_destroy(c);
     return TRUE;
 }
 
@@ -1449,12 +1453,12 @@ calf_tube_size_request (GtkWidget *widget,
         case 1:
             switch(self->size) {
                 case 1:
-                    widget->requisition.width = 70;
+                    widget->requisition.width = 82;
                     widget->requisition.height = 130;
                     break;
                 default:
                 case 2:
-                    widget->requisition.width = 110;
+                    widget->requisition.width = 130;
                     widget->requisition.height = 210;
                     break;
             }
@@ -1464,12 +1468,12 @@ calf_tube_size_request (GtkWidget *widget,
             switch(self->size) {
                 case 1:
                     widget->requisition.width = 130;
-                    widget->requisition.height = 70;
+                    widget->requisition.height = 82;
                     break;
                 default:
                 case 2:
                     widget->requisition.width = 210;
-                    widget->requisition.height = 110;
+                    widget->requisition.height = 130;
                     break;
             }
             break;
@@ -1511,12 +1515,12 @@ calf_tube_init (CalfTube *self)
         case 1:
             switch(self->size) {
                 case 1:
-                    widget->requisition.width = 70;
+                    widget->requisition.width = 82;
                     widget->requisition.height = 130;
                     break;
                 default:
                 case 2:
-                    widget->requisition.width = 110;
+                    widget->requisition.width = 130;
                     widget->requisition.height = 210;
                     break;
             }
@@ -1526,12 +1530,12 @@ calf_tube_init (CalfTube *self)
             switch(self->size) {
                 case 1:
                     widget->requisition.width = 130;
-                    widget->requisition.height = 70;
+                    widget->requisition.height = 82;
                     break;
                 default:
                 case 2:
                     widget->requisition.width = 210;
-                    widget->requisition.height = 110;
+                    widget->requisition.height = 130;
                     break;
             }
             break;
diff --git a/src/makerdf.cpp b/src/makerdf.cpp
index 430fb91..d3723c6 100644
--- a/src/makerdf.cpp
+++ b/src/makerdf.cpp
@@ -586,9 +586,15 @@ void make_ttl(string path_prefix)
         const char *in_names[] = { "in_l", "in_r" };
         const char *out_names[] = { "out_l", "out_r" };
         for (int i = 0; i < pi->get_input_count(); i++)
-            add_port(ports, in_names[i], in_names[i], "Input", pn++);
+            if(i <= pi->get_input_count() - pi->get_inputs_optional() - 1)
+                add_port(ports, in_names[i], in_names[i], "Input", pn++);
+            else
+                add_port(ports, in_names[i], in_names[i], "Input", pn++, "lv2:AudioPort", true);
         for (int i = 0; i < pi->get_output_count(); i++)
-            add_port(ports, out_names[i], out_names[i], "Output", pn++);
+            if(i <= pi->get_output_count() - pi->get_outputs_optional() - 1)
+                add_port(ports, out_names[i], out_names[i], "Output", pn++);
+            else
+                add_port(ports, out_names[i], out_names[i], "Output", pn++, "lv2:AudioPort", true);
         for (int i = 0; i < pi->get_param_count(); i++)
             add_ctl_port(ports, *pi->get_param_props(i), pn++, pi, i);
         if (pi->get_midi()) {
diff --git a/src/modules.cpp b/src/modules.cpp
index bf945c7..c33a617 100644
--- a/src/modules.cpp
+++ b/src/modules.cpp
@@ -216,25 +216,23 @@ CALF_PORT_NAMES(compressor) = {"In L", "In R", "Out L", "Out R"};
 
 const char *compressor_detection_names[] = { "RMS", "Peak" };
 const char *compressor_stereo_link_names[] = { "Average", "Maximum" };
-const char *compressor_weighting_names[] = { "Normal", "A-weighted", "Deesser (low)", "Deesser (med)", "Deesser (high)" };
 
 CALF_PORT_PROPS(compressor) = {
+    { 0,      0,  1,    0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" },
+    { 1,           0,           64,    0,  PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_in", "Input" },
+    { 0,      0,  1,    0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_in", "Input" },
+    { 0,      0,  1,    0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_out", "Output" },
+    { 0,      0,  1,    0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_in", "0dB" },
+    { 0,      0,  1,    0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_out", "0dB" },
     { 0.125,      0.000976563, 1,    0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "threshold", "Threshold" },
     { 2,      1, 20,  21, PF_FLOAT | PF_SCALE_LOG_INF | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "ratio", "Ratio" },
     { 20,     0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "attack", "Attack" },
     { 250,    0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "release", "Release" },
-    { 2,      1, 64,   0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "makeup", "Makeup Gain" },
+    { 2,      1, 64,    0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "makeup", "Makeup Gain" },
     { 2.828427125,      1,  8,   0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "knee", "Knee" },
-    { 0,      0,  1,   0, PF_ENUM | PF_CTL_COMBO, compressor_detection_names, "detection", "Detection" },
-    { 0,      0,  1,   0, PF_ENUM | PF_CTL_COMBO, compressor_stereo_link_names, "stereo_link", "Stereo Link" },
-    { 0,      0,  4,   0, PF_ENUM | PF_CTL_COMBO, compressor_weighting_names, "aweighting", "Weighting" },
-    { 0, 0.03125, 1,    0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "compression", "Compression" },
-    { 0,      0,  1,    0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "peak", "Peak Output" },
-    { 0,      0,  1,    0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip", "0dB" },
-    { 0,      0,  1,    0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" },
-    { 1,           0,           64,    0,  PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "input", "Input" },
-    // { 2000,      10,20000,    0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "deess_freq", "Frequency" },
-    // { 0.707,  0.707,   32,    0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "deess_res", "Q" },
+    { 0,      0,  1,    0, PF_ENUM | PF_CTL_COMBO, compressor_detection_names, "detection", "Detection" },
+    { 0,      0,  1,    0, PF_ENUM | PF_CTL_COMBO, compressor_stereo_link_names, "stereo_link", "Stereo Link" },
+    { 0, 0.03125, 1,    0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "compression", "Reduction" },
 };
 
 CALF_PLUGIN_INFO(compressor) = { 0x8502, "Compressor", "Calf Compressor", "Thor Harald Johansen", calf_plugins::calf_copyright_info, "CompressorPlugin" };
@@ -565,6 +563,62 @@ CALF_PLUGIN_INFO(equalizer12band) = { 0x8501, "Equalizer12Band", "Calf Equalizer
 
 ////////////////////////////////////////////////////////////////////////////
 
+CALF_PORT_NAMES(saturator) = {"In L", "In R", "Out L", "Out R"};
+
+CALF_PORT_PROPS(saturator) = {
+    { 0,           0,           1,     0,  PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" },
+    { 1,           0,           64,    0,  PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_in", "Gain" },
+    { 1,           0,           64,    0,  PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_out", "Master" },
+    { 0.5,         0,           1,     0,  PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB , NULL, "mix", "Mix" },
+    { 0,           0,           1,     0,  PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_in", "Input" },
+    { 0,           0,           1,     0,  PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_out", "Output" },
+    { 0,           0,           1,     0,  PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_in", "0dB" },
+    { 0,           0,           1,     0,  PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_out", "0dB" },
+    
+    { 2,           0.1,         10,    0,  PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "drive", "Drive" },
+    { 10,         -10,          10,    0,  PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_FADER | PF_UNIT_COEF, NULL, "blend", "Blend" },
+    { 0,           0,           1,     0,  PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_drive", "Drive" },
+    
+    { 20000,      10,           20000, 0,  PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "lp_pre_freq", "Lowpass" },
+    { 10,         10,           20000, 0,  PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "hp_pre_freq", "Highpass" },
+
+    { 20000,      10,           20000, 0,  PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "lp_post_freq", "Lowpass" },
+    { 10,         10,           20000, 0,  PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "hp_post_freq", "Highpass" },
+    
+    { 2000,       80,           8000,  0,  PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "p_freq", "Tone" },
+    { 1,          0.0625,       16,    0,  PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "p_level", "Amount" },
+    { 1,          0.1,          10,    1,  PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "p_q", "Gradient" },
+};
+
+CALF_PLUGIN_INFO(saturator) = { 0x8502, "Saturator", "Calf Saturator", "Markus Schmidt / Krzysztof Foltman", calf_plugins::calf_copyright_info, "DistortionPlugin" };
+
+////////////////////////////////////////////////////////////////////////////
+
+CALF_PORT_NAMES(enhancer) = {"In L", "In R", "Out L", "Out R"};
+
+CALF_PORT_PROPS(enhancer) = {
+    { 0,           0,           1,     0,  PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" },
+    { 1,           0,           64,    0,  PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_in", "Input" },
+    { 1,           0,           64,    0,  PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_out", "Output" },
+    { 1,           0,           64,    0,  PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB | PF_PROP_NOBOUNDS, NULL, "amount", "Amount" },
+    { 0,           0,           1,     0,  PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_in", "Input" },
+    { 0,           0,           1,     0,  PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_out", "Output" },
+    { 0,           0,           1,     0,  PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_in", "0dB" },
+    { 0,           0,           1,     0,  PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_out", "0dB" },
+    
+    { 8.5,         0.1,         10,    0,  PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "drive", "Harmonics" },
+    { 0,          -10,          10,    0,  PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_FADER | PF_UNIT_COEF, NULL, "blend", "Blend harmonics" },
+    { 0,           0,           1,     0,  PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_drive", "Harmonics level" },
+    
+    { 6000,       2000,         12000, 0,  PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "freq", "Scope" },
+    { 0,          0,            1,     0,  PF_BOOL | PF_CTL_TOGGLE, NULL, "listen", "Listen" },
+};
+
+CALF_PLUGIN_INFO(enhancer) = { 0x8502, "Enhancer", "Calf Enhancer", "Markus Schmidt / Krzysztof Foltman", calf_plugins::calf_copyright_info, "DistortionPlugin" };
+
+
+////////////////////////////////////////////////////////////////////////////
+
 ////////////////////////////////////////////////////////////////////////////
 
 CALF_PORT_NAMES(monosynth) = {
diff --git a/src/modules_dsp.cpp b/src/modules_dsp.cpp
index 66524da..2c71e75 100644
--- a/src/modules_dsp.cpp
+++ b/src/modules_dsp.cpp
@@ -426,218 +426,6 @@ float multichorus_audio_module::freq_gain(int subindex, float freq, float srate)
     return (subindex ? right : left).freq_gain(freq, srate);                
 }
 
-///////////////////////////////////////////////////////////////////////////////////////////////
-
-compressor_audio_module::compressor_audio_module()
-{
-    is_active = false;
-    srate = 0;
-    last_generation = 0;
-}
-
-void compressor_audio_module::activate()
-{
-    is_active = true;
-    linSlope = 0.f;
-    peak = 0.f;
-    clip = 0.f;
-}
-
-void compressor_audio_module::deactivate()
-{
-    is_active = false;
-}
-
-void compressor_audio_module::set_sample_rate(uint32_t sr)
-{
-    srate = sr;
-    awL.set(sr);
-    awR.set(sr);
-}
-
-bool compressor_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context)
-{ 
-    if (!is_active)
-        return false;
-    if (subindex > 1) // 1
-        return false;
-    for (int i = 0; i < points; i++)
-    {
-        float input = dB_grid_inv(-1.0 + i * 2.0 / (points - 1));
-        float output = output_level(input);
-        if (subindex == 0)
-            data[i] = dB_grid(input);
-        else
-            data[i] = dB_grid(output); 
-    }
-    if (subindex == (*params[param_bypass] > 0.5f ? 1 : 0))
-        context->set_source_rgba(0.35, 0.4, 0.2, 0.3);
-    else {
-        context->set_source_rgba(0.35, 0.4, 0.2, 1);
-        context->set_line_width(2);
-    }
-    return true;
-}
-
-bool compressor_audio_module::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context)
-{
-    if (!is_active)
-        return false;
-    if (!subindex)
-    {
-        bool rms = *params[param_detection] == 0;
-        float det = rms ? sqrt(detected) : detected;
-        x = 0.5 + 0.5 * dB_grid(det);
-        y = dB_grid(*params[param_bypass] > 0.5f ? det : output_level(det));
-        return *params[param_bypass] > 0.5f ? false : true;
-    }
-    return false;
-}
-
-bool compressor_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context)
-{
-    bool tmp;
-    vertical = (subindex & 1) != 0;
-    bool result = get_freq_gridline(subindex >> 1, pos, tmp, legend, context, false);
-    if (result && vertical) {
-        if ((subindex & 4) && !legend.empty()) {
-            legend = "";
-        }
-        else {
-            size_t pos = legend.find(" dB");
-            if (pos != std::string::npos)
-                legend.erase(pos);
-        }
-        pos = 0.5 + 0.5 * pos;
-    }
-    return result;
-}
-
-// In case of doubt: this function is written by Thor. I just moved it to this file, damaging
-// the output of "git annotate" in the process.
-uint32_t compressor_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
-{
-    bool bypass = *params[param_bypass] > 0.5f;
-    
-    if(bypass) {
-        numsamples += offset;
-        while(offset < numsamples) {
-            outs[0][offset] = ins[0][offset];
-            outs[1][offset] = ins[1][offset];
-            ++offset;
-        }
-
-        if(params[param_compression] != NULL) {
-            *params[param_compression] = 1.f;
-        }
-
-        if(params[param_clip] != NULL) {
-            *params[param_clip] = 0.f;
-        }
-
-        if(params[param_peak] != NULL) {
-            *params[param_peak] = 0.f;
-        }
-  
-        return inputs_mask;
-    }
-
-    bool rms = *params[param_detection] == 0;
-    bool average = *params[param_stereo_link] == 0;
-    int aweighting = fastf2i_drm(*params[param_aweighting]);
-    float linThreshold = *params[param_threshold];
-    ratio = *params[param_ratio];
-    float attack = *params[param_attack];
-    float attack_coeff = std::min(1.f, 1.f / (attack * srate / 4000.f));
-    float release = *params[param_release];
-    float release_coeff = std::min(1.f, 1.f / (release * srate / 4000.f));
-    makeup = *params[param_makeup];
-    knee = *params[param_knee];
-
-    float linKneeSqrt = sqrt(knee);
-    linKneeStart = linThreshold / linKneeSqrt;
-    adjKneeStart = linKneeStart*linKneeStart;
-    float linKneeStop = linThreshold * linKneeSqrt;
-    
-    threshold = log(linThreshold);
-    kneeStart = log(linKneeStart);
-    kneeStop = log(linKneeStop);
-    compressedKneeStop = (kneeStop - threshold) / ratio + threshold;
-    
-    if (aweighting >= 2)
-    {
-        bpL.set_highshelf_rbj(5000, 0.707, 10 << (aweighting - 2), srate);
-        bpR.copy_coeffs(bpL);
-        bpL.sanitize();
-        bpR.sanitize();
-    }
-
-    numsamples += offset;
-    
-    float compression = 1.f;
-    peak = 0.f;
-    clip -= std::min(clip, numsamples);
-
-    while(offset < numsamples) {
-        float left = ins[0][offset] * *params[param_input];
-        float right = ins[1][offset] * *params[param_input];
-        
-        if(aweighting == 1) {
-            left = awL.process(left);
-            right = awR.process(right);
-        }
-        else if(aweighting >= 2) {
-            left = bpL.process(left);
-            right = bpR.process(right);
-        }
-        
-        float absample = average ? (fabs(left) + fabs(right)) * 0.5f : std::max(fabs(left), fabs(right));
-        if(rms) absample *= absample;
-        
-        linSlope += (absample - linSlope) * (absample > linSlope ? attack_coeff : release_coeff);
-        
-        float gain = 1.f;
-
-        if(linSlope > 0.f) {
-            gain = output_gain(linSlope, rms);
-        }
-
-        compression = gain;
-        gain *= makeup;
-
-        float outL = ins[0][offset] * gain * *params[param_input];
-        float outR = ins[1][offset] * gain * *params[param_input];
-        
-        outs[0][offset] = outL;
-        outs[1][offset] = outR;
-        
-        ++offset;
-        
-        float maxLR = std::max(fabs(outL), fabs(outR));
-        if(maxLR > peak)
-            peak = maxLR;
-        
-        if(peak > 1.f) clip = srate >> 3; /* blink clip LED for 125 ms */
-    }
-    
-    detected = linSlope;
-    
-    if(params[param_compression] != NULL) {
-        *params[param_compression] = compression;
-    }
-
-    if(params[param_clip] != NULL) {
-        *params[param_clip] = clip;
-    }
-
-    if(params[param_peak] != NULL) {
-        *params[param_peak] = peak;
-    }
-
-    return inputs_mask;
-}
-
-
 /// Multibandcompressor by Markus Schmidt
 ///
 /// This module splits the signal in four different bands
@@ -1051,6 +839,161 @@ int multibandcompressor_audio_module::get_changed_offsets(int index, int generat
     return 0;
 }
 
+/// Compressor originally by Thor
+///
+/// This module provides Thor's original compressor without any sidechain or weighting
+///////////////////////////////////////////////////////////////////////////////////////////////
+
+compressor_audio_module::compressor_audio_module()
+{
+    is_active = false;
+    srate = 0;
+    last_generation = 0;
+}
+
+void compressor_audio_module::activate()
+{
+    is_active = true;
+    // set all filters and strips
+    compressor.activate();
+    params_changed();
+    meter_in = 0.f;
+    meter_out = 0.f;
+    clip_in = 0.f;
+    clip_out = 0.f;
+}
+void compressor_audio_module::deactivate()
+{
+    is_active = false;
+    compressor.deactivate();
+}
+
+void compressor_audio_module::params_changed()
+{
+    compressor.set_params(*params[param_attack], *params[param_release], *params[param_threshold], *params[param_ratio], *params[param_knee], *params[param_makeup], *params[param_detection], *params[param_stereo_link], *params[param_bypass], 0.f);
+}
+
+void compressor_audio_module::set_sample_rate(uint32_t sr)
+{
+    srate = sr;
+    compressor.set_sample_rate(srate);
+}
+
+uint32_t compressor_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
+{
+    bool bypass = *params[param_bypass] > 0.5f;
+    numsamples += offset;
+    if(bypass) {
+        // everything bypassed
+        while(offset < numsamples) {
+            outs[0][offset] = ins[0][offset];
+            outs[1][offset] = ins[1][offset];
+            ++offset;
+        }
+        // displays, too
+        clip_in    = 0.f;
+        clip_out   = 0.f;
+        meter_in   = 0.f;
+        meter_out  = 0.f;
+    } else {
+        // process
+        
+        clip_in    -= std::min(clip_in,  numsamples);
+        clip_out   -= std::min(clip_out,  numsamples);
+        
+        while(offset < numsamples) {
+            // cycle through samples
+            float outL = 0.f;
+            float outR = 0.f;
+            float inL = ins[0][offset];
+            float inR = ins[1][offset];
+            // in level
+            inR *= *params[param_level_in];
+            inL *= *params[param_level_in];
+            
+            float leftAC = inL;
+            float rightAC = inR;
+            float leftSC = inL;
+            float rightSC = inR;
+            
+            compressor.process(leftAC, rightAC, leftSC, rightSC);
+            
+            outL = leftAC;
+            outR = rightAC;
+            
+            // send to output
+            outs[0][offset] = outL;
+            outs[1][offset] = outR;
+            
+            // clip LED's
+            if(std::max(fabs(inL), fabs(inR)) > 1.f) {
+                clip_in   = srate >> 3;
+            }
+            if(std::max(fabs(outL), fabs(outR)) > 1.f) {
+                clip_out  = srate >> 3;
+            }
+            // rise up out meter
+            meter_in = std::max(fabs(inL), fabs(inR));;
+            meter_out = std::max(fabs(outL), fabs(outR));;
+            
+            // next sample
+            ++offset;
+        } // cycle trough samples
+    }
+    // draw meters
+    if(params[param_clip_in] != NULL) {
+        *params[param_clip_in] = clip_in;
+    }
+    if(params[param_clip_out] != NULL) {
+        *params[param_clip_out] = clip_out;
+    }
+    if(params[param_meter_in] != NULL) {
+        *params[param_meter_in] = meter_in;
+    }
+    if(params[param_meter_out] != NULL) {
+        *params[param_meter_out] = meter_out;
+    }
+    // draw strip meter
+    if(bypass > 0.5f) {
+        if(params[param_compression] != NULL) {
+            *params[param_compression] = 1.0f;
+        }
+    } else {
+        if(params[param_compression] != NULL) {
+            *params[param_compression] = compressor.get_comp_level();
+        }
+    }
+    // whatever has to be returned x)
+    return outputs_mask;
+}
+bool compressor_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context)
+{
+    if (!is_active)
+        return false;
+    return compressor.get_graph(subindex, data, points, context);
+}
+
+bool compressor_audio_module::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context)
+{
+    if (!is_active)
+        return false;
+    return compressor.get_dot(subindex, x, y, size, context);
+}
+
+bool compressor_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context)
+{
+    if (!is_active)
+        return false;
+    return compressor.get_gridline(subindex, pos, vertical, legend, context);
+}
+
+int compressor_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline)
+{
+    if (!is_active)
+        return false;
+    return compressor.get_changed_offsets(generation, subindex_graph, subindex_dot, subindex_gridline);
+}
+
 /// Sidecain Compressor by Markus Schmidt
 ///
 /// This module splits the signal in a sidechain- and a process signal.
@@ -1544,7 +1487,7 @@ uint32_t deesser_audio_module::process(uint32_t offset, uint32_t numsamples, uin
             outs[0][offset] = outL;
             outs[1][offset] = outR;
             
-            if(std::max(fabs(leftSC), fabs(rightSC)) > 0.1) {
+            if(std::max(fabs(leftSC), fabs(rightSC)) > *params[param_threshold]) {
                 detected_led   = srate >> 3;
             }
             if(std::max(fabs(leftAC), fabs(rightAC)) > 1.f) {
@@ -1641,10 +1584,10 @@ int deesser_audio_module::get_changed_offsets(int index, int generation, int &su
     return false;
 }
 
-/// Gain reduction module implemented by Markus Schmidt
-/// Nearly all functions of this module are originally written
+/// Gain reduction module by Thor
+/// All functions of this module are originally written
 /// by Thor, while some features have been stripped (mainly stereo linking
-/// and frequency correction as implemented in his Compressor above)
+/// and frequency correction as implemented in Sidechain Compressor above)
 /// To save some CPU.
 ////////////////////////////////////////////////////////////////////////////////
 gain_reduction_audio_module::gain_reduction_audio_module()
@@ -2950,3 +2893,563 @@ int equalizer5band_audio_module::get_changed_offsets(int index, int generation,
     }
     return false;
 }
+
+/// Saturator Band by Markus Schmidt
+///
+/// This module is based on Krzysztof's filters and distortion routine.
+/// It provides a blendable saturation stage followed by a highpass, a lowpass and a peak filter
+///////////////////////////////////////////////////////////////////////////////////////////////
+
+saturator_audio_module::saturator_audio_module()
+{
+    is_active = false;
+    srate = 0;
+    clip_in    = 0.f;
+    clip_out   = 0.f;
+    meter_in  = 0.f;
+    meter_out = 0.f;
+    meter_drive = 0.f;
+}
+
+void saturator_audio_module::activate()
+{
+    is_active = true;
+    // set all filters
+    params_changed();
+}
+void saturator_audio_module::deactivate()
+{
+    is_active = false;
+}
+
+void saturator_audio_module::params_changed()
+{
+    // set the params of all filters
+    if(*params[param_lp_pre_freq] != lp_pre_freq_old) {
+        lp[0][0].set_lp_rbj(*params[param_lp_pre_freq], 0.707, (float)srate);
+        if(in_count > 1 && out_count > 1)
+            lp[1][0].copy_coeffs(lp[0][0]);
+        lp[0][1].copy_coeffs(lp[0][0]);
+        if(in_count > 1 && out_count > 1)
+            lp[1][1].copy_coeffs(lp[0][0]);
+        lp_pre_freq_old = *params[param_lp_pre_freq];
+    }
+    if(*params[param_hp_pre_freq] != hp_pre_freq_old) {
+        hp[0][0].set_hp_rbj(*params[param_hp_pre_freq], 0.707, (float)srate);
+        if(in_count > 1 && out_count > 1)
+            hp[1][0].copy_coeffs(hp[0][0]);
+        hp[0][1].copy_coeffs(hp[0][0]);
+        if(in_count > 1 && out_count > 1)
+            hp[1][1].copy_coeffs(hp[0][0]);
+        hp_pre_freq_old = *params[param_hp_pre_freq];
+    }
+    if(*params[param_lp_post_freq] != lp_post_freq_old) {
+        lp[0][2].set_lp_rbj(*params[param_lp_post_freq], 0.707, (float)srate);
+        if(in_count > 1 && out_count > 1)
+            lp[1][2].copy_coeffs(lp[0][2]);
+        lp[0][3].copy_coeffs(lp[0][2]);
+        if(in_count > 1 && out_count > 1)
+            lp[1][3].copy_coeffs(lp[0][2]);
+        lp_post_freq_old = *params[param_lp_post_freq];
+    }
+    if(*params[param_hp_post_freq] != hp_post_freq_old) {
+        hp[0][2].set_hp_rbj(*params[param_hp_post_freq], 0.707, (float)srate);
+        if(in_count > 1 && out_count > 1)
+            hp[1][2].copy_coeffs(hp[0][2]);
+        hp[0][3].copy_coeffs(hp[0][2]);
+        if(in_count > 1 && out_count > 1)
+            hp[1][3].copy_coeffs(hp[0][2]);
+        hp_post_freq_old = *params[param_hp_post_freq];
+    }
+    if(*params[param_p_freq] != p_freq_old or *params[param_p_level] != p_level_old or *params[param_p_q] != p_q_old) {
+        p[0].set_peakeq_rbj((float)*params[param_p_freq], (float)*params[param_p_q], (float)*params[param_p_level], (float)srate);
+        if(in_count > 1 && out_count > 1)
+            p[1].copy_coeffs(p[0]);
+        p_freq_old = *params[param_p_freq];
+        p_level_old = *params[param_p_level];
+        p_q_old = *params[param_p_q];
+    }
+    // set distortion
+    dist[0].set_params(*params[param_blend], *params[param_drive]);
+    if(in_count > 1 && out_count > 1)
+        dist[1].set_params(*params[param_blend], *params[param_drive]);
+}
+
+void saturator_audio_module::set_sample_rate(uint32_t sr)
+{
+    srate = sr;
+    dist[0].set_sample_rate(sr);
+    if(in_count > 1 && out_count > 1)
+        dist[1].set_sample_rate(sr);
+}
+
+uint32_t saturator_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
+{
+    bool bypass = *params[param_bypass] > 0.5f;
+    numsamples += offset;
+    if(bypass) {
+        // everything bypassed
+        while(offset < numsamples) {
+            if(in_count > 1 && out_count > 1) {
+                outs[0][offset] = ins[0][offset];
+                outs[1][offset] = ins[1][offset];
+            } else if(in_count > 1) {
+                outs[0][offset] = (ins[0][offset] + ins[1][offset]) / 2;
+            } else if(out_count > 1) {
+                outs[0][offset] = ins[0][offset];
+                outs[1][offset] = ins[0][offset];
+            } else {
+                outs[0][offset] = ins[0][offset];
+            }
+            ++offset;
+        }
+        // displays, too
+        clip_in    = 0.f;
+        clip_out   = 0.f;
+        meter_in  = 0.f;
+        meter_out = 0.f;
+        meter_drive = 0.f;
+    } else {
+        
+        clip_in    -= std::min(clip_in,  numsamples);
+        clip_out   -= std::min(clip_out, numsamples);
+        meter_in = 0.f;
+        meter_out = 0.f;
+        meter_drive = 0.f;
+        
+        // process
+        while(offset < numsamples) {
+            // cycle through samples
+            float out[2], in[2] = {0.f, 0.f};
+            float maxIn, maxOut, maxDrive = 0.f;
+            int c = 0;
+            
+            if(in_count > 1 && out_count > 1) {
+                // stereo in/stereo out
+                // handle full stereo
+                in[0] = ins[0][offset];
+                in[0] *= *params[param_level_in];
+                in[1] = ins[1][offset];
+                in[1] *= *params[param_level_in];
+                c = 2;
+            } else {
+                // in and/or out mono
+                // handle mono
+                in[0] = ins[0][offset];
+                in[0] *= *params[param_level_in];
+                in[1] = in[0];
+                c = 1;
+            }
+            
+            float proc[2];
+            proc[0] = in[0];
+            proc[1] = in[1];
+            
+            for (int i = 0; i < c; ++i) {
+                // all pre filters in chain
+                proc[i] = lp[i][1].process(lp[i][0].process(proc[i]));
+                proc[i] = hp[i][1].process(hp[i][0].process(proc[i]));
+                
+                // saturate
+                proc[i] = dist[i].process(proc[i]);
+                
+                // tone control
+                proc[i] = p[i].process(proc[i]);
+
+                // all post filters in chain
+                proc[i] = lp[i][2].process(lp[i][3].process(proc[i]));
+                proc[i] = hp[i][2].process(hp[i][3].process(proc[i]));
+            }
+            
+            if(in_count > 1 && out_count > 1) {
+                // full stereo
+                out[0] = ((proc[0] * *params[param_mix]) + in[0] * (1 - *params[param_mix])) * *params[param_level_out];
+                outs[0][offset] = out[0];
+                out[1] = ((proc[1] * *params[param_mix]) + in[1] * (1 - *params[param_mix])) * *params[param_level_out];
+                outs[1][offset] = out[1];
+                maxIn = std::max(fabs(in[0]), fabs(in[1]));
+                maxOut = std::max(fabs(out[0]), fabs(out[1]));
+                maxDrive = std::max(dist[0].get_distortion_level(), dist[1].get_distortion_level());
+            } else if(out_count > 1) {
+                // mono -> pseudo stereo
+                out[0] = ((proc[0] * *params[param_mix]) + in[0] * (1 - *params[param_mix])) * *params[param_level_out];
+                outs[0][offset] = out[0];
+                out[1] = out[0];
+                outs[1][offset] = out[1];
+                maxOut = fabs(out[0]);
+                maxIn = fabs(in[0]);
+                maxDrive = dist[0].get_distortion_level();
+            } else {
+                // stereo -> mono
+                // or full mono
+                out[0] = ((proc[0] * *params[param_mix]) + in[0] * (1 - *params[param_mix])) * *params[param_level_out];
+                outs[0][offset] = out[0];
+                maxIn = fabs(in[0]);
+                maxOut = fabs(out[0]);
+                maxDrive = dist[0].get_distortion_level();
+            }
+            
+            if(maxIn > 1.f) {
+                clip_in  = srate >> 3;
+            }
+            if(maxOut > 1.f) {
+                clip_out = srate >> 3;
+            }
+            // set up in / out meters
+            if(maxIn > meter_in) {
+                meter_in = maxIn;
+            }
+            if(maxOut > meter_out) {
+                meter_out = maxOut;
+            }
+            if(maxDrive > meter_drive) {
+                meter_drive = maxDrive;
+            }
+            
+            // next sample
+            ++offset;
+        } // cycle trough samples
+        // clean up
+        lp[0][0].sanitize();
+        lp[1][0].sanitize();
+        lp[0][1].sanitize();
+        lp[1][1].sanitize();
+        lp[0][2].sanitize();
+        lp[1][2].sanitize();
+        lp[0][3].sanitize();
+        lp[1][3].sanitize();
+        hp[0][0].sanitize();
+        hp[1][0].sanitize();
+        hp[0][1].sanitize();
+        hp[1][1].sanitize();
+        hp[0][2].sanitize();
+        hp[1][2].sanitize();
+        hp[0][3].sanitize();
+        hp[1][3].sanitize();
+        p[0].sanitize();
+        p[1].sanitize();
+    }
+    // draw meters
+    if(params[param_clip_in] != NULL) {
+        *params[param_clip_in] = clip_in;
+    }
+    if(params[param_clip_out] != NULL) {
+        *params[param_clip_out] = clip_out;
+    }
+    
+    if(params[param_meter_in] != NULL) {
+        *params[param_meter_in] = meter_in;
+    }
+    if(params[param_meter_out] != NULL) {
+        *params[param_meter_out] = meter_out;
+    }
+    if(params[param_meter_drive] != NULL) {
+        *params[param_meter_drive] = meter_drive;
+    }
+    // whatever has to be returned x)
+    return outputs_mask;
+}
+
+/// Enhancer Band by Markus Schmidt
+///
+/// This module is based on Krzysztof's filters and distortion routine.
+/// It provides a blendable saturation stage followed by a highpass, a lowpass and a peak filter
+///////////////////////////////////////////////////////////////////////////////////////////////
+
+enhancer_audio_module::enhancer_audio_module()
+{
+    is_active = false;
+    srate = 0;
+    clip_in    = 0.f;
+    clip_out   = 0.f;
+    meter_in  = 0.f;
+    meter_out = 0.f;
+    meter_drive = 0.f;
+}
+
+void enhancer_audio_module::activate()
+{
+    is_active = true;
+    // set all filters
+    params_changed();
+}
+void enhancer_audio_module::deactivate()
+{
+    is_active = false;
+}
+
+void enhancer_audio_module::params_changed()
+{
+    // set the params of all filters
+    if(*params[param_freq] != freq_old) {
+        hp[0][0].set_hp_rbj(*params[param_freq], 0.707, (float)srate);
+        hp[0][1].copy_coeffs(hp[0][0]);
+        hp[0][2].copy_coeffs(hp[0][0]);
+        hp[0][3].copy_coeffs(hp[0][0]);
+        if(in_count > 1 && out_count > 1) {
+            hp[1][0].copy_coeffs(hp[0][0]);
+            hp[1][1].copy_coeffs(hp[0][0]);
+            hp[1][2].copy_coeffs(hp[0][0]);
+            hp[1][3].copy_coeffs(hp[0][0]);
+        }
+        freq_old = *params[param_freq];
+    }
+    // set distortion
+    dist[0].set_params(*params[param_blend], *params[param_drive]);
+    if(in_count > 1 && out_count > 1)
+        dist[1].set_params(*params[param_blend], *params[param_drive]);
+}
+
+void enhancer_audio_module::set_sample_rate(uint32_t sr)
+{
+    srate = sr;
+    dist[0].set_sample_rate(sr);
+    if(in_count > 1 && out_count > 1)
+        dist[1].set_sample_rate(sr);
+}
+
+uint32_t enhancer_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
+{
+    bool bypass = *params[param_bypass] > 0.5f;
+    numsamples += offset;
+    if(bypass) {
+        // everything bypassed
+        while(offset < numsamples) {
+            if(in_count > 1 && out_count > 1) {
+                outs[0][offset] = ins[0][offset];
+                outs[1][offset] = ins[1][offset];
+            } else if(in_count > 1) {
+                outs[0][offset] = (ins[0][offset] + ins[1][offset]) / 2;
+            } else if(out_count > 1) {
+                outs[0][offset] = ins[0][offset];
+                outs[1][offset] = ins[0][offset];
+            } else {
+                outs[0][offset] = ins[0][offset];
+            }
+            ++offset;
+        }
+        // displays, too
+        clip_in    = 0.f;
+        clip_out   = 0.f;
+        meter_in  = 0.f;
+        meter_out = 0.f;
+        meter_drive = 0.f;
+    } else {
+        
+        clip_in    -= std::min(clip_in,  numsamples);
+        clip_out   -= std::min(clip_out, numsamples);
+        meter_in = 0.f;
+        meter_out = 0.f;
+        meter_drive = 0.f;
+        
+        // process
+        while(offset < numsamples) {
+            // cycle through samples
+            float out[2], in[2] = {0.f, 0.f};
+            float maxIn, maxOut, maxDrive = 0.f;
+            int c = 0;
+            
+            if(in_count > 1 && out_count > 1) {
+                // stereo in/stereo out
+                // handle full stereo
+                in[0] = ins[0][offset];
+                in[0] *= *params[param_level_in];
+                in[1] = ins[1][offset];
+                in[1] *= *params[param_level_in];
+                c = 2;
+            } else {
+                // in and/or out mono
+                // handle mono
+                in[0] = ins[0][offset];
+                in[0] *= *params[param_level_in];
+                in[1] = in[0];
+                c = 1;
+            }
+            
+            float proc[2];
+            proc[0] = in[0];
+            proc[1] = in[1];
+            
+            for (int i = 0; i < c; ++i) {
+                // all pre filters in chain
+                proc[i] = hp[i][1].process(hp[i][0].process(proc[i]));
+                
+                // saturate
+                proc[i] = dist[i].process(proc[i]);
+
+                // all post filters in chain
+                proc[i] = hp[i][2].process(hp[i][3].process(proc[i]));
+            }
+            
+            if(in_count > 1 && out_count > 1) {
+                // full stereo
+                if(*params[param_listen] > 0.f)
+                    out[0] = proc[0] * *params[param_amount] * *params[param_level_out];
+                else
+                    out[0] = (proc[0] * *params[param_amount] + in[0]) * *params[param_level_out];
+                outs[0][offset] = out[0];
+                if(*params[param_listen] > 0.f)
+                    out[1] = proc[1] * *params[param_amount] * *params[param_level_out];
+                else
+                    out[1] = (proc[1] * *params[param_amount] + in[1]) * *params[param_level_out];
+                outs[1][offset] = out[1];
+                maxIn = std::max(fabs(in[0]), fabs(in[1]));
+                maxOut = std::max(fabs(out[0]), fabs(out[1]));
+                maxDrive = std::max(dist[0].get_distortion_level() * *params[param_amount],
+                                            dist[1].get_distortion_level() * *params[param_amount]);
+            } else if(out_count > 1) {
+                // mono -> pseudo stereo
+                if(*params[param_listen] > 0.f)
+                    out[0] = proc[0] * *params[param_amount] * *params[param_level_out];
+                else
+                    out[0] = (proc[0] * *params[param_amount] + in[0]) * *params[param_level_out];
+                outs[0][offset] = out[0];
+                out[1] = out[0];
+                outs[1][offset] = out[1];
+                maxOut = fabs(out[0]);
+                maxIn = fabs(in[0]);
+                maxDrive = dist[0].get_distortion_level() * *params[param_amount];
+            } else {
+                // stereo -> mono
+                // or full mono
+                if(*params[param_listen] > 0.f)
+                    out[0] = proc[0] * *params[param_amount] * *params[param_level_out];
+                else
+                    out[0] = (proc[0] * *params[param_amount] + in[0]) * *params[param_level_out];
+                outs[0][offset] = out[0];
+                maxIn = fabs(in[0]);
+                maxOut = fabs(out[0]);
+                maxDrive = dist[0].get_distortion_level() * *params[param_amount];
+            }
+            
+            if(maxIn > 1.f) {
+                clip_in  = srate >> 3;
+            }
+            if(maxOut > 1.f) {
+                clip_out = srate >> 3;
+            }
+            // set up in / out meters
+            if(maxIn > meter_in) {
+                meter_in = maxIn;
+            }
+            if(maxOut > meter_out) {
+                meter_out = maxOut;
+            }
+            if(maxDrive > meter_drive) {
+                meter_drive = maxDrive;
+            }
+            
+            // next sample
+            ++offset;
+        } // cycle trough samples
+        // clean up
+        hp[0][0].sanitize();
+        hp[1][0].sanitize();
+        hp[0][1].sanitize();
+        hp[1][1].sanitize();
+        hp[0][2].sanitize();
+        hp[1][2].sanitize();
+        hp[0][3].sanitize();
+        hp[1][3].sanitize();
+    }
+    // draw meters
+    if(params[param_clip_in] != NULL) {
+        *params[param_clip_in] = clip_in;
+    }
+    if(params[param_clip_out] != NULL) {
+        *params[param_clip_out] = clip_out;
+    }
+    
+    if(params[param_meter_in] != NULL) {
+        *params[param_meter_in] = meter_in;
+    }
+    if(params[param_meter_out] != NULL) {
+        *params[param_meter_out] = meter_out;
+    }
+    if(params[param_meter_drive] != NULL) {
+        *params[param_meter_drive] = meter_drive;
+    }
+    // whatever has to be returned x)
+    return outputs_mask;
+}
+
+/// Distortion Module by Krzysztof Foltman
+///
+/// This module provides a blendable saturation stage
+///////////////////////////////////////////////////////////////////////////////////////////////
+
+distortion_audio_module::distortion_audio_module()
+{
+    is_active = false;
+    srate = 0;
+    meter = 0.f;
+}
+
+void distortion_audio_module::activate()
+{
+    is_active = true;
+    set_params(0.f, 0.f);
+}
+void distortion_audio_module::deactivate()
+{
+    is_active = false;
+}
+
+void distortion_audio_module::set_params(float blend, float drive)
+{
+    // set distortion coeffs
+    // NOTICE!! This routine is implemented for testing purposes only!
+    // It is taken from TAP Plugins and will act as a placeholder until
+    // Krzysztof's distrotion routine is ready!
+    if ((drive_old != drive) || (blend_old != blend)) {
+        rdrive = 12.0f / drive;
+        rbdr = rdrive / (10.5f - blend) * 780.0f / 33.0f;
+        kpa = D(2.0f * (rdrive*rdrive) - 1.0f) + 1.0f;
+        kpb = (2.0f - kpa) / 2.0f;
+        ap = ((rdrive*rdrive) - kpa + 1.0f) / 2.0f;
+        kc = kpa / D(2.0f * D(2.0f * (rdrive*rdrive) - 1.0f) - 2.0f * rdrive*rdrive);
+
+        srct = (0.1f * srate) / (0.1f * srate + 1.0f);
+        sq = kc*kc + 1.0f;
+        knb = -1.0f * rbdr / D(sq);
+        kna = 2.0f * kc * rbdr / D(sq);
+        an = rbdr*rbdr / sq;
+        imr = 2.0f * knb + D(2.0f * kna + 4.0f * an - 1.0f);
+        pwrq = 2.0f / (imr + 1.0f);
+        
+        drive_old = drive;
+        blend_old = blend;
+    }
+}
+
+void distortion_audio_module::set_sample_rate(uint32_t sr)
+{
+    srate = sr;
+}
+
+float distortion_audio_module::process(float(in))
+{
+    // NOTICE!! This routine is implemented for testing purposes only!
+    // It is taken from TAP Plugins and will act as a placeholder until
+    // Krzysztof's distrotion routine is ready!
+    meter = 0.f;
+    float out = 0.f;
+    float proc = in;
+    float med;
+    if (proc >= 0.0f) {
+        med = (D(ap + proc * (kpa - proc)) + kpb) * pwrq;
+    } else {
+        med = (D(an - proc * (kna + proc)) + knb) * pwrq * -1.0f;
+    }
+    proc = srct * (med - prev_med + prev_out);
+    prev_med = M(med);
+    prev_out = M(proc);
+    out = proc;
+    meter = proc;
+    return out;
+}
+
+float distortion_audio_module::get_distortion_level()
+{
+    return meter;
+}

-- 
calf audio plugins packaging



More information about the pkg-multimedia-commits mailing list