• 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!

8ch hifiberry hat dac for RPI5

After a bit of multichannel gadget testing I think my hypothesis that it is related to the two different 7.1 channel formats is correct.

On a Mac, by default the gadget presents as 7.1 Wide as described in the Microsoft link I posted earlier and lists channels of FL, FC, FR, LFE, BL, BR, FLC, FLR.

Screen Shot 2025-03-01 at 12.22.51 PM.png


Playing the 7.1 test track from here -> https://www2.iis.fraunhofer.de/AAC/multichannel.html does not give any output from channels 7 and 8. However, on a Mac you have the ability to adjust the channel mapping, and sure enough in the 7.1 Rear Surround format channels 7 (LRS) and 8 (RRS) are unassigned by default. Assigning these to FLC and FRC as is done in the 7.1 Surround format gives the correct behavior with the test track.

Screen Shot 2025-03-01 at 12.22.38 PM.png
Screen Shot 2025-03-01 at 1.22.29 PM.png


Things seem a little trickier on Windows 11. Again, if I play the 7.1 test track I get nothing out of channels 7 and 8. I can get sound from channels 7 and 8 when I click the test button shown below but see no way of re-assigning channels like on a Mac.

Screenshot 2025-03-01 173857.png


After thinking about this some more I realized the channel mask is exactly what it sounds like. 0x63F = 0b110001111111 = 1599 and 0xFF = 0b11111111 = 255. I tried 0x63F (1599 also works) and it gave this on a Mac which looks about correct!

Screen Shot 2025-03-01 at 5.43.41 PM.png
Screen Shot 2025-03-01 at 5.43.54 PM.png


It still doesn't seem to map correctly by default unfortunately, I wonder if it is because Side Left and Side Right do not match the Left rear surround and Right rear surround nomenclature.

Unfortunately trying 0x63F with a Windows PC as a USB host gave me nothing, I couldn't even test.

Still it may be worth trying to use 0x63F as a capture channel mask and see if that works with your setup. If it doesn't I would look at see if you have any ability to re-assign channels on your USB host.

Michael
 
Last edited:
Hmm...I wonder if it is a difference between 7.1 home theater and 7.1 wide -> https://learn.microsoft.com/en-us/windows-hardware/drivers/audio/channel-mask?
It could be somehow related as the player uses wasapi code with channel mask support in the sample format.

I would suggest to try setting the channel bits of c_chmask according to standard 8ch configurations in Portaudio https://github.com/PortAudio/portau...rc/hostapi/wasapi/pa_win_wasapi.c#L2899-L2903 -. https://github.com/PortAudio/portau...9fd8c33/include/pa_win_waveformat.h#L103-L106 or https://github.com/PortAudio/portau...f19fd8c33/include/pa_win_waveformat.h#L96-L99
 
Thanks for the quick replies @mdsimon and @phofman.
It appears that you nailed the problem Michael when i tested with the mask 0x63F and inputing 8 channels it works flawlessely atleast on linux (coreelec)
Unfortunely if i play a source with less than 8 channels, the sound comes out completely distorted (that didn't happen with chmask 63 or 255)
i didn't had much time last weekend to play with this stuff and i still have to try chmask 1599, to see if i get the problem fixed!
 
Unfortunely if i play a source with less than 8 channels, the sound comes out completely distorted (that didn't happen with chmask 63 or 255)
The gadget reports its channels mask (configured via the c_chmask parameter) and channel count (number of set bits in the configuration chmask) via UAC2 protocol to the host.

If the USB device accepts 8 channels, the player decides what to do with the non-8 channels user wants to play. If it transforms those fewer channels to the supported 8 channels of the device incorrectly, messing up the samples, the device/gadget cannot do anything about it.
It appears that you nailed the problem Michael when i tested with the mask 0x63F and inputing 8 channels it works flawlessely atleast on linux (coreelec)
Did linux host have issues with the channel mask previously? It would be surprising, as channel configuration is only optional in linux alsa. Unlike in windows WASAPI where the client must configure a channel mask which is accepted by the driver (which is likely accepting the channel mask sent by the USB device/gadget).
 
@mdsimon2 and @phofman the error was on my side, i forgot to lock the samplerate at the clientt/linux/coreelec.
That said, with the 0x63F mask it all works flawlessely, the channels are mapped correctly!
The gadget is connected via usb to coreelec and it is receveing all channels from any kind of audio source (2.0, 5.1, 7.1);
That said, this is a crazy alternative to a home cinema receiver, whit a pretty decent SINAD.
It probably will work in android clients like nvidia shield, as long as the client have the hability to convert the audio to LPCM.
The major downside is if you really are into atmos (which i'm not). If you have ceiling speakers this is a no go for you.
At the moment i'm only downmixing to 2.0 and applying EQ filters to the speakers but with these findings i almost feel obligated to buy a pair of JBL 305p mkII for the surrounds! :cool:
Thank you very much @mdsimon2 and @phofman for the fast help!
 
Last edited:
I just got an email newsletter from Hifiberry which talked about two versions of their DAC8x. A single-ended output HAT and a balanced output one. The balanced output needs a breakout cable DB25, Tascam style. But I can't see the StudioDAC8x listed on their website. Any idea? Is it WIP?

1000230180.png
 
I wonder if anyone has tested 4 x PCM5102 modules available e.g. from Aliexpress?

View attachment 437112
IIUC they have the same PCM5102a as Hifiberry DAC8x, each has its own linear regulator. Example e.g. https://diyelectromusic.com/2024/05/27/rpi-5-quad-stereo-sound-with-pcm5102a/ + https://diyelectromusic.com/2024/06/09/minidexed-quad-dac-pcb-design/
To be honest, with 8ch DAC ICs available, I personally prefer to build my own single IC board. I am a bit surprised hifiberry go 4 stereo route, they must get those chips really cheap.
 
@MCH: I agree (e.g. that ES9080 you use is a perfect candidate I would use as well for this purpose, perhaps in a stackable configuration allowing balanced output).

On the other hand joining several dirt-cheap ready-made boards is accessible for those not willing to make their own board (and solder that 0.4mm pitch QFN), with only trivial duponts for connecting.
I am a bit surprised hifiberry go 4 stereo route, they must get those chips really cheap.
If complete boards can be sold for 2.5USD at single quantities, the chip itself at larger quantites must be probably lower than the 1.3USD@1k+ from TI eshop.
 
  • Like
Reactions: MCH
Considering Hifiberry uses TI DACs for the DAC8x this could be e.g. PCM5242 - QFN32, stereo, differential output with output amplifier (no filter required), integrated PLL for MCLK from BCLK.
 
Thanks MCH and phofman for the feedbacks. I wondered if they were using ES9080, but there were "too many". I was not aware of PCM5242 and TI similar DAC with integrated power stage. Interesting.
 
  • Like
Reactions: MCH
Here are both Dacs
1743436201761.jpg
1743436157371.jpg


And is here the new Version of my streamerDSPdac with 4 channel balanced output. The new studiodac8x is working with the old dtoverlay from the old dac8x. ;)
1743436096576.jpg
 
So the guess for PCM5242 was right.

The new studiodac8x is working with the old dtoverlay from the old dac8x.
That's because none of the chips use any control from RPi (via I2C or GPIO), and the driver is just configuration of the RPi I2S interface in master mode. The only custom part is a GPIO sensing the ADC hat which enables the capture alsa device automatically if the hat is installed. That's why a standalone ADC requires a different overlay which just tells the driver to disable the playback alsa device.

Again lost opportunity for using the master clock from RPi instead of PLL from bclk.
 
I have been inspired by all of your posts and have constructed the following system

1745950172833.png


I can capture Dolby EAC3, convert it to PCM and feed it via Camilla DSP to 4 Sabre DACs connected via HDMI out on the Raspberry Pi. Great! Now I need more than 8 outputs and would also like to have balanced outputs... enter the Studio DAC8x... and the I2S clock issues...

That's because none of the chips use any control from RPi (via I2C or GPIO), and the driver is just configuration of the RPi I2S interface in master mode. The only custom part is a GPIO sensing the ADC hat which enables the capture alsa device automatically if the hat is installed. That's why a standalone ADC requires a different overlay which just tells the driver to disable the playback alsa device.

Again lost opportunity for using the master clock from RPi instead of PLL from bclk.
@phofman your analysis is correct! However, I have tried to reuse the clock generated by the Toshiba tc358743 (i2s in) to drive the DAC8x (i2s out), but cannot get the device tree overlay to work (with the first 2 channels of the DAC8x). Any ideas?

Bash:
lsmod | grep snd
snd_soc_simple_card    49152  0
snd_soc_simple_card_utils    49152  1 snd_soc_simple_card
snd_soc_hdmi_codec     49152  2
snd_soc_pcm5102a       49152  1
snd_soc_spdif_rx       49152  1
snd_soc_core          311296  7 snd_soc_spdif_rx,vc4,snd_soc_pcm5102a,snd_soc_hdmi_codec,designware_i2ssnd_soc_simple_card_utils,snd_soc_simple_card
snd_compress           49152  1 snd_soc_core
snd_pcm_dmaengine      49152  1 snd_soc_core
snd_aloop              49152  3
snd_pcm               147456  9 snd_soc_hdmi_codec,designware_i2s,snd_compress,snd_soc_simple_card_utils,snd_soc_core,snd_aloop,snd_pcm_dmaengine
snd_timer              65536  2 snd_aloop,snd_pcm
snd                   131072  16 snd_soc_hdmi_codec,snd_timer,snd_compress,snd_soc_core,snd_aloop,snd_pcm

Bash:
cat /proc/asound/cards 
 1 [tc358743       ]: simple-card - tc358743
                      tc358743

Bash:
cat /proc/asound/pcm 
01-00: 1f000a4000.i2s-pcm5102a-hifi pcm5102a-hifi-0 : 1f000a4000.i2s-pcm5102a-hifi pcm5102a-hifi-0 : playback 1
01-01: 1f000a4000.i2s-dir-hifi dir-hifi-1 : 1f000a4000.i2s-dir-hifi dir-hifi-1 : capture 1

Code:
speaker-test -c 2 -t wav -D hw:CARD=tc358743,DEV=0

speaker-test 1.2.8

Playback device is hw:CARD=tc358743,DEV=0
Stream parameters are 48000Hz, S16_LE, 2 channels
WAV file(s)
Rate set to 48000Hz (requested 48000Hz)
Buffer size range from 16 to 131072
Period size range from 8 to 65536
Using max buffer size 131072
Periods = 4
was set period_size = 32768
was set buffer_size = 131072
 0 - Front Left
 1 - Front Right
Time per period = 0.688782
 0 - Front Left
 1 - Front Right
Time per period = 2.732148
 0 - Front Left
 1 - Front Right
Time per period = 3.411847
 0 - Front Left
 1 - Front Right

C:
//based on https://github.com/AkiyukiOkayasu/RaspberryPi_I2S_Slave/blob/master/genericstereoaudiocodec.dts
/dts-v1/;
/plugin/;

/ {
    compatible = "brcm,bcm2712";

    fragment@0 {
        target = <&sound>;
        __overlay__ {
            compatible = "simple-audio-card";
            simple-audio-card,name = "tc358743";
            status="okay";

            capture_link: simple-audio-card,dai-link@0 {
                format = "i2s";

                // Set RasPi to I2S slave
                bitclock-master = <&r_codec_dai>;
                frame-master = <&r_codec_dai>;

                r_cpu_dai: cpu {
                    sound-dai = <&i2s_clk_consumer>;

                // TDM slot configuration for stereo
                    dai-tdm-slot-num = <2>;
                    dai-tdm-slot-width = <32>;
                };

                r_codec_dai: codec {
                    sound-dai = <&capture_codec>;
                };
            };

            playback_link: simple-audio-card,dai-link@1 {
                format = "i2s";

                // Set RasPi to I2S slave
                bitclock-master = <&p_codec_dai>;
                frame-master = <&p_codec_dai>;

                p_cpu_dai: cpu {
                    sound-dai = <&i2s_clk_consumer>;

                // TDM slot configuration for stereo
                    dai-tdm-slot-num = <2>;
                    dai-tdm-slot-width = <32>;
                };

                p_codec_dai: codec {
                    sound-dai = <&playback_codec>;
                };
            };
        };
    };

    fragment@1 {
        target-path = "/";
        __overlay__ {
            playback_codec: playback_codec {
                #address-cells = <0>;
                #size-cells = <0>;
                #sound-dai-cells = <0>;
                /*
                    "linux,spdif-dit" is used in generic I2S(transmitter) driver.                   
                    You can see details "linux,spdif-dit" by bellow command
                    modinfo snd_soc_spdif_tx
                */
                //compatible = "linux,spdif-dit";
                compatible = "ti,pcm5102a";
                status = "okay";
            };
            capture_codec: capture_codec {
                #address-cells = <0>;
                #size-cells = <0>;
                #sound-dai-cells = <0>;
                /*
                    "linux,spdif-dir" is used in generic I2S(receiver) driver.                   
                    You can see details "linux,spdif-dir" by bellow command
                    modinfo snd_soc_spdif_rx
                */
                compatible = "linux,spdif-dir";
                status = "okay";
            };
        };
    };

    fragment@2 {
        target = <&i2s_clk_consumer>;
        __overlay__ {
            #sound-dai-cells = <0>;
            status = "okay";
        };
    };
};
 
Last edited:
Back
Top Bottom