- //
- // *20 - 200Hz Single Pole Bandpass IIR Filter
- //
- float bassFilter(float sample) {
- static float xv[3] = {0.0f, 0.0f, 0.0f};
- static float yv[3] = {0.0f, 0.0f, 0.0f};
- xv[0] = xv[1];
- xv[1] = xv[2];
- xv[2] = sample / 3.0f; //* regulacja pod siłe sygnału
- yv[0] = yv[1];
- yv[1] = yv[2];
- yv[2] = (xv[2] - xv[0])
- + (-0.7960060012f * yv[0])
- + (1.7903124146f * yv[1]);
- return yv[2];
- }
- //
- //* 10Hz Single Pole Lowpass IIR Filter
- //
- float envelopeFilter(float sample) {
- static float xv[2] = {0.0f, 0.0f};
- static float yv[2] = {0.0f, 0.0f};
- xv[0] = xv[1];
- xv[1] = sample / 50.0f;
- yv[0] = yv[1];
- yv[1] = (xv[0] + xv[1]) + (0.9875119299f * yv[0]);
- return yv[1];
- }
- //
- //* 1.7 - 3.0Hz Single Pole Bandpass IIR Filter
- //
- float beatFilter(float sample) {
- static float xv[3] = {0.0f, 0.0f, 0.0f};
- static float yv[3] = {0.0f, 0.0f, 0.0f};
- xv[0] = xv[1];
- xv[1] = xv[2];
- xv[2] = sample / 2.7f;
- yv[0] = yv[1];
- yv[1] = yv[2];
- yv[2] = (xv[2] - xv[0])
- + (-0.7169861741f * yv[0])
- + (1.4453653501f * yv[1]);
- return yv[2];
- }
- ///
- ///
- static unsigned int sampleCounter = 0;
- static unsigned long lastSampleTime = 0;
- unsigned long currentTime = micros();
- // Utrzymanie stałego tempa próbkowania: 5000Hz (co 200 µs)
- if (currentTime - lastSampleTime < SAMPLEPERIODUS) return;
- lastSampleTime = currentTime;
- // Odczyt próbki audio z kanału A0
- // Dla Pico Arduino: zakładamy, że audio jest podane na A0 (np. GPIO26)
- // Offset: dla 12-bit ADC (0-4095), środek to około 2048
- float sample = (float)analogRead(A0) - 2048.0f;
- // Przetwarzanie sygnału: filtr basów
- float value = bassFilter(sample);
- if (value < 0) value = -value;
- // Filtracja obwiedni sygnału
- float envelope = envelopeFilter(value);
- sampleCounter++;
- // Co 200 próbek (~25Hz) wykonujemy filtr beat oraz ustawiamy stan LED
- if (sampleCounter >= 200) {
- float beat = beatFilter(envelope);
- // Odczyt z potencjometru na A1 do ustawienia progu
- float thresh = 0.02f * (float)analogRead(A1);
- // Jeżeli wykryty beat przekracza próg, włącz LED
- if (beat > thresh)
- digitalWrite(LED_BUILTIN, HIGH);
- else
- digitalWrite(LED_BUILTIN, LOW);
- sampleCounter = 0;
- }
- ///