• 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

That's something I'm having trouble picturing here.
Basically, with the DSPs I'm used to (personally, two different mini-DSPs, but also a Behringer and a friend's Hypex), it's always the same: independent volume control at the DSP level allows for compression, loudness, or whatever else I don't use. In other words, whatever the input volume level, everything is still possible at the DSP level because it has its own volume control. What you call "preamp" (and which we - myself and some others - interpreted as volume control at the DSP level) is perhaps similar here to what we were used to experiencing... Basically, the independent volume at the DSP level allows lowering the "level" of the source volume without altering the signal (on the minidps the range is 0 to -128 dB...) but in order to be able to apply various and varied effects that are beyond me, except for the limiter/carrier/compressor for a tweeter, but above all to protect any output speakers that might be powered by dacs and amps without volume control).
When you talk about "digital gain control" it bothers me... And when you say, "No matter the level that you set, the USB audio output is always full scale," that confuses me even more. Because that's not at all (or at least not how I perceive it) how my DSPs work... Regarding your story about special compression imitating "Magic Boost", no problem, but for the rest it leaves me doubtful (only because I need more clarification).
The working principle for host volume control here is essentially identical to that of all other USB audio devices, with the exception of the fact that DSPi currently has no dedicated onboard master volume control.

No matter the audio device, the host always outputs USB audio at full scale (unless attenuated by a playback application such as Spotify) and simply sends the audio device a number representing the current Windows volume slider position. The device itself is responsible for using this number to control its volume. This is why certain devices seem to "ignore" the Windows volume slider.

In the firmware, we currently control volume at three levels:

- Audio input channel preamp
- Matrix mixer crosspoint gain
- Audio output channel gain * Multiplier

The input channel preamp is the "global preamp" that you see in the Console sidebar at the moment. It boosts or attenuates the level of the audio input (in this case USB) at the point where it enters the DSPi. This will soon be moved to the USB L and USB R channel pages, as there will soon be inputs other than just USB and so this will no longer be a global control.

The matrix mixer crosspoint gain determines the volume of a given input channel at the point where it is routed to an output channel. This is used for situations such as summing USB left and right to a subwoofer channel, where a gain reduction of -6dB is needed to avoid clipping.

The audio output channel gain is simply an individual volume control for each output channel, after all processing has taken place and prior to truncation to 24-bit for output. There are currently 8 of these controls (one for each output channel). The Multiplier is a float value by which all output channel gains are multiplied. When a user changes the Windows volume slider, it controls that float value.

So for example (using arbitrary numbers for simplicity), let's say that in DSPi Console, Output 1's gain is set to 100 and Output 2's gain is set to 50. The user then changes the Windows volume slider from 100 to 50. This changes the Multiplier float value from 1.0 to 0.5, which is applied to every output channel. Output 1's gain now internally becomes 50 and Output 2's gain internally becomes 25. All output channels retain the same individual relative settings in DSPi Console but become proportionally quieter at the point where they leave DSPi.

This is also where loudness compensation comes in. While the Multiplier float controls the volume of all output channels, it is also fed further back up the signal chain into the loudness compensation module (located just after the initial audio input) so that as the Windows volume slider is reduced, both the output volume and the frequency response change.

I hope this sheds some light on the current implementation. :)
 
Last edited:
What a great in detail post, very informative, thanks again for all your work!
 
Hi Troy,

Thanks again for your efforts on this project. I'm using firmware v1.1.3-beta with windows console v1.1.2b. This console version doesn't appear to support I2S pin reassignment. Is I2S output enabled by default with firmware v1.1.3-beta? If so, what is the default pinout?
 
I have ordered a set of six PCM5102A modules, which should be very helpful for comprehensive testing until I have time to design the custom DSPi prototype board with TAC5212s. This is the direct result of users' contributions to the project, so thanks again everybody.

View attachment 522581


16-channel output is possible on the RP2350, incidentally. I will be experimenting with this shortly.

Hi Troy, I have very similar modules here and found this quite helpful:

IMG_0122.PNG
 
Hi Troy,

Thanks again for your efforts on this project. I'm using firmware v1.1.3-beta with windows console v1.1.2b. This console version doesn't appear to support I2S pin reassignment. Is I2S output enabled by default with firmware v1.1.3-beta? If so, what is the default pinout?
DSPi Console for Windows will need to be updated in order to enable access to the I2S functionality. I hope to push v1.1.3 tomorrow.

Hi Troy, I have very similar modules here and found this quite helpful:

View attachment 522697
Thank you!
 
The working principle for host volume control here is essentially identical to that of all other USB audio devices, with the exception of the fact that DSPi currently has no dedicated onboard master volume control.

No matter the audio device, the host always outputs USB audio at full scale (unless attenuated by a playback application such as Spotify) and simply sends the audio device a number representing the current Windows volume slider position. The device itself is responsible for using this number to control its volume. This is why certain devices seem to "ignore" the Windows volume slider.

In the firmware, we currently control volume at three levels:

- Audio input channel preamp
- Matrix mixer crosspoint gain
- Audio output channel gain * Multiplier

The input channel preamp is the "global preamp" that you see in the Console sidebar at the moment. It boosts or attenuates the level of the audio input (in this case USB) at the point where it enters the DSPi. This will soon be moved to the USB L and USB R channel pages, as there will soon be inputs other than just USB and so this will no longer be a global control.

The matrix mixer crosspoint gain determines the volume of a given input channel at the point where it is routed to an output channel. This is used for situations such as summing USB left and right to a subwoofer channel, where a gain reduction of -6dB is needed to avoid clipping.

The audio output channel gain is simply an individual volume control for each output channel, after all processing has taken place and prior to truncation to 24-bit for output. There are currently 8 of these controls (one for each output channel). The Multiplier is a float value by which all output channel gains are multiplied. When a user changes the Windows volume slider, it controls that float value.

So for example (using arbitrary numbers for simplicity), let's say that in DSPi Console, Output 1's gain is set to 100 and Output 2's gain is set to 50. The user then changes the Windows volume slider from 100 to 50. This changes the Multiplier float value from 1.0 to 0.5, which is applied to every output channel. Output 1's gain now internally becomes 50 and Output 2's gain internally becomes 25. All output channels retain the same individual relative settings in DSPi Console but become proportionally quieter at the point where they leave DSPi.

This is also where loudness compensation comes in. While the Multiplier float controls the volume of all output channels, it is also fed further back up the signal chain into the loudness compensation module (located just after the initial audio input) so that as the Windows volume slider is reduced, both the output volume and the frequency response change.

I hope this sheds some light on the current implementation. :)
Great explanation, and it will be useful to many. But, I'm familiar with how DSPs work. I know and fully understand output gain, and that if you change the volume at the source (Software (OS slide or program slide) or digitaly via an adc/dac), that change is applied downstream. I also understand matrix gain, loudness compensation, protective attenuation/gain compression... All of this is perfectly clear to me and doesn't deviate from the behavior of any other DSP.

But when you say : "The input channel preamp is the "global preamp" that you see in the Console sidebar at the moment. It boosts or attenuates the level of the audio input (in this case USB) at the point where it enters the DSPi. This will soon be moved to the USB L and USB R channel pages, as there will soon be inputs other than just USB and so this will no longer be a global control." , that's where I have a problem.

The first thing is that if the preamp is separate for each channel (L and R), as you seem to be planning to do, it does indeed complicate the possibility of using it as an overall volume attenuator, as we can currently do.
The second, and this is related, is what will replace this possibility? From what I understand: nothing.

In one of our previous exchanges a few weeks ago, I thought you understood the benefit of having a global volume control at the DSP level, which would effectively act as a preamp.

This doesn't change the ability to adjust the volume upstream or downstream, but it does allow for centralized volume management at the DSP level. Therefore, you only need one controller/remote/app to manage the volume of all connected sources. This volume control acts exactly like a preamp; it attenuates the input signal, which remains variable, but it cannot act as a boost. It is therefore limited to 0dB. (On miniDSPs, it ranges from -127.5 to 0dB).

For example, if I set the DSP volume to -30dB, it remains at -30dB regardless of the selected source. This means that whatever the volume level of the sources, this volume will be attenuated by -30dB (and obviously whatever the preset the attenuation value remains the same whether you switch from one preset to another).

It also provides an additional layer of security for those building DIY speakers with active crossovers who have no possibility of volume attenuation between the DSP and the speaker (neither at the DAC nor the amplifier level)... and there are many in this situation!

Basically, you can switch from one source to another without worrying about the volume level of the sources because you know the DSP will attenuate them enough so that it doesn't cause any problems downstream...
 
Last edited:
Hi @Weeb Labs,
we tried modifying your firmware code to support sampling for 96khz from 48khz, we made some changes for it in the exisiting repository. But it failed. Can you suggest how can we modify the firmware in such a way it runs with the codebase you provided (https://github.com/WeebLabs/).
 

Attachments

  • Screenshot 2026-04-06 184631.jpg
    Screenshot 2026-04-06 184631.jpg
    132.3 KB · Views: 57
Great explanation, and it will be useful to many. But, I'm familiar with how DSPs work. I know and fully understand output gain, and that if you change the volume at the source (Software (OS slide or program slide) or digitaly via an adc/dac), that change is applied downstream. I also understand matrix gain, loudness compensation, protective attenuation/gain compression... All of this is perfectly clear to me and doesn't deviate from the behavior of any other DSP.

But when you say : "The input channel preamp is the "global preamp" that you see in the Console sidebar at the moment. It boosts or attenuates the level of the audio input (in this case USB) at the point where it enters the DSPi. This will soon be moved to the USB L and USB R channel pages, as there will soon be inputs other than just USB and so this will no longer be a global control." , that's where I have a problem.

The first thing is that if the preamp is separate for each channel (L and R), as you seem to be planning to do, it does indeed complicate the possibility of using it as an overall volume attenuator, as we can currently do.
The second, and this is related, is what will replace this possibility? From what I understand: nothing.

In one of our previous exchanges a few weeks ago, I thought you understood the benefit of having a global volume control at the DSP level, which would effectively act as a preamp.

This doesn't change the ability to adjust the volume upstream or downstream, but it does allow for centralized volume management at the DSP level. Therefore, you only need one controller/remote/app to manage the volume of all connected sources. This volume control acts exactly like a preamp; it attenuates the input signal, which remains variable, but it cannot act as a boost. It is therefore limited to 0dB. (On miniDSPs, it ranges from -127.5 to 0dB).

For example, if I set the DSP volume to -30dB, it remains at -30dB regardless of the selected source. This means that whatever the volume level of the sources, this volume will be attenuated by -30dB (and obviously whatever the preset the attenuation value remains the same whether you switch from one preset to another).

It also provides an additional layer of security for those building DIY speakers with active crossovers who have no possibility of volume attenuation between the DSP and the speaker (neither at the DAC nor the amplifier level)... and there are many in this situation!

Basically, you can switch from one source to another without worrying about the volume level of the sources because you know the DSP will attenuate them enough so that it doesn't cause any problems downstream...
When the input preamp is moved to the corresponding channel pages, it will be replaced with a new master volume control.
 
When the input preamp is moved to the corresponding channel pages, it will be replaced with a new master volume control.
Great.

Another thing to understand about using a DSP: "It's usually better to ensure that all DSP stages operate at close to their maximum level at all times. If the input is varied over the full range expected, the number of effective bits is reduced and the sound can become very 'grainy' at low volumes. True 24-bit systems are not usually greatly affected, but the filters and equalisers themselves also reduce effective bit depth." (Active Vs. Passive Crossovers - Rod Elliott (ESP), January 11, 2004)

Well, I imagine that with a system operating at 32-bit processing resolution, this is even less of a problem, but still, it's better to feed the DSP at maximum volume (0dB) to avoid degrading the signal during the multiple operations performed on it by the DSP. And therefore, obviously, volume control should be done at the end of the process.


Is this the plan, and if not, at what level will volume management be implemented and why ?

(And thank you for your patience. It just helps clarify things so everyone understands!)
 
Last edited:
Great.

Another thing to understand about using a DSP: "It's usually better to ensure that all DSP stages operate at close to their maximum level at all times. If the input is varied over the full range expected, the number of effective bits is reduced and the sound can become very 'grainy' at low volumes. True 24-bit systems are not usually greatly affected, but the filters and equalisers themselves also reduce effective bit depth." (Active Vs. Passive Crossovers - Rod Elliott (ESP), January 11, 2004)

Well, I imagine that with a system operating at 32-bit processing resolution, this is even less of a problem, but still, it's better to feed the DSP at maximum volume (0dB) to avoid degrading the signal during the multiple operations performed on it by the DSP. And therefore, obviously, volume control should be done at the end of the process.


Is this the plan, and if not, at what level will volume management be implemented and why ?

(And thank you for your patience. It just helps clarify things so everyone understands!)
As you mentioned, we do have 1,528dB of headroom at 32-bit float but the master volume control will become the first multiplier applied to the output gain control, followed by host volume. This will mean that the loudest possible host volume is the current master volume.

So, the output gain equation will look like this: (Output * Master Volume Multiplier) * Host Volume Multiplier
 
Last edited:
Yes, so that's what all DSPs do. Perfect !

The important thing is to ensure that the gain (or rather, the attenuation) remains constant when switching from one input to another (from one preset to another).
If, hypothetically, all inputs are at 0dB, then the output volume is limited by the DSP's volume. If the input volumes are different, then the attenuation applied by the DSP's value will necessarily be proportional to the input level. But it won't exceed the attenuation level when the inputs are at 0dB... Similarly, if the DSP's volume is at 0dB (100%), the output volume will also be at 0dB if the input volume is also at 0dB, and will vary depending on the input volume. So it's indeed the input volume that always defines the resulting output, but it will be attenuated by the DSPi's Master Volume (unless it's set to 0dB). This is a simplification, of course, because I'm obviously omitting the gains applied to the different output channels here.
 
Yes, so that's what all DSPs do. Perfect !

The important thing is to ensure that the gain (or rather, the attenuation) remains constant when switching from one input to another (from one preset to another).
If, hypothetically, all inputs are at 0dB, then the output volume is limited by the DSP's volume. If the input volumes are different, then the attenuation applied by the DSP's value will necessarily be proportional to the input level. But it won't exceed the attenuation level when the inputs are at 0dB... Similarly, if the DSP's volume is at 0dB (100%), the output volume will also be at 0dB if the input volume is also at 0dB, and will vary depending on the input volume. So it's indeed the input volume that always defines the resulting output, but it will be attenuated by the DSPi's Master Volume (unless it's set to 0dB). This is a simplification, of course, because I'm obviously omitting the gains applied to the different output channels here.
The master volume control will remain constant from one input to another but not necessarily from one preset to another. I might make it configurable in a similar fashion to the pin assignment.
 
The master volume control will remain constant from one input to another but not necessarily from one preset to another. I might make it configurable in a similar fashion to the pin assignment.

Okay, that's something!

If there's a way to configure the volume in each preset so that when you select a preset, the pre-configured volume is automatically applied (just like all the other parameters), then that will be enough. You understand the idea, which is to avoid ending up with 0dB output and sending 150W full power to an unprotected speaker driver...

Anyway, if we can switch inputs while keeping the same preset and its associated volume, that's fantastic!

Thanks for all the details!
 
I'm also thinking of another possibility, something along the lines of "parental control." Like a volume limit that can never be exceeded across all the settings/presssets, and which could only be enabled/disabled with a password to protect our little ones' eardrums. I don't know if something like that is feasible... but I suppose it's worth considering.

In fact, it seems to me that nothing of the sort exists on any DSP... obviously, it's not the main target of companies... :)
 
Last edited:
Wiim does that two separate controls

at least the Ultra


 
Hi @ALex_hha we created a fork of this same repo and tried to modify the code for 96 kHz sampling rate but after importing it on the pico its not reflecting on the gui. Although it works with the existing 48kHz release by @Weeb Labs . I am unable to figure it out how do I get the firmware for 96KHz sampling rate.
@Weeb Labs can you pls guide us in this matter :)
 
@Weeb Labs can you pls guide us in this matter :)
If memory serves, the only problem with 96KHz input at the moment is the USB descriptor packet size configuration and the endpoint stride type. If you increase .wMaxPacketSize to 582 within .core under .ep1_24 in usb_descriptors.c, that will enable 96KHz at 16-bit. For 24-bit, you will need to compute stride type per endpoint within usb_device.c in order to avoid overflowing the USB controller's 4096 bytes of DPRAM.

I will push these changes with the next beta, once my DAC modules arrive and I can confirm I2S alignment is fixed.
 
If memory serves, the only problem with 96KHz input at the moment is the USB descriptor packet size configuration and the endpoint stride type. If you increase .wMaxPacketSize to 582 within .core under .ep1_24 in usb_descriptors.c, that will enable 96KHz at 16-bit. For 24-bit, you will need to compute stride type per endpoint within usb_device.c in order to avoid overflowing the USB controller's 4096 bytes of DPRAM.

I will push these changes with the next beta, once my DAC modules arrive and I can confirm I2S alignment is fixed.
Thank you so much :)
 
Back
Top Bottom