I have code that allows me to record I2S audio from the INMP441 MEMS microphone module using an ESP32. The data is read from the data out pin of the device.

When I take the Fourier transform of this signal while recording a 2 kHz tone, I get a large low-frequency noise component that seems to saturate the ADC, see below. The first has 2048 samples while the second has 8192:

Fourier transform

Fourier transform 2

I am not sure what the source of this noise is and how one can remove it.

Things that may be important:

  • I am transmitting WiFi signals at the same time I am recording.



  • 1
    \$\begingroup\$ Where are you measuring this signal? You mention it saturating the ADC but from what I can tell, the ADC is internal to the INMP441. \$\endgroup\$
    – Matt S
    Dec 28, 2022 at 21:39
  • 1
    \$\begingroup\$ The INMP441 should include a high-pass filter that attenuates those low frequencies. Presumably your signal processing has a DC bias. \$\endgroup\$
    – sh-
    Dec 28, 2022 at 21:50
  • 2
    \$\begingroup\$ 2048 point FFT with a ~8KHz sampling rate only gives you ~ 4 Hz resolution, so that peak may just be the DC offset on the signal. \$\endgroup\$ Dec 29, 2022 at 0:22
  • \$\begingroup\$ Is the device USB powered (gnd hum)? Can you try a battery(bank)? \$\endgroup\$
    – RemyHx
    Dec 29, 2022 at 5:19
  • \$\begingroup\$ Breadboard? Use really short connectors/wires, can you supply a photo of the setup? Use a bulk cap on the power rail. \$\endgroup\$
    – RemyHx
    Dec 29, 2022 at 5:24

1 Answer 1


The issue was due to the fact that my software implementation was incorrect. The microphone I am using samples using 24 bits and I did not account for this.

Previously I would read and cast sets of 2 consecutive bytes assuming each sample was two bytes where in reality each sample was three. This meant I was casting incorrectly

Reading bytes from the samples buffer and converting them to uint_16 should have been done as follows:

i2s_read((i2s_port_t)uI2SInterfaceIndex, &buffer16, 4*256, &bytesRead, 100);

int samplesRead = bytesRead / 4;
for (int i = 0; i < samplesRead; i++) {
    m_pTimeChunk->m_vvfTimeChunks[uI2SInterfaceIndex][i] = ((buffer16[4*i+2] << 8) | (buffer16[4*i+3])); 

Where every third byte is discarded and only two are used.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.