Audio DSP Project for the Raspberry Pi Pico (RP2040). The project reads an I2S input stream, performs signal processing and outputs it as an I2S stream. The pico acts as the I2S master generating all required clocks (including MCLK).
DSP is done at 44.1kHz at 32 Bits fixed point. Fixed point is a hard requirement, as the RP2040 doesn't have an FPU. Running just one floating point IIR filter would require overclocking the core to 230MHz.
The I2S interfaces are realized via the PIOs.
The project takes strong influence from the pico-extras
and the arduino-pico
repositories.
The I2S communication works by using 3 PIOs. One transmitter, one receiver and a clock generator. The transmitter and receiver are clocked at the bitclock frequency (Bits * Channels * FS), while MCLK is run at it's own frequency (x * FS). These are synchronized using IRQ7. This could perhaps be consolidated into just two or even only one PIO.
Use the DAC Clocks (DAC WS and DAC BCK) for both the ADC and DAC.
The ADC Clocks are shifted by one nop
statement.
The test PCB consists of a Raspberry Pi Pico, a PCM5102A and a WM8782S on development boards. The ADC and DAC boards are supplied with +5V from the pico's VBUS connection. The ADC board requires a jumper between the V+ input and the secondary voltage regulator input to bypass the first regulator. (The primary regulator steps V+ down to +5V, as VBUS is 5V and the dropout voltage is greater than 0V, I opted to bypass it.)
The ADC is configured as:
- Slave mode
- Slave clock MCLK input (J3 = S, J1 = Don't care)
- I2S bit format
- 44.1K/48K sample rate
- 24 bit
The DAC board has no modifications and is left as-is (1L, 2L, H3, 4L).
Requires pico-sdk and pico-extras.
mkdir build
cd build
cmake ..
make
Proceed to flash the pico with the generated .elf
.
- hardware documentation
- restructure Ringbuffer ?
- Add more DSP functionality
- Cleanup unused clock outputs (I2S PIO In)
- try to optimize performance
- more docs
IIR filters using a 64 Bit accumulator require around 2.2us but enables a scaling factor for fixed point arithmetic of 30 or more. Running 5 filters at this width limits Fs to around 48kHz. Limiting the IIR's accumulator to 32 Bits drastically increases performance to enabled an Fs of 96kHz. However the scaling factor must be reduced to 15 and samples must be reduced to a width of 16 Bits. 32 Bit floating point IIR filters (in DF1) are borderline unusable unless overclocked to around 230MHz.
- The great earlevel engineering blog is a great resource for IIR Filters and various DSP subjects.
- My own projects ESP32 Bluetooth DSP and it's DSP Playground are peers to this project.