Hello,
I am integrating a SPH0645 (I attached the datasheet) I2S microphone with an IMX8MM.
When recording the resulting wav file is speed up by 2.
I am using arecord and when I specify a duration with -d it actually records for the double of the asked duration. The resulting wav file duration is "correct" and the sound is speed up. I detailed my tests at the end of the post.
My configuration is based on these posts :
- https://community.nxp.com/t5/i-MX-Processors/I2S-2-channel-mems-microphone/m-p/726626
- https://community.nxp.com/t5/i-MX-Processors/I2S-microphone-SPH0645LM4H-Driver-Implementation-with-i...
My configuration looks like this :
arch/arm64/boot/dts/freescale/imx8mm-evk.dts
/ {
[...]
sound {
compatible = "fsl,imx-audio-sph0645",
"fsl,imx-mic-sph0645";
model = "sph0645-audio";
cpu-dai = <&sai3>;
status = "okay";
};
};
&sai3 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sai3>;
assigned-clocks = <&clk IMX8MM_CLK_SAI3>;
assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
assigned-clock-rates = <24576000>;
status = "okay";
};
&iomuxc {
[...]
pinctrl_sai3: sai3grp {
fsl,pins = <
MX8MM_IOMUXC_SAI3_RXD_SAI3_RX_DATA0 0x00000116
MX8MM_IOMUXC_SAI3_TXC_SAI3_TX_BCLK 0x00001916
MX8MM_IOMUXC_SAI3_TXFS_SAI3_TX_SYNC 0x00000116
>;
};
[...]
}
You can find the driver patch attached 003-sph0645-driver.patch.
I also added supplementary debug logs to :
[...]
static int fsl_sai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq)
{
[...]
ratio = clk_rate / freq;
ret = clk_rate - ratio * freq;
printk("[fsl_sai_set_bclk][%d] clk_rate = %d, ratio = %d, ret = %d, freq = %d\r\n", id, clk_rate, ratio, ret, freq);
[...]
Tests :
time arecord -D hw:0,0 -r 48000 -f S32_LE -c 1 -d 5 -t wav -v 48000_32_1.wav
fsl_sai logs : clk_rate = 3072000, ratio = 1, ret = 0, freq = 3072000
Record time : 10s
File duration : 5s
Osciloscope clock 3.072 MHz, frame clock 48kHz
When opening the file in audacity, the configuration is correct but its length is 5 sec but it is speed up.
time arecord -D hw:0,0 -r 48000 -f S16_LE -c 1 -d 5 -t wav -v 48000_16_1.wav
fsl_sai logs : clk_rate = 3072000, ratio = 2, ret = 0, freq = 1536000
Record time : 5s
File duration : 5s
Osciloscope clock 1.536 MHz, frame clock 48kHz
Nothing on data out from the microphone (the WS = BCLK/64 is not respected here)
In audacity, the length is correct, but the configuration is 32bit and there is no sound.
time arecord -D hw:0,0 -r 48000 -f S24_LE -c 1 -d 5 -t wav -v 48000_24_1.wav
fsl_sai logs : clk_rate = 3072000, ratio = 1, ret = 768000, freq = 2304000
Error fsl-sai 30030000.sai: failed to derive required Rx rate: 2304000
When trying the same configurations with two channels the result is the same, the microphone send data only on its semi period, however in audacity both channels contain sound.
I tried different frequencies with the same results
time arecord -D hw:0,0 -r 32000 -f S32_LE -c 1 -d 5 -t wav -v 32000_32_1.wav
fsl_sai logs : clk_rate = 2048000, ratio = 1, ret = 0, freq = 2048000
Record time : 10s
File duration : 5s
Osciloscope clock 2.048 MHz, frame clock 32kHz
time arecord -D hw:0,0 -r 16000 -f S32_LE -c 1 -d 5 -t wav -v 16000_32_1.wav
fsl_sai logs : clk_rate = 1024000, ratio = 1, ret = 0, freq = 1024000
Record time : 10s
File duration : 5s
Osciloscope clock 1.024 MHz, frame clock 16kHz
Edit: I posted for the same issue on stackoverflow : https://stackoverflow.com/questions/66905698/alsa-records-double-speed
解決済! 解決策の投稿を見る。
I finally found the issue !
I don't understand it fully but it works. It's as simple as a 0 instead of a 1.
- snd_soc_dai_set_sysclk(cpu_dai, 1, bclk, SND_SOC_CLOCK_OUT);
+ snd_soc_dai_set_sysclk(cpu_dai, 0, bclk, SND_SOC_CLOCK_OUT);
I attached the fixed driver patch.
I get an error when trying to compile now on imx kernel 5.15:
```sound/soc/fsl/imx-sph0645.c:43:35: error: ‘struct snd_soc_pcm_runtime’ has no member named ‘cpu_dai’
43 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai;```