Bad Audio Quality with Adafruit SPH0645LM4H breakout board (I2S Mic)

Does anyone have any experience using the SPH0645LM4H Microphone in terms of sound quality? I used it to record a 2Khz tone from a nearby tone generator+speaker, and the recording was awful. Where you could barely hear the tone over the noise, but IRL the tone was of decent loudness.

I don’t expect nearly as much noise in the recording. I’ve tried numerous sample rates, and bit depth setting and nothing seems to give me the expected quality. I initially started with a bit depth of 32, but later changed that to 24.

Here is how I set up the SW.

1.) Install Jetpack 4.3 from the SD Card Image

2.) Configure the I2S pins for the Adafruit I2S Mic

Maximize the Terminal windows, and run the following.
sudo find /opt/nvidia/jetson-io/ -mindepth 1 -maxdepth 1 -type d -exec touch {}/ \; sudo mkdir /boot/dtb
sudo cp -v /boot/tegra210-p3448-0000-p3449-0000-[ab]0[02].dtb /boot/dtb/ sudo /opt/nvidia/jetson-io/

Under “Configure Jetson for compatible devices” select the Adafruit SPH0645LM4H, and then save/reboot.

3.) Verify it by making sure the pinmux configuration is good.

Open the terminal window and run the follow. Everything should match except dout which isn’t used.

$sudo grep dap4 /sys/kernel/debug/tegra_pinctrl_reg
Bank: 1 Reg: 0x70003144 Val: 0x00000044 -> dap4_fs_pj4
Bank: 1 Reg: 0x70003148 Val: 0x00000054 -> dap4_din_pj5
Bank: 1 Reg: 0x7000314c Val: 0x00000004 -> dap4_dout_pj6
Bank: 1 Reg: 0x70003150 Val: 0x00000044 -> dap4_sclk_pj7

4.) Set the Mixer controls, and assign the ADMAIF1. The ADMAIF is the DMA interface to the APE (Audio Processing Image). There is 10 of them on the Tegra210.

Reset Mixer Controls
$alsactl init tegrasndt210ref

Map I2S4 to ADMAIF1
amixer -c tegrasndt210ref sget "ADMAIF1 Mux" amixer -c tegrasndt210ref sget “I2S4 Mux”

Make sure that the 'MVC1 Channels" is set to 0
amixer -c tegrasndt210ref sget ‘MVC1 Channels’

5.) Record from the microphone

$ arecord -D hw:tegrasnd210ref,0 -r 48000 -f S24_LE -c 1 -d 10 test.wav

Have you confirmed that your connections are solid and correct?

Can you provide an audio sample?

In troubleshooting the issue with a second assembly I did determine that if I record with a bit depth of 24 that it will sound horrible when the wav file is copied over to my computer and played in VLC. But, it doesn’t sound anywhere near as bad when played with aplay on the Jetson Nano.

If I record with a bit depth of 32 then it’s not too bad on either system. So I’m not sure what’s going on with that.

In either case it’s not nearly as sensitive as I was hoping for.

I did order a USB Microphone with a similar Mic so when that comes in I’ll do a comparison test.

Here is a link to the zip file with different recordings. The recording starts with nothing, and then a tone generator outputs a 2khz sine wave.


According to the datasheet for the MEMS mic [0] it states …

“The SPH0645LM4H microphone operates as an I2S
slave. The master must provide the BCLK and WS
signals. The Over Sampling Rate is fixed at 64 therefore
the WS signal must be BCLK/64 and synchronized
to the BCLK. Clock frequencies from 2.048Mhz to
4.096MHz are supported so sampling rates from 32KHz
to 64KHz can be had by changing the clock frequency.”

According to the above, the BCLK needs to be 64 periods for each frame and so I always use S32_LE for capturing from these mics. Note you can connect two of these to the I2S interface; one for left and one for right.




Thanks. I did start with S32_LE as that was the only thing that initially worked. But, then for some reason 16bit along with 24bit worked or at least appeared to.

In any case I’m sticking with S32_LE, and making sure to keep the sample rate at or under 64KHz.

One other aspect I’m a bit confused about is the BCLK frequency. Is this something that gets changed automatically with sample rate. Or is it something I need to set somehow?


The bit clock frequency is based upon the sample-rate, sample-size and number of channels. So it will automatically scale with these parameters. You can check the rate via the debugfs …

$ sudo grep i2s4 /sys/kernel/debug/clk/clk_summary