using a Raspberry Pi 4 as a USB DSP-DAC

Status
This old topic is closed. If you want to reopen this topic, contact a moderator using the "Report Post" button.
WOO-HOO ! ! ! It works. Well, I figured it would. :D

I have Gstreamer installed under Windows 10 on my laptop. I am playing some random audio thru the laptop speakers using VLC.

On the laptop, in a command terminal, I run the command:
Code:
c:\gstreamer\1.0\X86_64\bin\gst-launch-1.0.exe wasapisrc ! queue ! audioconvert ! rtpL16pay ! udpsink host=192.168.2.2 port=1234

The above command payloads 16 bit audio into RTP and sends it using UDP to the IP address of the USB ethernet gadget that I set up earlier. The exact IP address depends on what has chosen as the static IP on the Pi for the USB ethernet gadget.

On the Pi I am using my GSASysCon software to receive the stream and send it to the HDMI HAT, to which I have a pair of headphones plugged in. GSASysCon constructs and runs the following Gstreamer pipeline:

Code:
gst-launch-1.0 udpsrc port=1234 caps='application/x-rtp,media=audio,clock-rate=48000,channels=2,payload=96' ! rtpjitterbuffer latency=100 ! rtpL16depay ! queue ! audioconvert ! audio/x-raw,format=F32LE ! deinterleave name=input   input.src_0 ! tee name=input_ch0   input.src_1 ! tee name=input_ch1   audiointerleave name=output0 latency=100000000 ! queue ! alsasink device='hw:0,1'   input_ch0. ! queue ! audioconvert ! 'audio/x-raw,format=S16LE,channel-mask=(bitmask)0x1' ! output0.sink_0     input_ch1. ! queue ! audioconvert ! 'audio/x-raw,format=S16LE,channel-mask=(bitmask)0x2' ! output0.sink_1

Don't try to write that command by hand... you will make an error somewhere. Heck I haven't even added any LADSPA DSP yet. Gstreamer pipelines follow a logic but can be quite complicated, and this is why I wrote GSASysCon: to make the whole process easier for the user.

In any case, I can now use the PI to implement a multichannel (up to 8 output channels) DSP crossover, with plug-and-play USB connectivity. Without trying to reduce it in any way, the end-to-end latency is about 500msec. I guesstimated this by changing the volume in VLC and listening for the change in my headphones.
 
After finally getting the setup working via the USB ethernet gadget interface, I took a step back to think about what is going on and the pros and cons, trying to keep in mind what the overall goal is: a DAC plus DSP capabilities that can be connected to a host (e.g Windows) computer via USB.


USB Audio Gadget Interface
PROS:
Appears on the host as an audio device. You just make this the default playback device and all audio will be routed over the USB to the Pi. Simple!
CONS:
Doesn't function under Windows! The driver needs improving and who knows when this will happen (if ever).
On the host, the audio device can only have one sample rate and bit depth, and that is configured on the Pi side, at bootup. Other formats must be resampled/adapted to it.

USB Ethernet Gadget Interface

PROS:
It works!
Can support multiple sample rates and the bit depth can be 16 or 24 bits.​
CONS:
When sample rate or bit depth is changed, the streaming pipelines on the host and the Pi must be restarted.
Because it is snooping the output of a host audio device via WASAPI, it is limited to the formats supported by that device. One workaround might be to use VB-Cable (I will try this soon).
Requires a host-side app to stream the audio over the gadget connection (e.g. Gstreamer, ffmpeg, etc.). Although this can be automated as a batch file, it is more complicated than the audio gadget on the host side.


DSP/DAC on the Pi side of the Connection:
Regardless of which USB Gadget is used to transmit the audio data, how that data is handled on the Pi-side of the connection is the same. The differences lie primarily on the host side in terms of how easy the audio functionality can be implemented and in the flexibility of the audio format. Although I use Gstreamer to do all of the Pi-side tasks, this could also be handled by other applications (two are usually needed) such as ffmpeg or VLC to receive the audio data, combined with ecasound for DSP (for those who are more familiar with these apps).
 
I looked into how to automate the startup scripts on host and Pi. Looks like it is doable.

Up until this point, both my "host" and "client" (e.g. Pi where DSP, amps, and speakers are located) machines were running some form of linux. A script (GSASysCon) running on the host would SSH into a client and run commands (e.g. Gstreamer pipelines) there, and then log out. It's all automated and smooth. It's all controlled by a multi-user interface. Nice!

Now we have a different scenario with the USB ethernet gadget connection - similar in some respects, but different. GSASysCon can't run on the "host" because the host is a Windows box and GSASysCon is a bash script. While you could run it in WSL, that is even one level MORE complicated. In this case, there is really only this one "local" client, connected by the USB cable to the host. What is needed is a way for the user to click on a single icon and that starts everything up and audio comes out of the Pi's DAC.

It turns out that this can be done using some different kinds of Windows scripting and a batch file to automate all of it.. The batch file would test for an open connection to the Pi, launch the Gstreamer pipeline on the host to stream Windows audio, and then use the program Plink, which is included when you install Putty, an SSH client/server program. Pink logs into the Pi over the USB ethernet connection and runs a script there. In this case, it can be GSASysCon, or just the Gstreamer pipeline itself. The only part of GSASysCon that wouldn't be available would be volume control, where an automated interface uses amixer commands to adjust the DAC's alsa volume controls. Instead, volume would be controlled at the source, in Windows.

I think all of this would work seamlessly to start up the playback chain. At this point I am not sure how to shut it all down, especially on the Windows side, without multiple actions by the user, but maybe that is not of too much concern. In fact, the Pi Gstreamer pipelines could be executed at startup and just left "on" the entire time. If no RTP stream is present I think one consisting of zeros is used, so it is essentially "off". On the Windows side, the user would have to kill the batch file and that would end the audio feed.
 
I also want point out that connecting the Pi in this way to a host computer via a USB ethernet gadget connection is yet another way to get around the fact that, while there are lots and lots of DACs (HATs, USB, etc.) that can run on the Pi, there are not so many ADCs or digital input boards. Since the audio will come via USB ethernet, there is no need for "input hardware". It's streamed instead.

Also, this is much more straightforward compared to actually using the Pi's ethernet port and having both the Pi and the host on a LAN. That is because to do so would require knowing the IP addresses of the machines. Many people (including me) might want to use DHCP and/or take the host+Pi based system somewhere else. There, a new network that is not under your control will assign some new IP addresses to both machines, and you will need to figure these out. Or you can try your luck with creating your own internet hotspot just for the host and Pi, but that is another can of worms.

Instead, using the USB ethernet gadget, you always have the same address for the Pi and this is hardcoded into the host thru RNDIS and it doesn't matter what dhcp is doing. DHCP is not part of that connection.

Now I do use streaming clients in my home with GSASysCon, and there I just put them on the LAN and assign each one a fixed IP address via my router. So that CAN be done, but you are kind of stuck there. I have been looking for a way to bring a loudspeaker system including its software crossover run by GSASysCon to local DIY events, and this would be a good way because of the permanence of the USB gadget connection.
 
Last edited:
I also want point out that connecting the Pi in this way to a host computer via a USB ethernet gadget connection is yet another way to get around the fact that, while there are lots and lots of DACs (HATs, USB, etc.) that can run on the Pi, there are not so many ADCs or digital input boards. Since the audio will come via USB ethernet, there is no need for "input hardware". It's streamed instead.

Not sure I follow you here.....an ADC is still needed somewhere upstream so what is the advantage of ADC>PC>USB Pi/gadget vs ADC HAT>Pi... ?
 
I was trying to emphasize that you do not need an ADC to get the audio in to the Pi when there are digital ways to do so. It wasn't so much that the source would be an analog one. People might have software (movies, games?) or other audio sources (streaming, ripped CDs) and the user might not want to move all of that to the Pi, or can't because the Pi is relatively low powered. Unless you are into vinyl or FM radio, it seems that most everything comes as digital audio these days.

The Pi can do DSP processing. I use LADSPA for that, and it is not easy to compile LASPA for Windows, and this has represented (for me) an insurmountable hurdle. I have to resort to installing Linux on the computer. Let's say you want to implement a DSP crossover so you buy a miniDSP 2x4 (not the HD version, which has SPDIF Toslink input). The 2x4 has only analog inputs, so you must render your digital audio to analog, and then re-sample it in the miniDSP. My approach gives you a way to perform the DSP and then render the audio in something that can be deployed as an "add-on" to a computer (like a laptop) that might not have multichannel audio output.
 
Yes, I see your point now....although as a vinyl user and archiver I was sort of hoping the gadget mode might have some use there...

Of course the other hope is that gadget mode would allow the use of interfaces and devices, currently Pi-centric only, that could extend to pc use....??

For instance, feeding audio from a pc to Pi as usb gadget and out to a dac via i2s...?
 
Yes, I see your point now....although as a vinyl user and archiver I was sort of hoping the gadget mode might have some use there...

Of course the other hope is that gadget mode would allow the use of interfaces and devices, currently Pi-centric only, that could extend to pc use....??
Sure, once you have the audio over to the Pi, you are free to treat it as you wish. The audio stream can be passed to ALSA and made available via a loopback for another app to use as input.
For instance, feeding audio from a pc to Pi as usb gadget and out to a dac via i2s...?

I am using an 8-channel HDMI audio extractor HAT, but I2S, or USB DACs are equally as good. The only problem is that you would need to supply power to the Pi via the GPIO pins and not thru the USB-C port (which doesn't have the current capability for the Pi 4 on the PC side). Since my HDMI HAT includes a power supply that connects to the Pi via GPIO pins it's very well suited for this application. And it only costs around US$60. See:
X6000 7.1 Hi-Fi Audio Channel Expansion Board for Raspberry Pi 3 Model B / 2B /B+
This board was originally designed for the Pi 2 and 3, and takes a full size HDMI input via external jumper. On the Pi 4 you need an adapter cable from micro HDMI to HDMI to make the connection.
 
Last edited:
Here is an amazon seller link to the 8-channel HDMI audio extractor HAT that I use in this project and that supplies power to the PI via the GPIO pins so that you can use the USB-C port as a OTG ethernet gadget:
https://www.amazon.com/WINGONEER-WX6000-Multifunction-Expansion-Raspberry/dp/B06XCFBTVW
The 5V 4A external power supply you will need is also available on that page under the heading "Frequently bought together".

51itP4HqyFL.jpg


Since the Pi 4 has micro HDMI ports and the HDMI input to the X6000 board is full size you will need an adapter cable or a standard HDMI cable plus an M-F adapter like this one:
https://www.amazon.com/GearIt-Micro-HDMI-Adapter-Type/dp/B00V5KRF66/ref=sr_1_11
 
In https://www.diyaudio.com/forums/pc-based/341590-using-raspberry-pi-4-usb-dsp-dac-3.html#post5889569 you talk about the need for knowing the IP of your xover RPi. With avahi (zeroconf) the xover.local would be resolved automatically, independently of network setup. You should be able to use that instead the specific IP address. On any network, without the dedicated USB-ethernet segment.

But it requires a network though. Just a network cable should do.

To initiate a Gstreamer RTP-over-UDP stream using the element udpsink you must provide the destination IP address, because that is how the element has been written. There might be other apps that are able to stream RTP audio data to a zeroconf type address, but I am not familiar with them.

Remember, one point of this project is to use the USB gadget connection. Sure that is "ethernet" it its protocol but it is not part of a network by design. The connection is "plug and play" like USB. In the last couple of days I wrote a small script that runs on the Pi. It continually pings the IP of the USB gadget and when that it up, it launches the Gstreamer pipeline. If script was run at start-up the entire Pi side would be a headless, black box. On the host PC a similar script is executed via a batch file, so the user has to only click on it to start sending audio data. It's pretty fault tolerant, as I have discovered. With everything up and audio playing, I can unplug the cable, wait a few minutes. The Gstreamer pipelines keep running and complain about buffer overruns. As soon as I plug it back in, audio playback resumes.

I don't really see a problem with the IP address approach. It's something that you set up one time on the PI and in Windows RNDIS and then forget about it unless you needed to change something about the setup. The Pi itself never needs to be connected to the internet.
 
Once I have the scripts finalized, I will post a HOW-TO.

The 8-channel HAT and PS only cost about US$65 via Amazon while supplies last. Combined with a Pi4 for $35 your $100 gets you an 8-channel DSP/DAC system that you can plug into a Windows or Linux machine via USB.



Question
After you write the code for this, and post the parts list and the scripts. I could use this for a car dsp or a home dsp system setup without a pc hooked up to the PI4 ?
I’m a newbie with these PI boards
I’m also a hands on learner, lol so yes I was horrible in school but great in any of my shop classes
 
A bit over my head, but will look forward to a How To. I use a TinkerBoard rather than Pi for running Volumio into my dac. Works great. Would love to be able to do crossovers in DSP on the TB. As a 62 year old dude this stuff blows my mind vs. my first HK receiver from Sam Goody's into EPI 100 speakers off of BIC turntable in 1974.
 
Question
After you write the code for this, and post the parts list and the scripts. I could use this for a car dsp or a home dsp system setup without a pc hooked up to the PI4 ?
I’m a newbie with these PI boards
I’m also a hands on learner, lol so yes I was horrible in school but great in any of my shop classes

How would you get audio into the Pi without the PC, e.g. in the car setting???

The whole point of this project is to make the Pi into an accessory for the PC that is a DAC wtih DSP capability.

If you want to do that "standalone" then you will need to use some kind of audio device (e.g. USB audio interface) that also has input. That would be a different project alltogether, and it has been done many, many times already. Look into ecasound and e.g. ASUS Xonar U7. You will need a PS for the Pi that works from the car DC power...
 
Last edited:
A bit over my head, but will look forward to a How To. I use a TinkerBoard rather than Pi for running Volumio into my dac. Works great. Would love to be able to do crossovers in DSP on the TB. As a 62 year old dude this stuff blows my mind vs. my first HK receiver from Sam Goody's into EPI 100 speakers off of BIC turntable in 1974.

This arrangement only works for systems that have USB OTG hosts. It looks like that Tinkerboard does have an OTG host but I don't have any experience using it for this application. I do have a TB lying around here somewhere (the original one) so I could give it a try but that will take some time.

Can you check into that for your board?

Also, if you are already using Volumio on the TB for playback, then you don't need this setup - it's only for playback from another (host) computer via the Pi to the DAC. Instead you can just connect the HDMI HAT to the HDMI output as a standalone accessory (not as a HAT) and then you will get 8 channels of up to 24/192 audio. You just need a program like ecasound to implement the DSP, and an audio loopback (e.g. snd-aloop in ALSA) or other means to direct the Volumio output to the input of ecasound.
 
Status
This old topic is closed. If you want to reopen this topic, contact a moderator using the "Report Post" button.