From ffbad53a21dd801c99a7b19c7a715269eb33be70 Mon Sep 17 00:00:00 2001
From: David Huss <dh@atoav.com>
Date: Fri, 16 Feb 2024 22:45:33 +0100
Subject: [PATCH] Fix Grain Settings

This commit fixes the settings for the Multi-Playback mode so it acts
more predictable

Changelog: fixed
---
 README.md                       |  2 +-
 daisyy-looper/daisyy-looper.ino |  4 +--
 daisyy-looper/looper.h          | 47 +++++++++++++++------------------
 daisyy-looper/potentiometers.h  |  2 +-
 daisyy-looper/ui.h              |  5 +++-
 5 files changed, 29 insertions(+), 31 deletions(-)

diff --git a/README.md b/README.md
index ae1d7f6..9093658 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
 software: daisyy-looper
 hardware: daisyy-hardware
 language: C++ (Arduino)
-version: 1.0.1
+version: 1.1.0
 ---
 
 # daisyy-looper
diff --git a/daisyy-looper/daisyy-looper.ino b/daisyy-looper/daisyy-looper.ino
index b19ec18..9385d51 100644
--- a/daisyy-looper/daisyy-looper.ino
+++ b/daisyy-looper/daisyy-looper.ino
@@ -442,8 +442,8 @@ void loop() {
       if (!isnan(p7)) {  lfo_amount = p7; }
       break;
     case FX_MODE_GRAIN:
-      if (!isnan(p5)) {  ui.activeLooper()->grain_count = 1+int(p5); }
-      if (!isnan(p6)) {  ui.activeLooper()->grain_spread = p6*10.0f; }
+      if (!isnan(p5)) {  ui.activeLooper()->playhead_count = 1+int(p5); }
+      if (!isnan(p6)) {  ui.activeLooper()->grain_spread = p6*5.0f; }
       if (!isnan(p7)) {  ui.activeLooper()->grain_variation = p7; }
       break;
   }
diff --git a/daisyy-looper/looper.h b/daisyy-looper/looper.h
index 594ae1a..abfa27c 100644
--- a/daisyy-looper/looper.h
+++ b/daisyy-looper/looper.h
@@ -1,9 +1,11 @@
 #pragma once
 
 #include "luts.h"
+#define N_PLAYHEADS 9
 
 namespace atoav {
 
+
 enum RecPitchMode {
   REC_PITCH_MODE_NORMAL,
   REC_PITCH_MODE_UNPITCHED,
@@ -63,7 +65,7 @@ class Head {
 };
 
 Head::Head() {
-  variation = random(-0.1f, 0.1f);
+  variation = drand(-4.0f, 4.0f);
 }
 void Head::activate() {
   this->active = true;
@@ -141,7 +143,7 @@ class Looper {
     void speedUp();
     float loop_start_f = 0.0f;
     float loop_length_f = 1.0f;
-    uint8_t grain_count = 8;
+    uint8_t playhead_count = 8;
     float grain_spread = 2.0f;
     float grain_variation = 0.0f;
     RecPitchMode rec_pitch_mode = REC_PITCH_MODE_NORMAL;
@@ -156,7 +158,7 @@ class Looper {
     float* buffer;
     size_t buffer_length = 0;
 
-    Head playheads[9];
+    Head playheads[N_PLAYHEADS];
     Head rec_head;
 
     size_t loop_start = 0;
@@ -299,17 +301,17 @@ float Looper::Process() {
   switch (playback_state) {
     case PLAYBACK_STATE_LOOP:
       playheads[0].activate();
-      for (size_t i=1; i<9; i++) {
+      for (size_t i=1; i<N_PLAYHEADS; i++) {
         playheads[i].deactivate();
       }
       break;
     case PLAYBACK_STATE_MULTILOOP:
-      for (size_t i=0; i<9; i++) {
+      for (size_t i=0; i<N_PLAYHEADS; i++) {
         playheads[i].activate();
       }
       break;
     case PLAYBACK_STATE_STOPPED:
-      for (size_t i=0; i<9; i++) {
+      for (size_t i=0; i<N_PLAYHEADS; i++) {
         playheads[i].deactivate();
       }
       break;
@@ -317,7 +319,7 @@ float Looper::Process() {
 
   double mix = 0.0;
 
-  for (size_t i=0; i<grain_count-1; i++) {
+  for (size_t i=0; i<=playhead_count; i++) {
     // Skip inactive playheads
     if (!playheads[i].isActive()) continue;
 
@@ -335,7 +337,7 @@ float Looper::Process() {
     }
 
     // Read from the buffer
-    mix += buffer[play_pos] * vol;
+    mix += buffer[play_pos] * vol * map(playhead_count, 1, N_PLAYHEADS, 1.0, 0.9);
 
     // Advance the playhead
     playheads[i].update();
@@ -355,14 +357,14 @@ float Looper::GetPlayhead() {
 
 float* Looper::GetPlayheads() {
   static float playhead_positions[9];
-  for (size_t i=0; i<9; i++) {
+  for (size_t i=0; i<N_PLAYHEADS; i++) {
     playhead_positions[i] = float(int(playheads[i].read()) % loop_length) / float(buffer_length);
   }
   return playhead_positions;
 }
 
 uint8_t Looper::GetPlayheadCount() {
-  return grain_count;
+  return playhead_count;
 }
 
 float Looper::GetRecHead() {
@@ -395,17 +397,10 @@ void Looper::setRecModeLoopShot() {
 }
 
 void Looper::setPlaybackSpeed(float increment) {
-  switch (playback_state) {
-    case PLAYBACK_STATE_LOOP:
-      playheads[0].setIncrement(increment);
-      break;
-    case PLAYBACK_STATE_MULTILOOP:
-      playheads[0].setIncrement(increment);
-      for (size_t i=1; i<9; i++) {
-        playheads[i].variation_amount = grain_variation;
-        playheads[i].setIncrement(increment + increment*grain_spread);
-      }
-      break;
+  playheads[0].setIncrement(increment);
+  for (size_t i=1; i<N_PLAYHEADS; i++) {
+    playheads[i].variation_amount = grain_variation;
+    playheads[i].setIncrement(increment + increment*grain_spread);
   }
 }
 
@@ -416,7 +411,7 @@ void Looper::addToPlayhead(float value) {
       break;
     case PLAYBACK_STATE_MULTILOOP:
       playheads[0].incrementBy(value);
-      for (size_t i=1; i<9; i++) {
+      for (size_t i=1; i<N_PLAYHEADS; i++) {
         playheads[i].incrementBy(value + value/(1+i));
       }
       break;
@@ -424,25 +419,25 @@ void Looper::addToPlayhead(float value) {
 }
 
 void Looper::slowDown() {
-  for (size_t i=0; i<9; i++) {
+  for (size_t i=0; i<N_PLAYHEADS; i++) {
     playheads[i].slowDown();
   }
 }
 
 void Looper::reverse() {
-  for (size_t i=0; i<9; i++) {
+  for (size_t i=0; i<N_PLAYHEADS; i++) {
     playheads[i].reverse();
   }
 }
 
 void Looper::restart() {
-  for (size_t i=0; i<9; i++) {
+  for (size_t i=0; i<N_PLAYHEADS; i++) {
     playheads[i].reset();
   }
 }
 
 void Looper::speedUp() {
-  for (size_t i=0; i<9; i++) {
+  for (size_t i=0; i<N_PLAYHEADS; i++) {
     playheads[i].speedUp();
   }
 }
diff --git a/daisyy-looper/potentiometers.h b/daisyy-looper/potentiometers.h
index 055264c..f429038 100644
--- a/daisyy-looper/potentiometers.h
+++ b/daisyy-looper/potentiometers.h
@@ -240,7 +240,7 @@ void Potentiometer::renderUi() {
       if (this->display_mode == POT_DISPLAY_MODE_SWITCH) {
         centeredText(switch_labels[int(last_reading+switch_offset)], x_center, y_center+4, SH110X_WHITE);
       } else if (this->display_mode == POT_DISPLAY_MODE_SWITCH_NUMBERS) {
-        sprintf(text_buffer, "%d", int(last_reading));  
+        sprintf(text_buffer, "%d", int(last_reading)+1);  
         centeredText(text_buffer, x_center, y_center+4, SH110X_WHITE);
       } else {
         centeredText(text_buffer, x_center, y_center+4, SH110X_WHITE);
diff --git a/daisyy-looper/ui.h b/daisyy-looper/ui.h
index 030f266..3f485e2 100644
--- a/daisyy-looper/ui.h
+++ b/daisyy-looper/ui.h
@@ -386,6 +386,9 @@ class Ui {
         button_1.onPress([this, n](){ 
           button_grids[n].grid_buttons_[0].next();
           activeLooper()->playback_state = (atoav::PlaybackState) (button_grids[n].grid_buttons_[0].active);
+          if (activeLooper()->playback_state == atoav::PLAYBACK_STATE_MULTILOOP) {
+            activeLooper()->grain_variation = 0.05f;
+          }
         });
 
         // Restart
@@ -621,7 +624,7 @@ class Ui {
             float* playheads = activeLooper()->GetPlayheads();
             uint8_t count = activeLooper()->GetPlayheadCount();
             int x_playhead = 0;
-            for (size_t i=0; i<count-1; i++) {
+            for (size_t i=0; i<count; i++) {
               x_playhead = int(playheads[i] * display.width()) + x_start_loop;
               int h = 6 + i*3;
               display.drawFastVLine(x_playhead, h, 3, SH110X_WHITE);
-- 
GitLab