ESP32 + MEMS mic +FFT = compilation error

Hello,
I am trying to use ESP32 and SPH0645 microphone in order to analyze the frequency by Fast Fourier Transformation library, but there is the error I receive during compilation:

MEMS_mic:125:26: error: invalid types 'int32_t {aka int}[uint16_t {aka short unsigned int}]' for array subscript

     vReal[i] = sampleIn[i] << 8;

                          ^

invalid types 'int32_t {aka int}[uint16_t {aka short unsigned int}]' for array subscript

Here is my code:

#include <WiFi.h>
#include "driver/i2s.h"
#include <arduinoFFT.h>
arduinoFFT FFT = arduinoFFT(); /* Create FFT object */

const int BLOCK_SIZE = 1024;
const double samplingFrequency = 10000;
double vReal[BLOCK_SIZE];
double vImag[BLOCK_SIZE];
int32_t samples[BLOCK_SIZE];

i2s_config_t i2s_config = {
      mode: (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
      sample_rate: 44100,
      bits_per_sample: I2S_BITS_PER_SAMPLE_32BIT,
      channel_format: I2S_CHANNEL_FMT_ONLY_LEFT,
      communication_format: (i2s_comm_format_t)(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_LSB),
      intr_alloc_flags: ESP_INTR_FLAG_LEVEL1,
      dma_buf_count: 8,
      dma_buf_len : BLOCK_SIZE
     // dma_buf_len: 64
};

//  Configure whatever pins you have available and make sure you set them up with PiNmode() Before setting up i2s system
i2s_pin_config_t pin_config = {
    .bck_io_num = 25, //this is BCK pin
    .ws_io_num = 26, // this is LRCK pin
    .data_out_num = I2S_PIN_NO_CHANGE, // this is DATA output pin
    .data_in_num = 23   //DATA IN
};
const int i2s_num=0;
int retStat = 0;
int32_t sampleIn=0, avgGain=0, peaks[2]={0,0}, avgSampleIn=0;
unsigned short int numOfBlanks=2000, smoothingReads=10;

void setup()
{
  Serial.begin(115200); 
  //Turn off WIFI to save power
  WiFi.mode(WIFI_OFF);
  //Set up pin 19 for data IN from the Mic to the esp32
  pinMode(23, INPUT);
  //Set up pin 21 and 25 as the BCK and LRCK pins
  pinMode(26, OUTPUT);
  pinMode(25, OUTPUT);
  //Init the i2s device
  i2s_driver_install((i2s_port_t)i2s_num, &i2s_config, 0, NULL);
  i2s_set_pin((i2s_port_t)i2s_num, &pin_config);
  i2s_start((i2s_port_t)i2s_num);
  
  Serial.print("\r\nBegin Level detect...");
  Serial.print("\r\n\tRead 4000 samples to level out...");
  //This pulls in a bunch of samples and does nothing, its just used to settle the mics output
  for(retStat=0; retStat<numOfBlanks*2; retStat++)
  {
    i2s_pop_sample((i2s_port_t)i2s_num, (char*)&sampleIn, portMAX_DELAY);
    delay(1);
  }
  //Pull in x number of samples (IN A QUITE ENVIRONMENT) and create the base gain average(the zero point for the mic)
  Serial.print("\r\n\tRead 2000 samples to get avg...");
  for(retStat=0; retStat<numOfBlanks; retStat++)
  {
    i2s_pop_sample((i2s_port_t)i2s_num, (char*)&sampleIn, portMAX_DELAY);
    sampleIn>>=14;
    avgGain -= sampleIn;
    delay(1);
  }
  avgGain = avgGain/numOfBlanks;
  Serial.printf("\t\tAVG Gain=\t%i", avgGain);
  peaks[0]=avgGain;
  peaks[1]=-avgGain;
  Serial.printf("\r\n\tSetting MAX gain to\t%i\tMin Gain to\t%i\r\n", peaks[0], peaks[1]);
  delay(1000);
}

void loop()
{
  sampleIn=0;
  avgSampleIn=0;

  //read in smoothingReads number of times and use the average
  for(retStat=0; retStat<smoothingReads; retStat++)
  {
              //this reads 32bits as 4 chars into a 32bit INT variable
  i2s_pop_sample((i2s_port_t)i2s_num, (char*)sampleIn, portMAX_DELAY);
              //this pushes out all the unwanted bits as we only need right channel data.
    sampleIn>>=14;
    avgSampleIn+=sampleIn;
  }
  sampleIn = round((float)avgSampleIn/smoothingReads);
  

  for (uint16_t i = 0; i < BLOCK_SIZE; i++) {
    vReal[i] = sampleIn[i] << 8;
    vImag[i] = 0.0; //Imaginary part must be zeroed in case of looping to avoid wrong calculations and overflows
  }

  FFT.Windowing(vReal, BLOCK_SIZE, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
  FFT.Compute(vReal, vImag, BLOCK_SIZE, FFT_FORWARD);
  FFT.ComplexToMagnitude(vReal, vImag, BLOCK_SIZE);
 
  double x;
  double v;
  FFT.MajorPeak(vReal, BLOCK_SIZE, samplingFrequency, &x, &v);
  Serial.print(x, 6);
  Serial.print(", ");
  Serial.println(v, 6);
    delay(2000);

}

Change

 for (uint16_t i = 0; i < BLOCK_SIZE; i++) {
    vReal[i] = sampleIn[i] << 8;
    vImag[i] = 0.0; //Imaginary part must be zeroed in case of looping to avoid wrong calculations and overflows
  }

to

 for (int i = 0; i < BLOCK_SIZE; i++) {
    vReal[i] = sampleIn[i] << 8;
    vImag[i] = 0.0; //Imaginary part must be zeroed in case of looping to avoid wrong calculations and overflows
  }

is one thing.

Also the ESP has a "bug" and code such as making/using a configuration structure

i2s_config_t i2s_config = {
      mode: (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
      sample_rate: 44100,
      bits_per_sample: I2S_BITS_PER_SAMPLE_32BIT,
      channel_format: I2S_CHANNEL_FMT_ONLY_LEFT,
      communication_format: (i2s_comm_format_t)(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_LSB),
      intr_alloc_flags: ESP_INTR_FLAG_LEVEL1,
      dma_buf_count: 8,
      dma_buf_len : BLOCK_SIZE
     // dma_buf_len: 64
};

could give you errors.
Often times the entire structure configuration values are not used, if something was written to ram, previously, where the structure will be defined, the ESP does not over write that information with zeros or NULL's. So if the structure memory area is larger than the items assigned in the structure bad data may remain in the structure.

Espressif advises that the structure memory area be cleared before assigning values to the structure as in

int ESP32_SPI_API::fReadSPI( int byteReadSize, int addressToRead )
{
  spi_transaction_t trans_desc;
  trans_desc = { };
  trans_desc.addr =  0;
  trans_desc.cmd = 0;
  trans_desc.flags = 0;
  trans_desc.length = (8 * 2) + (8 * byteReadSize) ; // total data bits
  trans_desc.tx_buffer = txData;
  trans_desc.rxlength = byteReadSize * 8 ; // Number of bits NOT number of bytes
  trans_desc.rx_buffer = rxData;
  txData[0] = (uint8_t)addressToRead;
  txData[1] = 0x0;
  return spi_device_transmit( hSPI, &trans_desc);
} // int fReadSPI( int byteReadSize, int addressToRead )

This line trans_desc = { }; insures that the memory area taken up by the structure is set to default values.