I finally managed to record with a pdm microphone a 16 bits pcm, 192000Hz, mono channel signal and a 32 bits pcm, 96000Hz, mono channel signal. I'm using a RPi 3.B
Here are the steps:
1/ I picked this loader to have a soundcard showing up in alsa. https://github.com/PaulCreaser/rpi-i2s-audio. I compiled it and put it in /lib/modules/$(uname -r) which is 4.14.79-v7+ for me. I added "my_loader" in /etc/modules which is the name of the .ko file compiled. I also added "snd-bcm2835", i'm not sure if it's necessary but i did it anyway.
2/ I modified bcm2835-i2s.c to fix the clock rate (bclk_rate) at 1536000 somewhere after the 380th line. You also have to add the following lines before it writes it in the register.
Be carefull, the PDMN is only for 32bits, you can comment it or put a condition to get a 16 bits signal.
Code: Select all
mode |= BCM2835_I2S_PDMN; // 32 bits mode |= BCM2835_I2S_PDME; regmap_write(dev->i2s_regmap, BCM2835_I2S_MODE_A_REG, mode);
Then I compiled it and replace /lib/modules/$(uname -r)/kernel/sound/soc/bcm/snd-soc_bcm2538-i2s.ko with this new module.
3/ The output format is either 16 bit unsigned (for 16 bits) and 20 bits unsigned (for 32 bits). So you have to create a program which delete the offset -32767 (for 16 bits) and -524287 (for 32 bits). This allows you to convert the signal in signed signal, to be able to observe it in audacity.
If you consider modifying the sampling_rate, you can either switch from 16 bits to 32 bits or change the bclk_rate. This depends on the hardware you are using.
I think this is some kind of cheesy way to do it, but it works fine for me.
By the way, if you want to record the 20 bits signal, you can record it in 32 bits by shifting the bits of each sample by 12 (or multiply by 4096), otherwise your signal will be super small in audacity.
I hope this could help you