#include "AudioThread.h" #include "SharedState.h" #include #include // I2S Pin definitions // You may need to change these to match your hardware setup (e.g., for a specific DAC). const int I2S_BCLK_PIN = 9; // Bit Clock (GP9) const int I2S_LRC_PIN = 10; // Left-Right Clock (GP10) const int I2S_DOUT_PIN = 11; // Data Out (GP11) // Audio parameters const int SAMPLE_RATE = 44100; const int16_t AMPLITUDE = 16383; // Use a lower amplitude to avoid clipping (max is 32767 for 16-bit) // Create an I2S output object I2S i2s(OUTPUT); // --- Synthesizer State --- // Frequencies for a C-Major scale to pick from const float NOTE_FREQUENCIES[] = { 261.63, 293.66, 329.63, 349.23, 392.00, 440.00, 493.88, 523.25 }; const int NUM_NOTES = sizeof(NOTE_FREQUENCIES) / sizeof(NOTE_FREQUENCIES[0]); float currentFrequency = 440.0f; double phase = 0.0; unsigned long lastNoteChangeTime = 0; // --- void setupAudio() { // Configure I2S pins i2s.setBCLK(I2S_BCLK_PIN); i2s.setDATA(I2S_DOUT_PIN); // Set the sample rate and start I2S communication i2s.setFrequency(SAMPLE_RATE); if (!i2s.begin()) { Serial.println("Failed to initialize I2S!"); while (1); // Halt on error } // Seed the random number generator from an unconnected analog pin randomSeed(analogRead(A0)); } void loopAudio() { unsigned long now = millis(); // Every 500ms, pick a new random note to play if (now - lastNoteChangeTime > 500) { lastNoteChangeTime = now; int noteIndex = random(0, NUM_NOTES); currentFrequency = NOTE_FREQUENCIES[noteIndex]; Serial.println("Playing note: " + String(currentFrequency) + " Hz"); } // Generate the sine wave sample double phaseIncrement = 2.0 * M_PI * currentFrequency / SAMPLE_RATE; phase = fmod(phase + phaseIncrement, 2.0 * M_PI); int16_t sample = static_cast(AMPLITUDE * sin(phase)); // Write the same sample to both left and right channels (mono audio). // This call is blocking and will wait until there is space in the DMA buffer. i2s.write(sample); i2s.write(sample); }