From 560598ea6ebca6855f379ddf54dea9b7c5f04a16 Mon Sep 17 00:00:00 2001
From: David Huss <dh@atoav.com>
Date: Thu, 29 Jun 2023 19:15:44 +0200
Subject: [PATCH] Add sigh, gate input

---
 Soft/Drum/Drum.ino | 123 +++++++++++++++++++++++++++++++++------------
 1 file changed, 91 insertions(+), 32 deletions(-)

diff --git a/Soft/Drum/Drum.ino b/Soft/Drum/Drum.ino
index 655ba06..579d2ec 100644
--- a/Soft/Drum/Drum.ino
+++ b/Soft/Drum/Drum.ino
@@ -9,12 +9,23 @@
 #define DEBUG_MODE false
 #define SAMPLES 512
 
+// KICKDRUM SETTINGS
+#define KICK_BASE_FREQ 0.15
+#define KICK_FREQ_RANGE 2.0
+#define KICK_SIGH_DELAY_MS 300
+#define KICK_SIGH_AMOUNT 0.02
+#define KICK_SIGH_SPEED 0.0004
+
+
 int wave[SAMPLES];
+
 float volume_envelope = 0.0;
 float pitch_envelope = 0.0;
+float pitch_sigh = 0.0;
 
+double last_trigger = 0;
 
-bool push_sw, old_push_sw;//push sw
+bool gate_high, old_gate_high;//push sw
 int freq_pot;
 float osc_freq;
 
@@ -23,14 +34,20 @@ float volume_decay;
 
 int inv_pot;
 float pitch_decay;
+float pitch_envelope_amount;
+float pitch_sigh_amount = KICK_SIGH_AMOUNT;
+float pitch_sigh_speed = KICK_SIGH_SPEED;
+float sigh_incrementer = 0.0;
+
+int voct_input;
 
 float osc_progress = 0;
 int slice_num = 0;
-int is_on = 0;
 
 
 
 void setup() {
+  Serial.begin(9600);
   // Mode select switch is a On-Off-On switch with the outer pins connected
   // to the pins 0 and 1. 
   pinMode(MODESWITCH_PIN_A, INPUT_PULLUP);
@@ -38,9 +55,11 @@ void setup() {
 
   // Push Button
   pinMode(PUSHBUTTON_PIN, INPUT_PULLUP);//push sw
+  // delay(1000);
 
   for (int i = 0; i < SAMPLES; i++) {
-    wave[i] = (sin(2 * M_PI * i  / 512)) * 511;
+    wave[i] = (sin(2 * M_PI * i  / SAMPLES)) * 511;
+    // Serial.println(wave[i]);
   }
 
   //-------------------PWM setting-------------------------------
@@ -61,55 +80,95 @@ void setup() {
 
 void loop() {
   // put your main code here, to run repeatedly:
-  old_push_sw = push_sw;
+  old_gate_high = gate_high;
   freq_pot = analogRead(FREQ_POT_PIN);
   chord_pot = map(analogRead(CHORD_POT_PIN), 0, 1023, 1023, 0);
   inv_pot = map(analogRead(INV_POT_PIN), 0, 1023, 1023, 0);
+  voct_input = analogRead(VOCT_PIN);
+  // Serial.println(voct_input);
 
-  osc_freq = 0.15 + freq_pot/1023.0;
-  volume_decay = 0.00002 + (float)chord_pot/1023.0/1000.0;
-  float _pitch_decay = (inv_pot/1023.0);
-  pitch_decay = 0.00001 + (float)inv_pot/1023.0/500.0;
+  osc_freq = KICK_BASE_FREQ + freq_pot/1023.0*KICK_FREQ_RANGE;
+  // Bigger decay values make the envelope shorter
+  volume_decay = 0.000005 + (float)chord_pot/1023.0/3000.0;
+  pitch_decay = 0.00001 + (float)inv_pot/1023.0/300.0;
+  // Increase the amount of the pitch envelope if the pitch decay is longer
+  pitch_envelope_amount = 0.5 + (1023.0-(float)inv_pot)/1023.0*1.5;
 
   //  -------------------push sw , play wave-------------------------------
-  push_sw = digitalRead(PUSHBUTTON_PIN);
-  // TODO: Add propper debouncing for the button here
-  if (push_sw == 0 && old_push_sw == 1) {//when push sw ON
-    // Change the selected waveform and ensure the selection is within bounds+1
-    //
-  }
-  if (push_sw == 0) {
-    is_on = 1;
-    if (old_push_sw == 1) {
-      osc_progress = 0;
-      volume_envelope = 1.0;
-      pitch_envelope = 2.0;
+  readGates();
+  
+  updateKickEnvelopes();
+}
+
+void updateKickEnvelopes() {
+  // Increment the pitch sigh (a slight rise in pitch after 
+  // the initial pitch envelope)
+  if ((millis() - last_trigger) > KICK_SIGH_DELAY_MS) {
+    sigh_incrementer += pitch_sigh_speed;
+    if (sigh_incrementer < 3.1415) {
+      pitch_sigh = max(0.0, sin(sigh_incrementer));
+    } else {
+      pitch_sigh = 0.0;
     }
-  }else {
-    is_on = 0;
+  }
+
+  // Decrement the pitch envelope
+  pitch_envelope -= pitch_decay;
+  if (pitch_envelope < 0.0001) {
+    pitch_envelope = 0.0;
   }
 }
 
 
-// Timer that pushes out the actual audio. 
+// Timer that pushes out the actual audio with a fixed frequency
+// Code inside this block needs to be fast in order to meet the deadlines
 void on_pwm_wrap() {
   pwm_clear_irq(slice_num);
-
-  pitch_envelope -= pitch_decay;
-  if (pitch_envelope < 0.0001) {
-    pitch_envelope = 0.0;
+  
+  // Decrement the volume envelope
+  volume_envelope -= volume_decay;
+  if (volume_envelope < 0.0001) {
+    volume_envelope = 0.0;
   }
 
-  osc_progress += osc_freq + pitch_envelope;
+  // Set the output to the actual level
+  pwm_set_chan_level(slice_num, PWM_CHAN_A, volume_envelope*wave[(int)osc_progress]/2+511);
 
+  // Advance the oscillator and reset it if it reached the end
+  osc_progress += osc_freq + pitch_envelope + pitch_sigh * pitch_sigh_amount;
   if (osc_progress > SAMPLES) {
     osc_progress = 0;
   }
+}
 
-  volume_envelope -= volume_decay;
-  if (volume_envelope < 0.0001) {
-    volume_envelope = 0.0;
+// Reads the push button and V/Oct Input in order to trigger the gate
+void readGates() {
+  // Read the push button
+  gate_high = !digitalRead(PUSHBUTTON_PIN);
+
+  // If there is a value bigger than 1 on the V/Oct Input, trigger the drum
+  if (voct_input > 512) { gate_high = 1; }
+
+  // If the module is first starting, supress any accidental triggering
+  if (millis() < 500) { gate_high = 0; }
+
+  // If there is a gate
+  if (gate_high == 1) {
+    // Trigger only on first rising flank
+    if (old_gate_high == 0) {
+      // Reset the oscillator and the envelopes
+      osc_progress = 0;
+      last_trigger = millis();
+      resetEnvelopes();
+    }
   }
+}
 
-  pwm_set_chan_level(slice_num, PWM_CHAN_A, volume_envelope*wave[(int)osc_progress]/2+511);
+
+
+void resetEnvelopes() {
+  volume_envelope = 1.0;
+  pitch_envelope = pitch_envelope_amount;
+  pitch_sigh = 0.0;
+  sigh_incrementer = 0.0;
 }
\ No newline at end of file
-- 
GitLab