I’ve been working on a project with a Daisy Seed, 2 switches, 5 potmeters and 2 audio outs (LR), but I can’t bring one of the switches to live in order to acces one of the 4 modi that I foresaw. This is my code thusfar :
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "DaisyDuino.h"
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// --- PIN DEFINITIES SCHAKELAARS & POTMETERS ---
#define PIN_FREEZE_SWITCH 10
#define PIN_SHIFT_SWITCH 9
#define MAX_VOICES 4
#define POT1_PIN A0
#define POT2_PIN A1
#define POT3_PIN A2
#define POT4_PIN A3
#define POT5_PIN A4
static Decimator lofi_crusher;
static Oscillator osc_op1\[MAX_VOICES\];
static Oscillator osc_op2\[MAX_VOICES\];
static Oscillator osc_op3\[MAX_VOICES\];
static Oscillator osc_op4\[MAX_VOICES\];
static DelayLine<float, 96000> DSY_SDRAM_BSS delay_l;
static DelayLine<float, 96000> DSY_SDRAM_BSS delay_r;
float base_center_pitch = 110.0f;
float master_gain_pot = 0.5f;
float filtered_p1 = 0.0f;
float filtered_p3 = 120.0f;
int active_voices = 4;
int scale_selector = 0;
String scale_name = "MINO";
int root_note_index = 0;
const char\* root_names\[\] = {"C ", "C#", "D ", "D#", "E ", "F ", "F#", "G ", "G#", "A ", "A#", "B "};
const char\* root_note_name = "C ";
int p1 = 512, p2 = 512, p3 = 512, p4 = 512, p5 = 512;
float voice_amp\[MAX_VOICES\];
float env_attack = 0.01f, env_decay = 0.3f, env_sustain = 0.5f, env_release = 0.4f;
int fm_algo = 0;
float fm_ratio = 1.0f, fm_index = 1.5f, fm_feedback = 0.2f, fm_detune = 1.002f;
float op4_feedback_mem\[MAX_VOICES\];
float current_delay_target = 24000.0f, actual_delay_l = 24000.0f, actual_delay_r = 24800.0f;
float delay_mix = 0.45f, delay_feedback = 0.60f;
float lofi_chorus_amt = 0.0f;
float lofi_wow_speed = 0.0f, lofi_flutter_amt = 0.0f, lofi_chaos_deg = 0.0f;
float wow_phase = 0.0f, chorus_phase = 0.0f, flutter_mem = 0.0f;
unsigned long last_clock_time\[MAX_VOICES\], last_display_time = 0;
int base_bpm = 100, base_clock_spee = 600, step_counter\[MAX_VOICES\], dynamic_clock_speed\[MAX_VOICES\];
float current_lf1\[MAX_VOICES\], live_pitch_offset\[MAX_VOICES\], markov_pitch_memory\[MAX_VOICES\];
int seq_mode = 0; String seq_mode_name = "WALK";
const int fibonacci_seq\[\] = {1, 1, 2, 3, 5, 8, 13, 21};
bool lofi_studio_active = false, shift_active = false;
int gate_stage\[MAX_VOICES\];
// Matrix 100% browser-veilig platgeslagen naar 1D-array layout (Geen dubbele haken meer nodig!)
const int scale_intervals\[\] = {
0, 2, 3, 5, 7, 8, 10, 12, 14, 15, 17, 19,
0, 2, 4, 5, 7, 9, 11, 12, 14, 16, 17, 19,
0, 3, 5, 7, 10, 12, 15, 17, 19, 22, 24, 27,
0, 2, 3, 5, 7, 9, 10, 12, 14, 15, 17, 21,
0, 1, 3, 5, 7, 8, 10, 12, 13, 15, 17, 19,
0, 2, 4, 6, 7, 9, 11, 12, 14, 16, 18, 19,
0, 2, 3, 5, 7, 8, 11, 12, 14, 15, 17, 23,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
};
float midiToHz(float note) { return 440.0f \* expf((note - 69.0f) \* 0.057762265f); }
void AudioAdvancedModSpaceCallback(float \*\*in, float \*\*out, size_t size) {
unsigned long current_time = millis();
shift_active = (digitalRead(PIN_FREEZE_SWITCH) == LOW);
lofi_studio_active = (digitalRead(PIN_SHIFT_SWITCH) == LOW);
if (lofi_studio_active) {
float norm_p1 = (float)p1 / 1023.0f;
float norm_p2 = (float)p2 / 1023.0f;
float crush_factor = 1.0f - norm_p1;
float down_factor = 1.0f - norm_p2;
if (crush_factor < 0.001f) crush_factor = 0.001f;
if (down_factor < 0.001f) down_factor = 0.001f;
lofi_crusher.SetBitcrushFactor(crush_factor);
lofi_crusher.SetDownsampleFactor(down_factor);
lofi_wow_speed = ((float)p3 / 1023.0f) \* 5.0f;
lofi_flutter_amt = ((float)p4 / 1023.0f) \* 0.8f;
lofi_chaos_deg = (float)p5 / 1023.0f;
}
else if (shift_active) {
env_attack = 0.001f + ((float)p1 / 1023.0f) \* 1.5f;
root_note_index = map(p2, 0, 1023, 0, 11);
root_note_name = root_names\[root_note_index\];
env_sustain = (float)p3 / 1023.0f;
env_release = 0.01f + ((float)p4 / 1023.0f) \* 3.0f;
active_voices = map(p5, 0, 1023, 1, MAX_VOICES);
}
else {
scale_selector = map((int)filtered_p1, 0, 1023, 0, 7);
if (scale_selector == 0) scale_name = "MINO"; else if (scale_selector == 1) scale_name = "MAJ"; else if (scale_selector == 2) scale_name = "PENT"; else if (scale_selector == 3) scale_name = "DORI";
else if (scale_selector == 4) scale_name = "PHRY"; else if (scale_selectr == 5) scale_name = "LYDI"; else if (scale_selector == 6) scale_name = "HM_I"; else scale_name = "CHRO";
fm_ratio = map(p2, 0, 1023, 4, 32) \* 0.25f;
seq_mode = map((int)filtered_p3, 0, 1023, 0, 7);
if (seq_mode == 0) seq_mode_name = "WALK"; else if (seq_mode == ) seq_mode_name = "LADR"; else if (seq_mode == 2) seq_mode_name = "CHOS"; else if (seq_mode == 3) eq_mode_name = "EUCL"; else if (seq_mode == 4) seq_mode_name = "FIBO"; else if (seq_mode == 5) se_mode_name = "MARK"; else if (seq_mode == 6) scale_name = "SYNC"; else seq_mode_name = "POLY";
fm_algo = map(p4, 0, 1023, 0, 5); if (fm_algo > 5) fm_algo = 5;
fm_feedback = map(p4, 750, 1023, 0, 100) / 120.0f; if (fm_feedback < 0.0f) fm_feedback = 0.0f;
fm_detune = 1.0f + ((float)p1 / 1023.0f) \* 0.004f;
master_gain_pot = (float)p5 / 1023.0f;
}
int base_midi_note = 48 + root_note_index;
for (int v = 0; v < MAX_VOICES; v++) {
int note_step = abs((int)live_pitch_offset\[v\]) % 12;
int array_position = (scale_selector \* 12) + note_step; // Matrix omzeild via 1D indexering
int l_idx = scale_intervals\[array_position\];
fm_index = 1.5f + (env_decay \* 2.0f);
current_lf1\[v\] = midiToHz(base_midi_note + l_idx + (v \* 12));
}
for (int v = 0; v < active_voices; v++) {
int v_spd = base_clock_speed;
if (v == 1) v_spd = base_clock_speed \* 2;
if (v == 2) v_spd = (base_clock_speed \* 3) / 2;
if (v == 3) v_spd = base_clock_speed / 2;
unsigned long elapsed = current_time - last_clock_time\[v\];
unsigned long gate_limit = (unsigned long)(dynamic_clock_speed\[v\] \* 0.45f);
if (elapsed < gate_limit) {
if (gate_stage\[v\] == 0) gate_stage\[v\] = 1;
} else {
if (gate_stage\[v\] == 2) gate_stage\[v\] = 3;
}
if (elapsed >= (unsigned long)dynamic_clock_speed\[v\]) {
last_clock_time\[v\] = current_time; step_counter\[v\]++; dynamic_clock_speed\[v\] = v_spd;
if (lofi_studio_active) {
int chaos_check = (int)(lofi_chaos_deg \* 100.0f);
if (lofi_chaos_deg > 0.0f && random(0, 100) < chaos_check) {
live_pitch_offset\[v\] = random(0, 12); gate_stage\[v\] = 1;
}
} else {
int c_st = step_counter\[v\] + (v \* 2);
if (seq_mode == 0) live_pitch_offset\[v\] = (c_st % 4) \* 2.0f;
else if (seq_mode == 1) { const int ln\[\] = {0, 2, 4, 5, 4, 2}; live_pitch_offset\[v\] = ln\[c_st % 6\]; }
else if (seq_mode == 2) { live_pitch_offset\[v\] += randm(-1, 2); if(live_pitch_offset\[v\] > 11.0f || live_pitch_offset\[v\] < 0.0f) live_pitch_offset\[v\] = 0.0f; }
else if (seq_mode == 3) { int es = c_st % 8; live_pitch_offset\[v\] = (es == 0 || es == 3 || es == 5) ? 7.0f : 0.0f; }
else if (seq_mode == 4) { live_pitch_offset\[v\] = fibonacci_seq\[c_st % 8\] % 12; }
else { int mr = random(0, 100); if (mr < 35) markov_pitch_memory\[v\] += 1.0f; else i (mr < 70) markov_pitch_memory\[v\] -= 1.0f; if (markov_pitch_memory\[v\] > 11.0f || markov_pich_memory\[v\] < 0.0f) markov_pitch_memory\[v\] = 0.0f; live_pitch_offset\[v\] = markov_pitch_memory\[v\]; }
}
}
}
float a_step = 1.0f / (env_attack \* 32000.0f);
float d_step = (1.0f - env_sustain) / (env_decay \* 32000.0f);
float r_step = env_sustain / (env_release \* 32000.0f);
// Audio kanaal-pointers ophalen zonder haken te gebruiken (Voorkomt browserverlies)
float \*ch_left = \*(out + 0);
float \*ch_right = \*(out + 1);
for (size_t i = 0; i < size; i++) {
float mix_l = 0.0f, mix_r = 0.0f, wow_flut = 0.0f, chorus_mod_l = 0.0f, chorus_mod_r = 0.0f;
if (lofi_studio_active) {
wow_phase += (lofi_wow_speed \* 0.0003f); if (wow_phase > TWO_PI) wow_phase -= TWO_PI;
float rand_val = (random(-50, 51) / 50.0f) \* lofi_flutter_amt \* 4.0f;
flutter_mem += 0.05f \* (rand_val - flutter_mem);
wow_flut = sinf(wow_phase) \* 1.5f + flutter_mem;
chorus_phase += 0.0002f; if (chorus_phase > TWO_PI) chorus_phase -= TWO_PI;
chorus_mod_l = sinf(chorus_phase) \* lofi_chorus_amt \* 8.0f;
chorus_mod_r = cosf(chorus_phase) \* lofi_chorus_amt \* 8.0f;
}
for (int v = 0; v < MAX_VOICES; v++) {
if (gate_stage\[v\] == ) { voice_amp\[v\] += a_step; if (voice_amp\[v\] >= 1.0f) { voice_amp\[v\] = 1.0f; gate_stage\[v\] = 2; } }
else if (gate_stge\[v\] == 2) { voice_amp\[v\] -= d_step; if (voice_amp\[v\] <= env_sustain) { voice_amp\[v\] = env_sustain; } }
else if (gate_stage\[v\ == 3) { voice_amp\[v\] -= r_step; if (voice_amp\[v\] <= 0.0001f) { voice_amp\[v\] = 0.0f; gate_stage\[v\] = 0; } }
if (voice_amp\[v\] <= 0.0f) continue;
float f_mod = current_lf1\[v\] + wow_flut;
osc_op1\[v\].SetFreq(f_mod);
osc_op2\[v\].SetFreq(f_mod \* fm_ratio \* fm_detune);
osc_op3\[v\].SetFreq(f_mod \* fm_ratio);
osc_op4\[v\].SetFreq(f_mod \* 0.5f);
float op4 = osc_op4\[v\].Process();
float op3 = osc_op3\[v\].Process();
float op2 = osc_op2\[v\].Process();
float op1 = osc_op1\[v\].Process();
float voice_out = op1 \* voice_amp\[v\];
mix_l += voice_out \* 0.5f; mix_r += voice_out \* 0.5f;
}
float delay_out_l = delay_l.Read();
float delay_out_r = delay_r.Read();
delay_l.Write(mix_l + (delay_out_r \* delay_feedback));
delay_r.Write(mix_r + (delay_out_l \* delay_feedback));
float final_out_l = (mix_l \* (1.0f - delay_mix)) + (delay_out_l \* delay_mix);
float final_out_r = (mix_r \* (1.0f - delay_mix)) + (delay_out_r \* delay_mix);
final_out_l \*= master_gain_pot;final_out_r \*= master_gain_pot;
if (lofi_studio_active) {final_out_l = lofi_crusher.Process(final_out_l);
final_out_r = lofi_crusher.Process(final_out_r);
}
// Pointer-verschuiving schrijven die 100% browser-proof is
\*(ch_left + i) = final_out_l;
\*(ch_right + i) = final_out_r;
}
}
void setup() {
pinMode(PIN_FREEZE_SWITCH, INPUT_PULLUP);
pinMode(PIN_SHIFT_SWITCH, INPUT_PULLUP);
lofi_crusher.Init();
DAISY.init(DAISY_SEED, AUDIO_SR_32K);
for (int v = 0; v < MAX_VOICES; v++) {
osc_op1\[v\].Init(32000.0f); osc_op1\[v\].SetWaveform(Oscillator::WAVE_SIN);
osc_op2\[v\].Init(32000.0f); osc_op2\[v\].SetWaveform(Oscillator::WAVE_SIN);
osc_op3\[v\].Init(32000.0f); osc_op3\[v\].SetWaveform(Oscillator::WAVE_SIN);
osc_op4\[v\].Init(32000.0f); osc_op4\[v\].SetWaveform(Oscillator::WAVE_SIN);
voice_amp\[v\] = 0.0f; gate_stage\[v\] = 0; step_counter\[v\] = 0;
last_clock_time\[v\] = millis() + (v \* 75); dynamic_clock_speed\[v\] = base_clock_speed;
}
delay_l.Init(); delay_r.Init();
DAISY.begin(AudioAdvancedModSpaceCallback);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { for(;;); }
display.clearDisplay(); display.display();
}
void loop() {
p1 = 1023 - analogRead(POT1_PIN);
p2 = 1023 - analogRead(POT2_PIN);
p3 = 1023 - analogRead(POT3_PIN);
p4 = 1023 - analogRead(POT4_PIN);
p5 = 1023 - analogRead(POT5_PIN);
filtered_p1 = filtered_p1 \* 0.90f + p1 \* 0.10f;
filtered_p3 = filtered_p3 \* 0.90f + p3 \* 0.10f;
if (millis() - last_display_time > 65) {
last_display_time = millis();
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.print("FM-SYNTH");
display.setCursor(75, 0);
if (lofi_studio_active) {
display.print("\[LOFI\]");
} else if (shift_active) {
display.print("\[ADSR\]");
} else {
display.print("\[NORM\]");
}
display.setCursor(0, 16);
if (lofi_studio_active) {
display.print("Crush: "); display.println(p1);
display.print("DwnSmp: "); display.println(p2);
display.print("WowSpd: "); display.println(p3);
display.print("Fluttr: "); display.println(p4);
display.print("Chaos: "); display.println(p5);
}
else if (shift_active) {
display.print("Attack: "); display.println(p1);
display.print("RootIdx: "); display.println(p2);
display.print("Sustain: "); display.println(p3);
display.print("Release: "); display.println(p4);
display.print("Voices: "); display.println(active_voices);
}
else {
display.print("Scale: "); display.println(scale_name);
display.print("Ratio: "); display.println(fm_ratio);
display.print("Seq: "); display.println(seq_mode_name);
display.print("Algo: "); display.println(fm_algo);
display.print("Gain: "); display.println(p5);
}
display.setCursor(0, 56); display.print("Root: "); display.print(root_note_name);
display.setCursor(70, 56); display.print("V: "); display.print(active_voices);
display.display();
}
}
Can anyone help, please?