• Welcome to ASR. There are many reviews of audio hardware and expert members to help answer your questions. Click here to have your audio equipment measured for free!

Introducing DSPi | A powerful, user friendly and open source DSP for less than a cup of coffee

I've noticed that when listening with headphones, the stereo image seems slightly shifted to the left. After some experimentation, I found that adding about 0.3 ms delay to the left channel makes the center image lock into place for me. I have a Fosi Audio ZH3.

My EQ is identical on both channels (AutoEQ profile for the Hifiman Sundara), so the effect doesn't seem to be caused by frequency response differences between left and right.

My assumption is that this is related to interaural time perception rather than the headphone itself. Since our brains use very small timing differences between ears for localization, even a fraction of a millisecond can affect where a centered signal is perceived. Delaying the left channel by ~0.3 ms appears to compensate for whatever is causing the image to lean left in my case.

I'm also using BS2B crossfeed occasionally, which made me wonder whether others have experienced a similar need for a small channel delay adjustment when fine-tuning headphone imaging.

Has anyone else measured or subjectively found a personal left/right delay offset that improves center imaging?

However, I may have found a bug or limitation in the implementation. Small delay values such as 0.3 ms do not always persist correctly. Sometimes the delay appears to reset or disappear, and values above 0.5 ms seem to be rounded to 1.0 ms. In some cases, the UI even shows the delay on both channels although it was only configured for the left channel. Has anyone else experienced this?
Could you possibly do an export of your filters and post the file? All output channels are phase locked, so it's not really possible for them to become misaligned in any way. I would suggest reapplying the Sundara profile and enabling the L/R link function. Also verify that the preamp controls for both input channels are identical.

Does the issue persist if you bypass the PEQ?
 
Yes the issue persist. I load the Filters from export. In the export i can not see any delay. I use a Mac.
Thanks for that. Could you verify that the preamp controls for both of the input and output channels are identical? A screenshot of your matrix mixer would also be very helpful.
 
I just went through your wiring guide. Am I just being numb or is there still no schematic for the SPDIF input?
I also was searching the www for TOSLINK txs and rxs.
The TOTX179 and TORX179 seem to be EOL for quite a while and are not obtainable through official channels.
On e--y they cost more than the Pi board.
Any recommendations on current types which need no additional components to work? I found something which needs a capacitor and an inductor.
Sourcing capacitors might not be an issue at all but you might have to buy a bag of inductors which again including shipping may exceed the cost of the Pi board.
I ordered from mouser in the past and shipping was more than the actual parts.
 
1780509152169.png

and then it is the same on R
1780509198561.png


1780509235500.png
 
Last edited:
I just went through your wiring guide. Am I just being numb or is there still no schematic for the SPDIF input?
I also was searching the www for TOSLINK txs and rxs.
The TOTX179 and TORX179 seem to be EOL for quite a while and are not obtainable through official channels.
On e--y they cost more than the Pi board.
Any recommendations on current types which need no additional components to work? I found something which needs a capacitor and an inductor.
Sourcing capacitors might not be an issue at all but you might have to buy a bag of inductors which again including shipping may exceed the cost of the Pi board.
I ordered from mouser in the past and shipping was more than the actual parts.
Toslink transceivers are widely available at the usual distributors (RS, Farnell, CPC, DigiKey, Mouser etc.) and generally have 3 pins, Vcc, Gnd, Vin/Vout depending on whether it's a receiver or transmitter. They usually want a capacitor around 0.1µF between Vcc and Gnd close to the connector. I don't think I've seen one that needs an inductor. The critical thing here is the operating voltage - it needs to work with a 3.3V supply. A lot of them will accept a wide range of supply voltage, including 3.3V and 5V, so check the datasheet. You also need to check which pin is which as it doesn't seem to be standard. The Cliff ones should do the job and aren't too expensive:
https://cpc.farnell.com/w/c/cable-l...rand=cliff-electronic-components&sort=P_PRICE

S/PDIF input is a bit trickier than output. This post links to a good application note that contains several ways to do it and discusses their relative strengths and weaknesses.
 
@somebodyelse Thanks a lot! The units I found were all app. 12€ a piece.
If I want TOSLINK input will it be sufficient to connect the output of the rx to the PI input ( pin 11 if I remember right ) or do I still need to re-sharpen the pulses with some logic / schmitt trigger or similar? I don´t want coax inputs to avoid any sort of ground loops.
 
@somebodyelse Thanks a lot! The units I found were all app. 12€ a piece.
If I want TOSLINK input will it be sufficient to connect the output of the rx to the PI input ( pin 11 if I remember right ) or do I still need to re-sharpen the pulses with some logic / schmitt trigger or similar? I don´t want coax inputs to avoid any sort of ground loops.
You can connect the RX directly to the GPIO. They can be found very cheaply on AliExpress.
 
Feature Request: About versioning: as an end-user it would make my life much simpler if every time you changed the driver you visibly updated the version #. imho the reason for having three numbers in version is so you can use the first number for major version, second number for minor version, and third number for build number (starting at 1 for each minor version or just absolute). If you really don't want to do that then maybe include a build date that's viewable?

Thank you.
 
I wanted a simple way to control my downstairs main DSPi system from an upstairs PC without unplugging the DSPi or running a long USB cable.

The solution I have working is a GL.iNet GL-AR300M16-Ext mini OpenWrt router. I paid £14 new on eBay. The DSPi plugs into the router's USB-A port, and the router joins my home network in Wi-Fi repeater mode. Windows then connects to the DSPi using usbip-win2, so DSPi Console sees it over the network.

Screenshot_20260604_140721_DuckDuckGo.jpg

My system is standalone: WiiM -> TOSLINK/S/PDIF -> 4-DAC DSPi build. I do not use USB audio, so the DSPi can stay permanently connected to the mini router. This is perfect for my use case because I can adjust all DSPi Console parameters remotely, including filters, PEQ, presets, output settings, pin assignments and volume control, without touching the downstairs system.

Important limitation: this is not a wireless USB audio solution. In my testing, Windows could recognise the DSPi as a USB sound device, but USB audio did not stream reliably. Treat this as a DSPi Console/control bridge only. Audio should still enter the DSPi locally, for example by S/PDIF/TOSLINK or future local I2S inputs.

Another limitation: I would not use this for firmware flashing/bootloader mode. When the DSPi enters bootloader/flash mode, the USB device disconnects/re-enumerates and the USB/IP connection is likely to eject/drop. For firmware flashing, I would still plug the DSPi directly into the PC.

Power-wise, I tested it with a 5 V / 3 A USB supply powering the router and my 4-DAC DSPi build, and stability was fine. For a more permanent or expanded build, independent DSPi/audio power and a USB data-only cable would be the cleaner option.

I have attached my setup notes/wizard guide for anyone who wants to try it.

I have also attached the PowerShell wizard as a text file named DSPi_USBIP_Setup_Wizard rather than as a direct .ps1 script, because scripts are often blocked by forum or security filters. Anyone using it should review the contents first. If happy, rename it to:

DSPi_USBIP_Setup_Wizard.ps1

Then run PowerShell as Administrator and use:

Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass

before running the script.

The wizard d prompts for the router IP and uses SSH to install the required USB/IP packages on the GL.iNet router. The wizard will install two bat files to the desktop (connect and disconect) right click open as admin and hit enter.

I have not had time to fully test the wizard but it follows the workflow I used to get mine up and running.

Tonight I will reset the router to default and run the wizard.

No VirtualHere licence needed.
 

Attachments

Last edited:
Hi @Weeb Labs

Thank you for your Great project, I'm planning to build one for my system and wanted to sanity-check my config before I start.

My plan setup: WiiM Ultra (USB out) → DSPi (Pico 2) → Topping D90 III (via S/PDIF coax) + SVS PB-1000 subwoofer (via I2S → PCM5102A DAC module).

A few questions:

1. WiiM Ultra USB audio out → DSPi: is this straightforward? I assume DSPi presents itself as a standard USB Audio Class device so the WiiM doesn't care what's downstream.

2. Wiring: does this look correct?

S/PDIF out (Slot 0 → D90 III):
GPIO 6 → 75Ω resistor → RCA center pin
GND → RCA shield

I2S out (Slot 1 → PCM5102A → sub):
GPIO 7 → PCM5102A DIN
GPIO 14 → PCM5102A BCK
GPIO 15 → PCM5102A LRCK
3.3V → PCM5102A VCC
GND → PCM5102A GND
PCM5102A LOUT → RCA → SVS PB-1000 L input

Since I'm not using PDM, Core 1 should run in EQ Worker mode and all Out 1–8 stay available — is that right?

3. PEQ allocation — my plan is:
- Master L/R (PASS 2): room correction filters from REW
- Out L/R (PASS 5): LR24 HPF @ 80Hz (2× HP biquad Q=0.707 cascaded)
- Sub (PASS 5): LR24 LPF @ 80Hz + sub-specific room mode cuts

Does applying crossover at the output stage (PASS 5) rather than Master make sense here, or is there a better approach?
 
Hi @Weeb Labs

Thank you for your Great project, I'm planning to build one for my system and wanted to sanity-check my config before I start.

My plan setup: WiiM Ultra (USB out) → DSPi (Pico 2) → Topping D90 III (via S/PDIF coax) + SVS PB-1000 subwoofer (via I2S → PCM5102A DAC module).

A few questions:

1. WiiM Ultra USB audio out → DSPi: is this straightforward? I assume DSPi presents itself as a standard USB Audio Class device so the WiiM doesn't care what's downstream.

2. Wiring: does this look correct?

S/PDIF out (Slot 0 → D90 III):
GPIO 6 → 75Ω resistor → RCA center pin
GND → RCA shield

I2S out (Slot 1 → PCM5102A → sub):
GPIO 7 → PCM5102A DIN
GPIO 14 → PCM5102A BCK
GPIO 15 → PCM5102A LRCK
3.3V → PCM5102A VCC
GND → PCM5102A GND
PCM5102A LOUT → RCA → SVS PB-1000 L input

Since I'm not using PDM, Core 1 should run in EQ Worker mode and all Out 1–8 stay available — is that right?

3. PEQ allocation — my plan is:
- Master L/R (PASS 2): room correction filters from REW
- Out L/R (PASS 5): LR24 HPF @ 80Hz (2× HP biquad Q=0.707 cascaded)
- Sub (PASS 5): LR24 LPF @ 80Hz + sub-specific room mode cuts

Does applying crossover at the output stage (PASS 5) rather than Master make sense here, or is there a better approach?
Hello and thank you for the kind words!

Your plan looks very well thought out. DSPi does indeed enumerate as a standard UAC1 audio device and your WiiM will be perfectly happy.

Here is the correct SPDIF output circuit:

1780906161019.jpeg


Assuming your PCM5102A DAC is the common purple one, it needs 5V for VIN.

With PDM disabled, all eight output channels are available. Crossovers or driver correction should ideally be handled on the output channels and room correction on the input channels. :)
 
Thank you @Weeb Labs

I have virtually no experience or knowledge about programming and electronics. However, with Claude's help, I believe I can complete this project.
I have created a very basic build guide and wiring diagram with Claude's assistance. These are very basic and designed for beginners like me.
If you have time, could you please review this and point out any errors? I would greatly appreciate your feedback.

DSPi Build Guide — KEF R3 + SVS PB-1000

Goals

Add a DSP processor to the system to achieve:
  • Independent PEQ for the sub channel (separate from mains)
  • Time alignment for the subwoofer
  • Proper LR24 crossover (replacing the SVS internal LPF at 12 dB/oct)
  • Direct REW filter import

Final Signal Chain

Code:
WiiM Ultra (USB out, volume control)
  → USB → Raspberry Pi Pico 2 / RP2350 (DSPi firmware)
      → S/PDIF coaxial (Slot 0, GPIO 6) → D90 III Discrete (fixed output, 5V XLR)
          → 2× LA90 Discrete Mono (G=L) → KEF R3
      → I2S (Slot 1, GPIO 7) → PCM5102A DAC module → SVS PB-1000 (RCA analog in)
Sub signal taken directly from DSPi via PCM5102A.


DSPi Signal Pipeline (RP2350)

Code:
USB Input (WiiM Ultra)
  → PASS 1: Per-channel preamp (L/R gain)
  → PASS 2: Master EQ (10 bands/channel — room correction PEQ)
  → PASS 4: Matrix Mixer (2×9)
  → PASS 5: Per-Output EQ (10 bands/channel) → Gain/Mute → Delay
      → Slot 0 Out 1-2 (S/PDIF) → D90 III → main chain
      → Slot 1 Out 3-4 (I2S)   → PCM5102A → SVS PB-1000
PDM output (GPIO 10) not used → Core 1 runs in EQ Worker mode → all Out 1–8 available.


Parts List

ItemNotesEstimated Cost
Raspberry Pi Pico 2 (RP2350)Buy the with headers version (pins pre-soldered)~$7
PCM5102A I2S DAC moduleAliExpress/local, search "PCM5102A module" — buy the purple board~$3–5
Breadboard 400 or 830 tie pointsFor prototyping without soldering~$2–3
Jumper wires (male-to-male + male-to-female)Assorted pack ~40 wires~$2
330Ω resistorS/PDIF R1 — 1 piece<$1
100Ω resistorS/PDIF R2 — 1 piece<$1
100nF ceramic capacitorS/PDIF C1 — 1 piece<$1
RCA female panel mount jackFor S/PDIF coax out only — 1 piece~$1–2
3.5mm to RCA cableFor PCM5102A LINE OUT → SVS PB-1000~$2–3
Soldering iron + solderOnly needed for the 2 RCA jacks~$8–12
Total: ~$25–30 USD


Wiring

S/PDIF Coaxial Output (Slot 0 → D90 III)

Circuit confirmed by the DSPi author:
Code:
Pico 2 GPIO 6 ──→ [C1: 100nF] ──→ [R1: 330Ω] ──→ RCA jack center pin
                                         |
                                   [R2: 100Ω]
                                         |
                                        GND
Pico 2 GND ──────────────────────────────────→ RCA jack shield
RCA jack ──→ coax RCA cable ──→ D90 III COAX IN
  • C1 (100nF ceramic): DC blocking — prevents GPIO offset from reaching the DAC
  • R1 (330Ω): Series resistor — reduces voltage
  • R2 (100Ω): Pull-down to GND — voltage divider to meet S/PDIF spec (~0.5V RMS)

I2S Output (Slot 1 → PCM5102A → SVS PB-1000)

Code:
Pico 2 GPIO 7  ──→ PCM5102A DIN    (I2S DATA, Slot 1)
Pico 2 GPIO 14 ──→ PCM5102A BCK    (shared I2S bit clock)
Pico 2 GPIO 15 ──→ PCM5102A IRCK   (word clock — labeled IRCK on purple module, = LRCK)
Pico 2 5V      ──→ PCM5102A VIN    (5V — VBUS pin on Pico, NOT 3.3V)
Pico 2 GND     ──→ PCM5102A GND

PCM5102A LINE OUT (3.5mm jack) ──→ 3.5mm-to-RCA cable ──→ SVS PB-1000 L input
Important: The purple PCM5102A module requires 5V on VIN (VBUS, Pin 40 on Pico 2), not 3.3V. The word clock pin is labeled IRCK on this module (equivalent to LRCK).
Use the LINE OUT 3.5mm jack for the sub output — plug a standard 3.5mm-to-RCA cable directly into it. No soldering needed on the PCM5102A side. Only the S/PDIF RCA jack requires soldering.

All connections on breadboard — only solder 1 RCA jack

Pico 2 and PCM5102A plug directly into the breadboard; connect with jumper wires. Only the S/PDIF RCA jack needs soldering. The sub output uses the PCM5102A LINE OUT 3.5mm jack with a standard cable — no soldering required.

Soldering — S/PDIF RCA Jack Only

Only 1 RCA jack needs soldering (S/PDIF out). The sub uses the PCM5102A 3.5mm jack directly.
Each RCA jack has 2 terminals on the back:
  • Center pin terminal → signal wire
  • Tab/shield terminal → GND wire
Technique: heat the terminal for 2–3 seconds → apply solder → let cool. No prolonged heat needed.


Firmware

  1. Hold the BOOTSEL button on the Pico 2
  2. Plug USB into Mac → Pico appears as a USB drive
  3. Drag and drop DSPi.uf2 onto the drive (use the RP2350 build)
  4. Pico reboots automatically, DSPi is running
Download: github.com/WeebLabs/DSPi


DSPi Console — Configuration

First step: Set Master Volume to 0 dB

DSPi boots with Master Volume = −20 dB by default. Set it to 0 dB immediately after flashing — volume is controlled exclusively by WiiM Ultra.

Slot Assignment

SlotGPIOOutput TypeDestinationFunction
Slot 0GPIO 6S/PDIFD90 III COAX INMain L/R
Slot 1GPIO 7I2SPCM5102A → SVSSub (mono)

Matrix Mixer (2×9)

InputOutputEnableGain
LOut 1 (Main L)0 dB
ROut 2 (Main R)0 dB
LOut 3 (Sub)0 dB
ROut 3 (Sub)0 dB

PEQ Band Allocation

Each channel has 10 bands. Recommended allocation (confirmed by DSPi author):
Master L / Master R (PASS 2 — room correction):
  • Bands 1–6: Room correction PEQ from REW (cuts only, 20–400 Hz)
  • Bands 7–8: House curve (Low Shelf ~200 Hz, ~1 dB/oct)
  • Bands 9–10: Reserve
Out L / Out R — Slot 0 S/PDIF (PASS 5 — crossover):
  • Band 1: HP @ 80 Hz, Q=0.707 (Butterworth biquad 1)
  • Band 2: HP @ 80 Hz, Q=0.707 (Butterworth biquad 2) → cascade = LR24
  • Bands 3–10: Reserve
Sub — Slot 1 I2S (PASS 5 — crossover + sub correction):
  • Band 1: LP @ 80 Hz, Q=0.707 (Butterworth biquad 1)
  • Band 2: LP @ 80 Hz, Q=0.707 (Butterworth biquad 2) → cascade = LR24
  • Band 3: Sub-specific PEQ (~49 Hz room mode, cut only)
  • Bands 4–10: Reserve

SVS PB-1000 Settings When Using DSPi

  • Internal LPF: set to MAX (160 Hz) — DSPi handles the LR24 crossover at 80 Hz. Leaving SVS at 80 Hz causes double filtering and excessive sub roll-off.
  • Phase: set to 0° — LR24 is an even-order crossover; mains and sub are in-phase at the crossover point. Start at 0°, verify with REW. Do not carry over the 180° setting from the old setup.
  • SVS volume/gain: set to midpoint, fine-tune via DSPi output gain + REW.

Sub Level Calibration

D90 III XLR out = 5V RMS → LA90 mains. PCM5102A out ≈ 2.1V RMS → SVS PB-1000. Fixed difference ~7.5 dB — compensate using the SVS PB-1000 volume knob directly. Keep DSPi Sub output gain at 0 dB.
This is cleaner than boosting in DSPi: analog attenuation at the sub is the right place to trim level, and avoids any risk of digital clipping from gain staging in the DSP chain.
Calibration: measure SPL with REW at the listening position, compare sub vs mains, adjust SVS volume knob until levels match.

Delay (Time Alignment)

Code:
Sub distance from front wall:  56 cm → listener-to-sub ≈ 234 cm
Main distance from front wall: 63 cm → listener-to-main ≈ 227 cm
Δ = 7 cm → sub delay ≈ 0.2 ms
Enter this value in the Sub output delay field. Fine-tune using REW step response.

REW Filter Import

File → Import → REW format → assign to Master L or Master R bands.

Gain Setting — LA90 Discrete Mono

Use G=L (Low gain).
  • G=L input sensitivity: 6.9V RMS for full power
  • D90 III at 5V cannot reach theoretical full power, but still delivers ~80W+ — more than enough for 80–85 dB @ 2.8m listening levels (~1–3W needed)
  • Benefit: WiiM operates at ~−25 dB attenuation instead of ~−35 dB (G=H) → less digital attenuation → ~20.5 effective bits vs ~18

Volume Control

  • WiiM Ultra: primary volume control
  • D90 III: fixed output (DAC only, no volume)
  • DSPi Master Volume: set to 0 dB, leave it there

Quality Notes

  • S/PDIF jitter: Not a concern — Pico 2 uses a fixed 307.2 MHz clock; D90 III has solid clock recovery.
  • Breadboard noise: No impact — all signals here are digital. A loose connection causes dropouts, not noise.
  • Processing noise: Float 32-bit on RP2350 gives a ~−150 dB noise floor — well below the D90 III's own SNR. Fully transparent.
  • Ground loop: If a 50 Hz hum appears from the sub after assembly, add a ferrite bead on the PCM5102A GND wire.

REW Measurements

Measure L+sub and R+sub separately.
PEQ correction must match what the ear actually hears — the combined response of main + sub at the listening position, including phase interaction at the crossover and room modes. Measuring each source in isolation is useful for diagnostics, but not for generating correction filters.


Deployment Order

  1. Flash DSPi firmware (RP2350 build) onto Pico 2
  2. Open DSPi Console → set Master Volume to 0 dB
  3. Assemble breadboard: Pico 2 + PCM5102A + S/PDIF circuit (C1/R1/R2) + jumper wires
  4. Verify signal in DSPi Console (live metering) before soldering anything
  5. Solder 1 RCA jack (S/PDIF); connect to D90 III COAX IN. Plug 3.5mm-to-RCA cable into PCM5102A LINE OUT → SVS PB-1000 L input
  6. Set LA90 Discrete Mono → G=L
  7. Set SVS PB-1000: LPF → 160 Hz (max), Phase → 0°
  8. Configure DSPi Console: slot types, matrix mixer, LR24 crossover bands
  9. Calibrate sub level: adjust SVS PB-1000 volume knob until sub SPL matches mains at listening position (measure with REW). Keep DSPi Sub output gain at 0 dB.
  10. Measure with REW: L+sub and R+sub separately at listening position
  11. Generate PEQ filters in REW → import into Master L and Master R bands
  12. Apply sub-specific PEQ (~49 Hz) in Sub output bands
  13. Fine-tune sub delay using REW step response
  14. Apply house curve in Master L/R bands
  15. Save preset in DSPi Console — configuration is lost on reboot if not saved

System: WiiM Ultra → DSPi/Pico 2 → D90 III Discrete (fixed) → 2× LA90 Mono (G=L) → KEF R3 Non-Meta + SVS PB-1000 Wiring and PEQ strategy confirmed by DSPi author on ASR
 

Attachments

  • 1780910857562.png
    1780910857562.png
    234.2 KB · Views: 83
Hi @longts : A couple of thoughts:

1) You might consider using an Adafruit PCM51xx dac. They are a great small company and have three different PCM dacs - and for another $2 you can get the PCM5122 which is noticeably higher quality. I like Adafruit and have tested their PCM5102 and PCM5122 dacs and while the capacitor part quality isn't outstanding it's competent and probably better than random Aliexpress. Also, they spec the DAC at 3.3V usable, which is what I used to test with.

2) SPDIF is relatively high frequency and unless you build a PCB I would avoid having the SPDIF output pin right next to the I2S pin. There are lots of alternative pins available in DSPi that are physically farther away from the output data.

3) Raspberry Pi usually recommend the Vsys 5V output pin rather than the VBus 5V pin for peripherals since it adds some protection.
 
..you can get the PCM5122 which is noticeably higher quality. I like Adafruit and have tested their PCM5102 and PCM5122 dacs and while the capacitor part quality isn't outstanding it's competent and probably better than random Aliexpress.
What is this based on? Measurements or a hunch?
 
What is this based on? Measurements or a hunch?
The measured performance of the common purple boards is excellent, so I would only recommend spending the additional money on a 5122 if the slightly lower noise floor is needed for some specific reason.

index.png



Thank you @Weeb Labs

I have virtually no experience or knowledge about programming and electronics. However, with Claude's help, I believe I can complete this project.
I have created a very basic build guide and wiring diagram with Claude's assistance. These are very basic and designed for beginners like me.
If you have time, could you please review this and point out any errors? I would greatly appreciate your feedback.

DSPi Build Guide — KEF R3 + SVS PB-1000

Goals

Add a DSP processor to the system to achieve:
  • Independent PEQ for the sub channel (separate from mains)
  • Time alignment for the subwoofer
  • Proper LR24 crossover (replacing the SVS internal LPF at 12 dB/oct)
  • Direct REW filter import

Final Signal Chain

Code:
WiiM Ultra (USB out, volume control)
  → USB → Raspberry Pi Pico 2 / RP2350 (DSPi firmware)
      → S/PDIF coaxial (Slot 0, GPIO 6) → D90 III Discrete (fixed output, 5V XLR)
          → 2× LA90 Discrete Mono (G=L) → KEF R3
      → I2S (Slot 1, GPIO 7) → PCM5102A DAC module → SVS PB-1000 (RCA analog in)
Sub signal taken directly from DSPi via PCM5102A.


DSPi Signal Pipeline (RP2350)

Code:
USB Input (WiiM Ultra)
  → PASS 1: Per-channel preamp (L/R gain)
  → PASS 2: Master EQ (10 bands/channel — room correction PEQ)
  → PASS 4: Matrix Mixer (2×9)
  → PASS 5: Per-Output EQ (10 bands/channel) → Gain/Mute → Delay
      → Slot 0 Out 1-2 (S/PDIF) → D90 III → main chain
      → Slot 1 Out 3-4 (I2S)   → PCM5102A → SVS PB-1000
PDM output (GPIO 10) not used → Core 1 runs in EQ Worker mode → all Out 1–8 available.


Parts List


ItemNotesEstimated Cost
Raspberry Pi Pico 2 (RP2350)Buy the with headers version (pins pre-soldered)~$7
PCM5102A I2S DAC moduleAliExpress/local, search "PCM5102A module" — buy the purple board~$3–5
Breadboard 400 or 830 tie pointsFor prototyping without soldering~$2–3
Jumper wires (male-to-male + male-to-female)Assorted pack ~40 wires~$2
330Ω resistorS/PDIF R1 — 1 piece<$1
100Ω resistorS/PDIF R2 — 1 piece<$1
100nF ceramic capacitorS/PDIF C1 — 1 piece<$1
RCA female panel mount jackFor S/PDIF coax out only — 1 piece~$1–2
3.5mm to RCA cableFor PCM5102A LINE OUT → SVS PB-1000~$2–3
Soldering iron + solderOnly needed for the 2 RCA jacks~$8–12
Total: ~$25–30 USD

Wiring

S/PDIF Coaxial Output (Slot 0 → D90 III)

Circuit confirmed by the DSPi author:
Code:
Pico 2 GPIO 6 ──→ [C1: 100nF] ──→ [R1: 330Ω] ──→ RCA jack center pin
                                         |
                                   [R2: 100Ω]
                                         |
                                        GND
Pico 2 GND ──────────────────────────────────→ RCA jack shield
RCA jack ──→ coax RCA cable ──→ D90 III COAX IN
  • C1 (100nF ceramic): DC blocking — prevents GPIO offset from reaching the DAC
  • R1 (330Ω): Series resistor — reduces voltage
  • R2 (100Ω): Pull-down to GND — voltage divider to meet S/PDIF spec (~0.5V RMS)

I2S Output (Slot 1 → PCM5102A → SVS PB-1000)

Code:
Pico 2 GPIO 7  ──→ PCM5102A DIN    (I2S DATA, Slot 1)
Pico 2 GPIO 14 ──→ PCM5102A BCK    (shared I2S bit clock)
Pico 2 GPIO 15 ──→ PCM5102A IRCK   (word clock — labeled IRCK on purple module, = LRCK)
Pico 2 5V      ──→ PCM5102A VIN    (5V — VBUS pin on Pico, NOT 3.3V)
Pico 2 GND     ──→ PCM5102A GND

PCM5102A LINE OUT (3.5mm jack) ──→ 3.5mm-to-RCA cable ──→ SVS PB-1000 L input
Important: The purple PCM5102A module requires 5V on VIN (VBUS, Pin 40 on Pico 2), not 3.3V. The word clock pin is labeled IRCK on this module (equivalent to LRCK).
Use the LINE OUT 3.5mm jack for the sub output — plug a standard 3.5mm-to-RCA cable directly into it. No soldering needed on the PCM5102A side. Only the S/PDIF RCA jack requires soldering.

All connections on breadboard — only solder 1 RCA jack

Pico 2 and PCM5102A plug directly into the breadboard; connect with jumper wires. Only the S/PDIF RCA jack needs soldering. The sub output uses the PCM5102A LINE OUT 3.5mm jack with a standard cable — no soldering required.

Soldering — S/PDIF RCA Jack Only

Only 1 RCA jack needs soldering (S/PDIF out). The sub uses the PCM5102A 3.5mm jack directly.
Each RCA jack has 2 terminals on the back:

  • Center pin terminal → signal wire
  • Tab/shield terminal → GND wire
Technique: heat the terminal for 2–3 seconds → apply solder → let cool. No prolonged heat needed.

Firmware


  1. Hold the BOOTSEL button on the Pico 2
  2. Plug USB into Mac → Pico appears as a USB drive
  3. Drag and drop DSPi.uf2 onto the drive (use the RP2350 build)
  4. Pico reboots automatically, DSPi is running
Download: github.com/WeebLabs/DSPi

DSPi Console — Configuration

First step: Set Master Volume to 0 dB

DSPi boots with Master Volume = −20 dB by default. Set it to 0 dB immediately after flashing — volume is controlled exclusively by WiiM Ultra.

Slot Assignment


SlotGPIOOutput TypeDestinationFunction
Slot 0GPIO 6S/PDIFD90 III COAX INMain L/R
Slot 1GPIO 7I2SPCM5102A → SVSSub (mono)

Matrix Mixer (2×9)


InputOutputEnableGain
LOut 1 (Main L)0 dB
ROut 2 (Main R)0 dB
LOut 3 (Sub)0 dB
ROut 3 (Sub)0 dB

PEQ Band Allocation

Each channel has 10 bands. Recommended allocation (confirmed by DSPi author):
Master L / Master R (PASS 2 — room correction):


  • Bands 1–6: Room correction PEQ from REW (cuts only, 20–400 Hz)
  • Bands 7–8: House curve (Low Shelf ~200 Hz, ~1 dB/oct)
  • Bands 9–10: Reserve
Out L / Out R — Slot 0 S/PDIF (PASS 5 — crossover):

  • Band 1: HP @ 80 Hz, Q=0.707 (Butterworth biquad 1)
  • Band 2: HP @ 80 Hz, Q=0.707 (Butterworth biquad 2) → cascade = LR24
  • Bands 3–10: Reserve
Sub — Slot 1 I2S (PASS 5 — crossover + sub correction):

  • Band 1: LP @ 80 Hz, Q=0.707 (Butterworth biquad 1)
  • Band 2: LP @ 80 Hz, Q=0.707 (Butterworth biquad 2) → cascade = LR24
  • Band 3: Sub-specific PEQ (~49 Hz room mode, cut only)
  • Bands 4–10: Reserve

SVS PB-1000 Settings When Using DSPi

  • Internal LPF: set to MAX (160 Hz) — DSPi handles the LR24 crossover at 80 Hz. Leaving SVS at 80 Hz causes double filtering and excessive sub roll-off.
  • Phase: set to 0° — LR24 is an even-order crossover; mains and sub are in-phase at the crossover point. Start at 0°, verify with REW. Do not carry over the 180° setting from the old setup.
  • SVS volume/gain: set to midpoint, fine-tune via DSPi output gain + REW.

Sub Level Calibration

D90 III XLR out = 5V RMS → LA90 mains. PCM5102A out ≈ 2.1V RMS → SVS PB-1000. Fixed difference ~7.5 dB — compensate using the SVS PB-1000 volume knob directly. Keep DSPi Sub output gain at 0 dB.
This is cleaner than boosting in DSPi: analog attenuation at the sub is the right place to trim level, and avoids any risk of digital clipping from gain staging in the DSP chain.
Calibration: measure SPL with REW at the listening position, compare sub vs mains, adjust SVS volume knob until levels match.

Delay (Time Alignment)

Code:
Sub distance from front wall:  56 cm → listener-to-sub ≈ 234 cm
Main distance from front wall: 63 cm → listener-to-main ≈ 227 cm
Δ = 7 cm → sub delay ≈ 0.2 ms
Enter this value in the Sub output delay field. Fine-tune using REW step response.

REW Filter Import

File → Import → REW format → assign to Master L or Master R bands.

Gain Setting — LA90 Discrete Mono

Use G=L (Low gain).
  • G=L input sensitivity: 6.9V RMS for full power
  • D90 III at 5V cannot reach theoretical full power, but still delivers ~80W+ — more than enough for 80–85 dB @ 2.8m listening levels (~1–3W needed)
  • Benefit: WiiM operates at ~−25 dB attenuation instead of ~−35 dB (G=H) → less digital attenuation → ~20.5 effective bits vs ~18

Volume Control

  • WiiM Ultra: primary volume control
  • D90 III: fixed output (DAC only, no volume)
  • DSPi Master Volume: set to 0 dB, leave it there

Quality Notes

  • S/PDIF jitter: Not a concern — Pico 2 uses a fixed 307.2 MHz clock; D90 III has solid clock recovery.
  • Breadboard noise: No impact — all signals here are digital. A loose connection causes dropouts, not noise.
  • Processing noise: Float 32-bit on RP2350 gives a ~−150 dB noise floor — well below the D90 III's own SNR. Fully transparent.
  • Ground loop: If a 50 Hz hum appears from the sub after assembly, add a ferrite bead on the PCM5102A GND wire.

REW Measurements

Measure L+sub and R+sub separately.
PEQ correction must match what the ear actually hears — the combined response of main + sub at the listening position, including phase interaction at the crossover and room modes. Measuring each source in isolation is useful for diagnostics, but not for generating correction filters.


Deployment Order

  1. Flash DSPi firmware (RP2350 build) onto Pico 2
  2. Open DSPi Console → set Master Volume to 0 dB
  3. Assemble breadboard: Pico 2 + PCM5102A + S/PDIF circuit (C1/R1/R2) + jumper wires
  4. Verify signal in DSPi Console (live metering) before soldering anything
  5. Solder 1 RCA jack (S/PDIF); connect to D90 III COAX IN. Plug 3.5mm-to-RCA cable into PCM5102A LINE OUT → SVS PB-1000 L input
  6. Set LA90 Discrete Mono → G=L
  7. Set SVS PB-1000: LPF → 160 Hz (max), Phase → 0°
  8. Configure DSPi Console: slot types, matrix mixer, LR24 crossover bands
  9. Calibrate sub level: adjust SVS PB-1000 volume knob until sub SPL matches mains at listening position (measure with REW). Keep DSPi Sub output gain at 0 dB.
  10. Measure with REW: L+sub and R+sub separately at listening position
  11. Generate PEQ filters in REW → import into Master L and Master R bands
  12. Apply sub-specific PEQ (~49 Hz) in Sub output bands
  13. Fine-tune sub delay using REW step response
  14. Apply house curve in Master L/R bands
  15. Save preset in DSPi Console — configuration is lost on reboot if not saved

System: WiiM Ultra → DSPi/Pico 2 → D90 III Discrete (fixed) → 2× LA90 Mono (G=L) → KEF R3 Non-Meta + SVS PB-1000 Wiring and PEQ strategy confirmed by DSPi author on ASR
Claude's plan is generally correct but one consideration here is the volume control. Claude recommends using the WiiM as your sole volume control and while this will certainly work, it means that you won't be able to make use of the loudness compensated volume control available on DSPi. My suggestion would be to treat User Volume on DSPi as your primary volume control, unless you don't intend to use the loudness compensation.

Additionally, I would question Claude's decision to "immediately set master volume to 0dB" upon first boot. The purpose of master volume is to function as a safety net that prevents you from accidentally destroying speakers with sudden loud noises. This is especially important during the initial setup, as it is not necessarily a given that your wiring will be correct on the first attempt.

Claude also did not mention External Mute Control, which is quite important when using an I2S output. The EMC output needs to be connected to your DAC's mute pin so that it can be muted automatically during system state transitions that might otherwise produce loud pops or clicks.
 
Last edited:
Back
Top Bottom