I'd like some help with this issue.
I'm using Arduino IDE 2.3.4 on Windows 10 and a ESP32 board. The original author used an older Arduino verson. I tried using that and got similar compiler errors. I also used his latest versions as shown on his web page and get similar compiler errors
This is his web link: https://www.instructables.com/Portable-Sound-Analyzer-on-ESP32/
Here's the code that I'm unable to compile:
SoundAnalyzer_ESP32_TTGO.ino
/* Sound analyzer
Several display modes (spectrum, sound amplitude, envelope)
(by) Lesept October 2020
TFT_eSPI:
In the file TFT_eSPI/User_Setup_Select.h
comment this line: #include <User_Setup.h>
and uncomment this line: #include <User_Setups/Setup25_TTGO_T_Display.h>
*/
#include <Arduino.h>
#include <driver/adc.h>
#include <complex.h>
#define FREQ2IND (SAMPLES * 1.0 / MAX_FREQ)
#include "params.h"
#include <TFT_eSPI.h>
#include <SPI.h>
#define MIC 32
//Display parameters
#ifndef TFT_DISPOFF
#define TFT_DISPOFF 0x28
#endif
#ifndef TFT_SLPIN
#define TFT_SLPIN 0x10
#endif
#define TFT_MOSI 19
#define TFT_SCLK 18
#define TFT_CS 5
#define TFT_DC 16
#define TFT_RST 23
#define TFT_BL 4 // Display backlight control pin
#define ADC_EN 14 // ADC_EN is the ADC detection enable port
#define ADC_PIN 34
#define BUTTON_1 35
#define BUTTON_2 0
TFT_eSPI display = TFT_eSPI(135, 240); // Invoke custom library
unsigned long chrono, chrono1;
unsigned long sampling_period_us;
byte peak[SAMPLES] = {0};
float _Complex data[SAMPLES];
const int nTimes = 54; // number of acquisitions in a row (700 ms total)
uint16_t data2D[SAMPLES][nTimes];
int sound[SAMPLES];
float MULT = MAX_FREQ * 1000.0 / SAMPLES;
unsigned int P2P = 0;
const int LOG2SAMPLE = log(SAMPLES) / log(2);
int32_t backgroundSound = 0;
#include "functions.h"
#define MODE 19
#define MAXMODES 7
void setup() {
Serial.begin(115200);
pinMode(BUTTON_1, INPUT_PULLUP);
pinMode(BUTTON_2, INPUT_PULLUP);
adc1_config_width(ADC_WIDTH_BIT_12);
// ADC1 Channel 4 is GPIO 32 (microphone)
// https://microcontrollerslab.com/wp-content/uploads/2019/03/ESP32-ADC-channels-pinout.jpg
adc1_config_channel_atten(ADC1_CHANNEL_4, ADC_ATTEN_DB_11);
calibrate();
display.init();
display.fillScreen(TFT_BLACK);
display.setRotation(3);
display.setTextColor(TFT_BLUE);
display.drawString("on ESP32", 20, 110, 4); // Splash screen
display.setTextSize(2);
display.drawString("SONO", 0, 10, 4);
display.drawString("METER", 68, 60, 4);
display.setTextSize(1);
display.setTextColor(TFT_RED);
display.drawString("[by Lesept]", 165, 120, 2);
Serial.println("SonoMeter on ESP32");
delay(2000);
sampling_period_us = round(1000ul * (1.0 / MAX_FREQ));
chrono1 = millis();
}
void loop() {
static int modes = 0;
bool changeMode = false;
// Push the button to change modes
if (millis() - chrono1 > 1000ul) {
if (digitalRead(BUTTON_1) == LOW) { // Modes up
delay(30);
modes = (modes + 1) % MAXMODES;
changeMode = true;
chrono1 = millis();
} else if (digitalRead(BUTTON_2) == LOW) { // Modes down
delay(30);
modes = (modes - 1 + MAXMODES) % MAXMODES;
changeMode = true;
chrono1 = millis();
}
}
switch (modes) {
case 0: // Display spectrum
acquireSound();
displaySpectrum();
break;
case 1: // Display spectrum
acquireSound();
displaySpectrum2();
break;
case 2: // Display amplitude with bars
displayAmplitudeBars();
break;
case 3: // Display envelope
displayEnvelope(changeMode);
break;
case 4: // Display running amplitude
displayRunningEnvelope(changeMode);
break;
case 5: // Display Spectrogram
displaySpectrogram (changeMode, false);
break;
case 6: // Display Spectrogram with maxima in circles
displaySpectrogram (changeMode, true);
break;
default:
break;
}
// Touch GPIO 15 to stop the display
const int touchPin = 15;
const int threshold = 90;
if (touchRead(touchPin) < threshold) while (touchRead(touchPin) < threshold);
}
typedef enum fft_dir {
FFT_FORWARD, /* kernel uses "-1" sign /
FFT_INVERSE / kernel uses "+1" sign */
} fft_dir;
void window (float _Complex *data, unsigned int log2_N, byte windowType, fft_dir direction) {
unsigned int N = 1 << log2_N;
unsigned int Nd2 = N >> 1;
for (int i = 0; i < Nd2; i++) {
double indexMinusOne = double(i);
double ratio = (indexMinusOne / (N - 1));
double weighingFactor = 1.0;
// Compute and record weighting factor
switch (windowType) {
case RECTANGLE: // rectangle (box car)
weighingFactor = 1.0;
break;
case HAMMING: // hamming
weighingFactor = 0.54 - (0.46 * cos(2 * PI * ratio));
break;
case HANN: // hann
weighingFactor = 0.54 * (1.0 - cos(2 * PI * ratio));
break;
case TRIANGLE: // triangle (Bartlett)
weighingFactor = 1.0 - ((2.0 * abs(indexMinusOne - ((N - 1) / 2.0))) / (N - 1));
break;
case NUTTALL: // nuttall
weighingFactor = 0.355768 - (0.487396 * (cos(2 * PI * ratio))) + (0.144232 * (cos(4 * PI * ratio))) - (0.012604 * (cos(6 * PI * ratio)));
break;
case BLACKMAN: // blackman
weighingFactor = 0.42323 - (0.49755 * (cos(2 * PI * ratio))) + (0.07922 * (cos(4 * PI * ratio)));
break;
case BLACKMAN_NUTTALL: // blackman nuttall
weighingFactor = 0.3635819 - (0.4891775 * (cos(2 * PI * ratio))) + (0.1365995 * (cos(4 * PI * ratio))) - (0.0106411 * (cos(6 * PI * ratio)));
break;
case BLACKMAN_HARRIS: // blackman harris
weighingFactor = 0.35875 - (0.48829 * (cos(2 * PI * ratio))) + (0.14128 * (cos(4 * PI * ratio))) - (0.01168 * (cos(6 * PI * ratio)));
break;
case FLT_TOP: // flat top
weighingFactor = 0.2810639 - (0.5208972 * cos(2 * PI * ratio)) + (0.1980399 * cos(4 * PI * ratio));
break;
case WELCH: // welch
weighingFactor = 1.0 - sq((indexMinusOne - (N - 1) / 2.0) / ((N - 1) / 2.0));
break;
}
if (direction == FFT_FORWARD) {
data[i] *= weighingFactor;
data[N - (i + 1)] *= weighingFactor;
}
else {
data[i] /= weighingFactor;
data[N - (i + 1)] /= weighingFactor;
}
}
}
functions.h
void ffti_shuffle_f(float _Complex data, unsigned int log2_N)
{
/
Basic Bit-Reversal Scheme:
The incrementing pattern operations used here correspond
to the logic operations of a synchronous counter.
Incrementing a binary number simply flips a sequence of
least-significant bits, for example from 0111 to 1000.
So in order to compute the next bit-reversed index, we
have to flip a sequence of most-significant bits.
*/
unsigned int N = 1 << log2_N; /* N /
unsigned int Nd2 = N >> 1; / N/2 = number range midpoint /
unsigned int Nm1 = N - 1; / N-1 = digit mask /
unsigned int i; / index for array elements /
unsigned int j; / index for next element swap location */
for (i = 0, j = 0; i < N; i++) {
if (j > i) {
float _Complex tmp = data[i];
data[i] = data[j];
data[j] = tmp;
}
/*
Find least significant zero bit
*/
unsigned int lszb = ~i & (i + 1);
/*
Use division to bit-reverse the single bit so that we now have
the most significant zero bit
N = 2^r = 2^(m+1)
Nd2 = N/2 = 2^m
if lszb = 2^k, where k is within the range of 0...m, then
mszb = Nd2 / lszb
= 2^m / 2^k
= 2^(m-k)
= bit-reversed value of lszb
*/
unsigned int mszb = Nd2 / lszb;
/*
Toggle bits with bit-reverse mask
*/
unsigned int bits = Nm1 & ~(mszb - 1);
j ^= bits;
}
}
void ffti_evaluate_f(float _Complex data, unsigned int log2_N, fft_dir direction)
{
/
In-place FFT butterfly algorithm
input:
A[] = array of N shuffled complex values where N is a power of 2
output:
A[] = the DFT of input A[]
for r = 1 to log2(N)
m = 2^r
Wm = exp(−j2π/m)
for n = 0 to N-1 by m
Wmk = 1
for k = 0 to m/2 - 1
u = A[n + k]
t = Wmk * A[n + k + m/2]
A[n + k] = u + t
A[n + k + m/2] = u - t
Wmk = Wmk * Wm
For inverse FFT, use Wm = exp(+j2π/m)
*/
unsigned int N = 1 << log2_N;
double theta_2pi = (direction == FFT_FORWARD) ? -PI : PI;
theta_2pi *= 2;
for (unsigned int r = 1; r <= log2_N; r++)
{
unsigned int m = 1 << r;
unsigned int md2 = m >> 1;
double theta = theta_2pi / m;
double re = cos(theta);
double im = sin(theta);
double _Complex Wm = re + I * im;
for (unsigned int n = 0; n < N; n += m) {
double _Complex Wmk = 1.0f; /* Use double for precision */
for (unsigned int k = 0; k < md2; k++) {
unsigned int i_e = n + k;
unsigned int i_o = i_e + md2;
double _Complex t = Wmk * data[i_o];
data[i_o] = data[i_e] - t;
data[i_e] = data[i_e] + t;
t = Wmk * Wm;
Wmk = t;
}
}
}
}
void ffti_f(float _Complex data[], unsigned int log2_N, fft_dir direction)
{
ffti_shuffle_f(data, log2_N);
ffti_evaluate_f(data, log2_N, direction);
}
void acquireSound () {
for (int i = 0; i < SAMPLES; i++) {
unsigned long chrono = micros();
data[i] = analogRead(MIC);
while (micros() - chrono < sampling_period_us); // do nothing
} // 12.8 ms
}
void displaySpectrum () {
window (data, LOG2SAMPLE, HAMMING, FFT_FORWARD);
ffti_f(data, LOG2SAMPLE, FFT_FORWARD);
// window + FFT last 10ms
int nFreq = SAMPLES / 2;
int hauteur = display.height();
display.fillScreen(TFT_BLACK);
display.setTextColor(TFT_WHITE);
display.setTextSize(1);
const float freqs[7] = {.5, 1, 2, 3, 4, 6, 8};
for (int i = 0; i < 7; i++) {
int pos = FREQ2IND * freqs[i] * 1.9 ;
if (i == 0) display.drawString(".5", pos - 5, hauteur - 13, 2);
else display.drawString(String(freqs[i], 0), pos, hauteur - 13, 2);
}
display.drawString("kHz", display.width() - 22, hauteur - 13, 2);
const int decal = 15;
// Affichage du spectre
int ampmax = 0;
int imax = 0;
for (int i = 2; i < nFreq; i++) {
int amplitude = (int)creal(data[i]) / COEF;
if (amplitude > ampmax) {
ampmax = amplitude;
imax = i;
}
amplitude = min(amplitude, hauteur - decal);
display.drawFastVLine (i * 2, hauteur - amplitude - decal, amplitude, TFT_GREEN);
}
// Affichage fréquence de plus forte amplitude
if (ampmax > 20) {
display.setTextSize(2);
display.setTextColor(TFT_BLUE);
int freqmax = 985.0 * imax * MAX_FREQ / SAMPLES;
char texte[14];
sprintf(texte, "%4d Hz: %3d", freqmax, ampmax);
display.drawString(texte, display.width() - 145, 0, 1);
}
// Affichage et décroissance des valeurs peak
for (int i = 2; i < nFreq - 4; i = i + 4) {
int amplitude = (int)creal(data[i]);
amplitude = max(amplitude, (int)creal(data[i + 1]));
amplitude = max(amplitude, (int)creal(data[i + 2]));
amplitude = max(amplitude, (int)creal(data[i + 3]));
amplitude /= COEF;
if (amplitude > peak[i]) peak[i] = amplitude;
if (peak[i] > hauteur - decal) peak[i] = hauteur - decal;
if (peak[i] > 8) {
peak[i] -= 2; // Decay the peak
display.drawFastHLine(i * 2, hauteur - peak[i] - decal, 4, TFT_RED);
}
}
}
void rectangleGR (int x0, int w, int h) {
const uint16_t colors[8] = {TFT_DARKGREEN, TFT_GREEN, TFT_GREENYELLOW, TFT_YELLOW,
TFT_GOLD, TFT_ORANGE, TFT_RED, TFT_BROWN
};
const int decal = 15;
int x = x0 * (w + 2);
int dh = (display.height() - decal) / 8;
for (int i = 1; i < 8; i++) {
if (h > i * dh) {
int y = display.height() - decal - i * dh;
display.fillRect(x, y, w, dh, colors[i - 1]);
} else {
int y = display.height() - decal - h;
display.fillRect(x, y, w, h - (i - 1) * dh, colors[i - 1]);
break;
}
}
}
void displaySpectrum2 () {
window (data, LOG2SAMPLE, HAMMING, FFT_FORWARD);
ffti_f(data, LOG2SAMPLE, FFT_FORWARD);
int nFreq = SAMPLES / 2;
int hauteur = display.height();
display.fillScreen(TFT_BLACK);
display.setTextColor(TFT_WHITE);
display.setTextSize(1);
const float freqs[6] = {.5, 1, 1.5, 2, 3, 4};
for (int i = 0; i < 6; i++) {
int pos = FREQ2IND * freqs[i] * 3.5 ;
if (i == 0) display.drawString(".5", pos - 5, hauteur - 13, 2);
else if (i == 1) display.drawString("1", pos - 10, hauteur - 13, 2);
else if (i == 2) display.drawString("1.5", pos - 5, hauteur - 13, 2);
else display.drawString(String(freqs[i], 0), pos, hauteur - 13, 2);
}
display.drawString("kHz", display.width() - 22, hauteur - 13, 2);
const int decal = 15;
// Affichage du spectre
for (int i = 0; i < 16; i++) {
int amplitude = 0;
for (int j = 0; j < 4; j++) amplitude += abs((int)creal(data[i * 4 + j + 2]) / COEF);
amplitude = min(amplitude, hauteur - decal);
rectangleGR (i, 13, amplitude);
}
}
void displayAmplitudeBars() {
const uint16_t colors[8] = {TFT_DARKGREEN, TFT_GREEN, TFT_GREENYELLOW, TFT_YELLOW,
TFT_GOLD, TFT_ORANGE, TFT_RED, TFT_BROWN
};
int ampmax = -5000;
int ampmin = 5000;
int N = display.width();
int decal = 15;
int hauteur = display.height() - decal;
for (int i = 0; i < N; i++) {
sound[i] = analogRead(MIC);
delayMicroseconds(50);
}
display.fillScreen(TFT_BLACK);
int prevamp = 1;
for (int i = 0; i < N; i++) {
uint16_t colour;
// colour = TFT_GREEN;
// colour = colors[(i / 10) % 8];
uint16_t red = 0b11111;
uint16_t red2 = 0b00001;
if (i < N / 2) colour = (red - i * (red - red2) * 2 / N) << 11;
else colour = (i + N / 2) * 32 / N;
int amplitude = (sound[i] - SILENCE) / COEF2;
constrain(amplitude, -hauteur / 2, hauteur / 2);
if (amplitude > ampmax) ampmax = amplitude;
if (amplitude < ampmin) ampmin = amplitude;
display.drawFastVLine (i, hauteur / 2 - amplitude + decal, abs(amplitude), colour);
if (amplitude * prevamp < 0 && i > 0)
display.drawLine(i - 1, hauteur / 2 - prevamp + decal, i, hauteur / 2 - amplitude + decal, colour);
}
// Affichage plus forte amplitude
display.setTextColor(TFT_BLUE);
display.setTextSize(2);
char texte[25];
sprintf(texte, "Min: %3d, Max: %3d", ampmin, ampmax);
display.drawString(texte, 10, 0, 1);
delay(50);
}
void displayEnvelope(bool erase) {
static int i = 0;
if (i == 1 || erase) display.fillScreen(TFT_BLACK);
const int decal = 15;
const int hauteur = display.height();
const int N = display.width();
static unsigned int maxP2P = 0;
static unsigned int minP2P = 5000;
static unsigned int maxP2Pold = 0;
static unsigned int minP2Pold = 5000;
static int amplitudeold = 0;
if (i >= N || erase) {
i = 0;
maxP2P = 0;
minP2P = 5000;
maxP2Pold = 0;
minP2Pold = 5000;
}
unsigned int signalMax = 0;
unsigned int signalMin = 4096;
unsigned long chrono = micros(); // Sample window 10ms
while (micros() - chrono < 10000ul) {
int sample = analogRead(MIC) / COEF3;
if (sample > signalMax) signalMax = sample;
else if (sample < signalMin) signalMin = sample;
}
unsigned int peakToPeak = signalMax - signalMin;
int amplitude = peakToPeak - SENSITIVITY;
if (amplitude < 0) amplitude = 0;
else if (amplitude > 500) amplitude = 500;
int ampPrev = map(amplitudeold, 0, 500, hauteur - 1, decal);
int amp = map(amplitude, 0, 500, hauteur - 1, decal);
if (amplitude > maxP2P) maxP2P = amplitude;
if (amplitude < minP2P) minP2P = amplitude;
if (i > 0) display.drawLine (i - 1, ampPrev, i, amp, TFT_GREEN);
amplitudeold = amplitude;
// Affichage plus forte amplitude
if ((maxP2Pold != maxP2P) || (minP2Pold != minP2P) || (i == 0)) {
display.fillRect(0, 0, N, 15, TFT_BLACK);
display.setTextColor(TFT_BLUE);
char texte[25];
sprintf(texte, "Min : %3d, Max: %3d", minP2P, maxP2P);
display.drawString(texte, 0, 0, 1);
}
maxP2Pold = maxP2P;
minP2Pold = minP2P;
++i;
}
void displayRunningEnvelope(bool erase) {
if (erase) display.fillScreen(TFT_BLACK);
static int ampMaxOld = 0;
static int ampMinOld = 1024;
const int decal = 15;
const int hauteur = display.height();
const int N = display.width();
static int sound[240] = {0};
int save = sound[0];
for (int i = 0; i < N - 1 ; i++) sound[i] = sound[i + 1];
unsigned int signalMax = 0;
unsigned int signalMin = 4096;
unsigned long chrono = micros(); // Sample window 10ms
while (micros() - chrono < 10000ul) {
int sample = analogRead(MIC) / COEF3;
if (sample > signalMax) signalMax = sample;
else if (sample < signalMin) signalMin = sample;
}
unsigned int peakToPeak = signalMax - signalMin;
int x = peakToPeak - SENSITIVITY;
if (x < 0) x = 0;
if (x > 500) x = 500;
sound[N - 1] = map(x, 0, 500, 1, hauteur - decal);
int ampMin = 500;
int ampMax = 0;
display.drawLine (0, hauteur - save, 1, hauteur - sound[0], TFT_BLACK);
for (int j = 1; j < N; j++) {
if (sound[j] > ampMax) ampMax = sound[j];
if (sound[j] < ampMin) ampMin = sound[j];
if (ampMin == 1) ampMin = 0;
display.drawLine (j, hauteur - sound[j - 1], j + 1, hauteur - sound[j], TFT_BLACK);
display.drawLine (j - 1, hauteur - sound[j - 1], j, hauteur - sound[j], TFT_GREEN);
}
// Affichage bornes d'amplitude
if ((ampMaxOld != ampMax) || (ampMinOld != ampMin) || erase) {
display.fillRect(0, 0, N, 15, TFT_BLACK);
char texte[25];
sprintf(texte, "Min : %3d, Max: %3d", ampMin, ampMax);
display.drawString(texte, 0, 0, 1);
ampMaxOld = ampMax;
ampMinOld = ampMin;
}
}
/*
Get "ambient" volume
*/
void calibrate() {
for (int i = 0; i < 200; i++) backgroundSound += analogRead(MIC);
backgroundSound /= 200;
// Serial.print("Threshold set at ");
// Serial.println(backgroundSound);
}
bool soundDetected() {
return abs(analogRead(MIC) - backgroundSound) >= SOUND_THRESHOLD;
}
void displaySpectrogram (bool erase, bool displayMax) {
#define nCoul 20
if (erase) {
display.fillScreen(TFT_BLACK);
display.setTextColor(TFT_BLUE);
display.setTextSize(1);
display.drawString("WAITING", 65, 40, 4);
display.drawString("FOR SOUND", 40, 70, 4);
}
const int rectW = display.width() / nTimes;
const int nbFreqD = 60;
const int decal = 15;
const int rectH = (display.height() - decal) / nbFreqD;
const uint16_t colors[nCoul] = {TFT_BLACK, TFT_BLACK, TFT_BLACK, TFT_BLACK,
TFT_BLACK, TFT_BLACK, TFT_BLACK, TFT_BLACK,
TFT_BLACK, TFT_BLACK, TFT_DARKGREEN, TFT_VIOLET,
TFT_BLUE, TFT_SKYBLUE, TFT_GREEN, TFT_GREENYELLOW,
TFT_YELLOW, TFT_GOLD, TFT_ORANGE, TFT_RED //, TFT_BROWN
};
// Wait until a sound arrives
if (erase) delay(300); // to avoid the sound of the button
if (!soundDetected()) return;
// Acquire samples over the 700ms range
for (int j = 0; j < nTimes; j++) {
for (int i = 0; i < SAMPLES; i++) {
unsigned long chrono = micros();
data2D[i][j] = analogRead(MIC);
//Serial.printf("%d %d %d\n",j,i,data2D[i][j]);
while (micros() - chrono < sampling_period_us); // do nothing
} // 12.8 ms
}
// Fourier transform and display each sound
display.fillScreen(TFT_BLACK);
for (int k = 1; k < 5; k++) display.drawString(String(k), 0, display.height() - k * 25 - decal - 8, 2);
for (int k = 0; k < 8; k++) // '8' is for 700ms
display.drawString(String((float)(k / 10.0), 1), k * 30, display.height() - 13, 2);
display.drawString("s", display.width() - 7, display.height() - 13, 2);
//Histogram
// int nb[22] = {0};
int indMax0[nTimes] = {0}; int thresh0 = 400;
int indMax1[nTimes] = {0}; int thresh1 = 800;
int indMax2[nTimes] = {0}; int thresh2 = 2000;
int indMax3[nTimes] = {0}; int thresh3 = 4000;
for (int j = 0; j < nTimes; j++) {
for (int i = 0; i < SAMPLES; i++) data[i] = (float)data2D[i][j] + I * 0.0f;
window (data, LOG2SAMPLE, HAMMING, FFT_FORWARD);
ffti_f(data, LOG2SAMPLE, FFT_FORWARD);
int amplitude[nbFreqD] = {0};
for (int i = 3; i < nbFreqD; i++) {
amplitude[i] = abs((int)creal(data[i]));
if (!displayMax) {
// draw spectrogram
int iCoul = map(amplitude[i], 0, 160, 0, nCoul - 1);
if (iCoul < 0) iCoul = 0;
if (iCoul > nCoul - 1) iCoul = nCoul - 1;
// ++nb[iCoul];
int y = display.height() - decal - i * rectH;
display.fillRect((j + 2) * rectW + 3, y, rectW, rectH, colors[iCoul]);
}
}
// Search the envelopes in time - frequency
if (displayMax) {
for (int i = nbFreqD; i > 2; i--) {
if (amplitude[i] > thresh0 && indMax0[j] == 0) indMax0[j] = i;
if (amplitude[i] > thresh1 && indMax1[j] == 0) indMax1[j] = i;
if (amplitude[i] > thresh2 && indMax2[j] == 0) indMax2[j] = i;
if (amplitude[i] > thresh3 && indMax3[j] == 0) indMax3[j] = i;
}
}
}
// Print histogram
// for (int h = 0; h < nCoul; h++) Serial.printf("Colour %2d : %d\n", h, nb[h]);
// Serial.println();
display.drawString("kHz", 15, 0, 2);
if (!displayMax) {
// Display scale
int dx = 13;
int dy = (display.height() - 2 * decal) / 11;
for (int i = 9; i < nCoul; i++) {
int y = display.height() - (i - 9) * dy - decal * 2 - 3;
display.fillRect(display.width() - dx, y, dx, dy - 3, colors[i]);
display.drawRect(display.width() - dx, y, dx, dy - 3, TFT_WHITE);
}
} else {
// Display envelopes
int xp = 2 * rectW + 3;
int yp = display.height() - decal - indMax0[0] * rectH;
for (int j = 1; j < nTimes; j++) {
int x = (j + 2) * rectW + 3;
int y = display.height() - decal - indMax0[j] * rectH;
display.drawLine(xp, yp, x, y, TFT_RED);
xp = x;
yp = y;
}
xp = 2 * rectW + 3;
yp = display.height() - decal - indMax1[0] * rectH;
for (int j = 1; j < nTimes; j++) {
int x = (j + 2) * rectW + 3;
int y = display.height() - decal - indMax1[j] * rectH;
display.drawLine(xp, yp, x, y, TFT_CYAN);
xp = x;
yp = y;
}
xp = 2 * rectW + 3;
yp = display.height() - decal - indMax2[0] * rectH;
for (int j = 1; j < nTimes; j++) {
int x = (j + 2) * rectW + 3;
int y = display.height() - decal - indMax2[j] * rectH;
display.drawLine(xp, yp, x, y, TFT_BLUE);
xp = x;
yp = y;
}
xp = 2 * rectW + 3;
yp = display.height() - decal - indMax3[0] * rectH;
for (int j = 1; j < nTimes; j++) {
int x = (j + 2) * rectW + 3;
int y = display.height() - decal - indMax3[j] * rectH;
display.drawLine(xp, yp, x, y, TFT_GREEN);
xp = x;
yp = y;
}
}
}
params.h
/* Windowing type /
#define RECTANGLE 0x00 / rectangle (Box car) /
#define HAMMING 0x01 / hamming /
#define HANN 0x02 / hann /
#define TRIANGLE 0x03 / triangle (Bartlett) /
#define NUTTALL 0x04 / nuttall /
#define BLACKMAN 0x05 / blackman /
#define BLACKMAN_NUTTALL 0x06 / blackman nuttall /
#define BLACKMAN_HARRIS 0x07 / blackman harris*/
#define FLT_TOP 0x08 /* flat top /
#define WELCH 0x09 / welch */
// FFT parameters
#define SAMPLES 256
#define MAX_FREQ 20 // kHz
// Attenuation for display
#define COEF 60
#define COEF2 5
#define COEF3 3
#define SILENCE 1426
#define SENSITIVITY 30 // decrease for better sensitivity
#define SOUND_THRESHOLD 150