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