From 6d54dc0a7b7f9091aa17905e1b68c4de8940c5e2 Mon Sep 17 00:00:00 2001
From: Jan-Henrik Bruhn <hi@jhbruhn.de>
Date: Sun, 10 May 2020 14:54:25 +0200
Subject: [PATCH] Implement attenuverters

---
 stereo_mix/processor.cc | 25 +++++++++++++++----------
 stereo_mix/processor.h  | 21 ++++++++++++++++-----
 stereo_mix/ui.cc        |  3 +++
 stereo_mix/ui.h         |  2 +-
 stmlib                  |  2 +-
 5 files changed, 36 insertions(+), 17 deletions(-)

diff --git a/stereo_mix/processor.cc b/stereo_mix/processor.cc
index bcd5a92..3944f8d 100644
--- a/stereo_mix/processor.cc
+++ b/stereo_mix/processor.cc
@@ -1,5 +1,6 @@
 #include "processor.h"
 #include "stmlib/stmlib.h"
+#include "stmlib/dsp/dsp.h"
 #include "stmlib/utils/dsp.h"
 #include <math.h>
 
@@ -12,14 +13,16 @@ void Processor::Process(int16_t cvs[], uint16_t* outs)
   uint32_t value_r;
 
   uint16_t pan_pot = (pan_offset + 32767L);
-  uint16_t vol_pot = (volume_offset);
-  int16_t pan_cv = cvs[0];
-  int16_t vol_cv = cvs[1];
-  int32_t pan = pan_pot + pan_cv;
+  uint16_t vol_pot = (vol_offset);
+  int32_t pan_cv = (cvs[0] * static_cast<int32_t>(pan_att)) >> 15; // full attenuate gives 3x amplification :)
+  int32_t vol_cv = (cvs[1] * static_cast<int32_t>(vol_att)) >> 15;
+  pan_cv = Clip16(pan_cv);
+  vol_cv = Clip16(vol_cv);
+
 
   // calculate value for ui
-  int32_t lin = volume_offset + (cvs[1] << 1);
-  CONSTRAIN(lin, 0, 65535);
+  int32_t lin = vol_offset + vol_cv * 3;
+  lin = ClipU16(lin);
   lin *= !mute;
   this->linear_vol = lin;
 
@@ -29,18 +32,20 @@ void Processor::Process(int16_t cvs[], uint16_t* outs)
   vol_pot = Mix(vol_pot_exp, vol_pot_log, log_exp_mix_pot);
   int32_t vol = vol_pot;
 
-  uint16_t vol_cv_absu16 = abs(vol_cv);
+  uint16_t vol_cv_absu16 = abs(vol_cv) << 1;
   uint16_t vol_cv_exp = Interpolate124(lut_linear_to_exp, vol_cv_absu16);
   uint16_t vol_cv_log = 65535 - InverseInterpolate124(lut_linear_to_exp, vol_cv_absu16);
-  uint16_t vol_cv_pre = Mix(vol_cv_exp, vol_cv_log, log_exp_mix_cv);
+  uint32_t vol_cv_pre = Mix(vol_cv_exp, vol_cv_log, log_exp_mix_cv) * 3;
   vol += vol_cv > 0 ? vol_cv_pre : -vol_cv_pre;
   vol *= !mute;
 
-  CONSTRAIN(pan, 0, 65535);
-  CONSTRAIN(vol, 0, 65535);
+  vol = ClipU16(vol);
 
   this->previous_vol = vol;
 
+  int32_t pan = pan_pot + (pan_cv * 3);
+  pan = ClipU16(pan);
+
   value_l = (Interpolate124(lut_left_sin_pan, pan) * vol) >> 16;
   value_r = (Interpolate124(lut_right_cos_pan, pan) * vol) >> 16;
 
diff --git a/stereo_mix/processor.h b/stereo_mix/processor.h
index efd0c60..4f57d20 100644
--- a/stereo_mix/processor.h
+++ b/stereo_mix/processor.h
@@ -9,7 +9,7 @@ class Processor {
 
   inline void set_volume_offset(uint16_t volume_offset_)
   {
-    volume_offset = volume_offset_;
+    vol_offset = volume_offset_;
   }
 
   inline void set_pan_offset(int16_t pan_offset_)
@@ -17,6 +17,14 @@ class Processor {
     pan_offset = pan_offset_;
   }
 
+  inline void set_volume_attenuverter(int16_t vol_att_) {
+    vol_att = vol_att_;
+  }
+
+  inline void set_pan_attenuverter(int16_t pan_att_) {
+    pan_att = pan_att_;
+  }
+
   inline void set_muted(bool m)
   {
     mute = m;
@@ -27,13 +35,16 @@ class Processor {
   }
 
   private:
-  uint16_t volume_offset = 0;
-  int16_t pan_offset = 0;
   uint16_t previous_vol;
   uint16_t linear_vol;
 
-  uint16_t log_exp_mix_cv  = 32767; // -> linear
-  uint16_t log_exp_mix_pot = 0;
+  uint16_t vol_offset = 0;
+  int16_t pan_offset = 0;
+  int16_t vol_att;
+  int16_t pan_att;
+  uint16_t log_exp_mix_cv  = 32767;//32767; // -> linear
+  uint16_t log_exp_mix_pot = 0; // -> exp
+
 
   bool mute = false;
 };
diff --git a/stereo_mix/ui.cc b/stereo_mix/ui.cc
index c14d118..b47a43f 100644
--- a/stereo_mix/ui.cc
+++ b/stereo_mix/ui.cc
@@ -89,6 +89,9 @@ void UI::TaskProcessPotControllers()
   for (size_t i = 0; i < kNumChannels; i++) {
     potControllers[i].ProcessUIRate();
     potControllers[i + kNumChannels].ProcessUIRate();
+
+    processors[i].set_volume_attenuverter(this->volume_att_pots[i] - 32767);
+    processors[i].set_pan_attenuverter(this->pan_att_pots[i] - 32767);
   }
 }
 
diff --git a/stereo_mix/ui.h b/stereo_mix/ui.h
index ef85d1f..0b340f3 100644
--- a/stereo_mix/ui.h
+++ b/stereo_mix/ui.h
@@ -29,7 +29,7 @@ class UI {
       uint16_t* pan_hidden_params[kNumChannels] = {&pan_att_pots[i], &pan_att_pots[i], &pan_att_pots[i], &pan_att_pots[i]};
       potControllers[i + kNumChannels].Init(&pan_pots[i], pan_hidden_params);
 
-      volume_att_pots[i] = pan_att_pots[i] = 65535;
+      volume_att_pots[i] = pan_att_pots[i] = 32767 + (32767 / 2);
     }
 
   }
diff --git a/stmlib b/stmlib
index bac07fc..e5d7705 160000
--- a/stmlib
+++ b/stmlib
@@ -1 +1 @@
-Subproject commit bac07fcc33cbdf4f53528ba79f8b94ee8d0093bd
+Subproject commit e5d7705dbabd7e6827057d8a30be44d0ca55c6d6