esp-idf
esp-idf copied to clipboard
ESP32S3 - PDM (Master Rx) - Over 104kHz not working (originally -- IDFGH-13234) (IDFGH-14902)
I have made your suggested change to the pdm driver, but the audio still doesn't seem to be working correctly.
Any chance you could try this on one of your development boards that includes a PDM microphone? Maybe you could use the PDM Microphone Recording example and modify it to work at 192,000Hz ?
Thanks! -Tim
Originally posted by @timsterc in #14169
Hi @timsterc, could you describe more detailedly about the issue? Like, did it can run successfully but the sampled audio seems not correct? Or the program still report error when setting the sample rate to 192KHz?
From the information I collect, there are several challenges for your scheme (i.e., sample ultrasonic by normal PDM microphone):
- Frequency response range limitation (most electret microphones have an effective range of ≤ 50kHz, but the bat's ultrasonic might reach 200KHz)
- Low ultrasonic sensitivity (may require preamplifier)
So, I guess you may need a preamplifier and filter to get the expected data.
Another possible scheme is to use an ultrasonic receiver to replace the PDM microphone, and also need a preamplifier and filter to get the proper analog data, then convert it to digital by an ADC (whose sample rate better to be higher than 400 KHz), lastly, read the digital data from ADC via SPI or I2S interface.
@L-KAYA -- ok, I just pulled the latest 5.4 release, made the suggested changes (in the prior thread) and it's now behaving much better above 104kHz! I think that might have done the trick. If you can keep this open for another week or so, I'll post any further questions if they arise.
Thanks! -Tim
@timsterc Glad to hear that, this issue will keep open~ I'm looking forward to your good news!
@L-KAYA Next question -- I'm wondering if it is an option to bypass the PDM to PCM conversion?
I made this modification in the i2s_ll.h file in esp-idf-5.4 -- in hopes that I might be able to gain access to the raw PDM bit stream, so that I could perform my own filtering / decimation.
/**
- @brief Enable RX PDM mode.
- @param hw Peripheral I2S hardware instance address. */ static inline void i2s_ll_rx_enable_pdm(i2s_dev_t *hw) { hw->rx_conf.rx_pdm_en = true; hw->rx_conf.rx_tdm_en = false; //hw->rx_conf.rx_pdm2pcm_en = true; hw->rx_conf.rx_pdm2pcm_en = false; }
Unfortunately, it's not looking promising when I made the change and attempt to perform my own filtering and decimation.
@timsterc This feature has been supported on the master branch, you can take a try with it first. It will be released in the next minor version v5.5.
@L-KAYA -- could you elaborate on the RAW format? I have (2) microphones -- Left and Right -- does the RAW configuration respect MONO or would it always be L/R interleaved?
Also curious when v5.5 (even RC1) might be ready? While I'm keen to experiment a bit, I would prefer to have something that's stable.
@timsterc Sure, there is no much difference on the configuration compare to the current one, you can choose either both slots or any one of them.
But if you use the raw PDM format, the PDM2PCM converter will be bypassed, and the converter coefficients will no longer take effect.
And you will still receive the data in 16 bits for each slot, but the catenated raw data will look like 0001100110111101 1111110011110000 1100000010000000, whose value is represented by the density of 1. You need to realize a FIR filter in the software to convert it into PCM format.
@L-KAYA -- I'm making some progress, using the raw format, but would be curious if you're able to share any details on the FIR / decimation scheme that is employed by the on-chip PDM to PCM converter.
I've tried a number of different approaches, but am continuing to get a fairly large amount of higher frequency noise.
In this example, I've set things up for Raw Format, running at 3.072MHz for a 48kHz sampling rate (64:1 effective decimation ratio) I'm speaking a few words, which can be seen down ~1kHz.
@L-KAYA -- just a ping to see if you have any thoughts?
TBH, I did not find a good enough FIR filter yet, I tried some simple FIR filter but not perform well. It needs far more effort to finalize the algorithm, which is supposed to be universal, flexible and well performed.
@L-KAYA -- I've continued to try -- FIR filtering the Raw PDM data, but am not able to get anywhere near how clean the PCM data is, even at 48kHz. Are you guys 100% sure that the Raw PDM stream is working correctly?
@timsterc Maybe take a try with this filter, I've tested locally, it worked, but still have some background noise.
Usage
- Compile the source file
gcc -I. -o pcmpdm pcmpdm.c -lm
- Receive the raw PDM binary data to the host (via TCP or SD card)
- Convert the raw PDM binary data into PCM format
./pcmpdm -i <raw_pdm_binary> -o <output_file> -c pdm2pcm -m <downsample_rate, 128 or 64> -f <pdm_oversample_clock_freq, like 1024000>
@L-KAYA -- I apprecaite you sharing the C files. I've tried them, but am indeed getting a rather lot of background noise -- far more than when I use the built-in PDM to PCM conversion within the ESP32S3.
Is there any way to obtain the C equivalent of what is done in the ESP32S3's I2S module?
@L-KAYA -- just bumping in hopes of a comment.
@timsterc Sorry for the late reply, here is an example of the software PDM2PCM converter, maybe you can take a try first
0001-feat-i2s_pdm-add-raw-pdm-to-pcm-conversion-example.patch