No, the changes only apply to this particular functionality.
⌠and what about Embedded 4, will it work with new NAA versions?
Yes, it will work with any NAA 4.x at least. It just cannot use all the features of newer ones.
But still you benefit from newer NAA OS / HQPlayer OS (when used as NAA) in form of updated DAC driver support.
Can you give an overview of how this UAC2 works. I canât wrap my head around it yet. I have embedded 5.3.1 on Ubuntu Server installed with your latest kernel.
So does that mean auto rate switching will now work with something like minidsp mchstreamer connected to NAA?
Should work with any USB (UAC2) audio source.
It makes HQPlayer (directly or through NAA) look like a USB connected DAC. This requires that the device running the HQPlayer Embedded or NAA instance has needed hardware capabilities to become a USB device (instead of host; normal desktop/laptop computers lack this).
Well done to all involved. This has been pretty exciting watching this evolve.
Maybe not great for Roon?
Now the new Desktop release is also out.
For example if one boots up latest HQPlayer OS on UP Gateway with the USB OTG set to Device mode, in HQPlayer Desktop select âhqplayer:USB Audio (DWC3)â as input device. Connect your source device with USB â microB cable to the UP Gateway USB 3 OTG port.
If you use RPi4 with HQPlayer OS, before bootin up with new image, edit the config.txt first and on the last lines swap the â#â prefix so that the dwc2 host mode line has â#â (commented out) and the dwc2 peripheral mode line has â#â removed. In HQPlayer instead select âhqplayer:USB Audio (RPi4)â as input device. Connect your source device with USB â type-C cable to the RPi4 Type-C port. Since the RPi4 can draw quite a bit of power, you may have best results if you can use type-C â type-C cable for connecting. You will need to use at least USB3 â type-C cable on USB3 port to supply enough current.
In HQPlayer Desktop, for source URI line (above playback queue display) enter âaudio:default/0/2â and hit enter. Now it should appear on the playback queue. Then just start playback. Now the NAA should appear as a USB DAC on the source device. When you start playing something, HQPlayer time should start proceeding and you should hear what ever you play on the source device. Iâve tested mostly with my old iPad Pro through the Appleâs Lightning to USB3 adapter dongle which also allows simultaneous charging of iPad.
I donât think it has impact on this, since you can use Roon as source just like before. But the feature is useful if youâd like to use something like Apple Music, Amazon Music or Spotify as source. So it widens the range of potential sources, especially streaming ones.
Thanks for this.
Will get to testing - after I measure SMSL DO300EX (4499EX) which just arrived today
So, I could connect one of my Android DAPs playing Tidal or local music through an OTG cable to the NAA Up Gateway and tunnel through my Mac running HQPlayer hooked to a DAC? Itâs almost like a Roon source, right? Except you can do Spotify Apple and Amazon?
I can only speak for myself, but this pathway with Apple Music seems a better option than Roon and Tidal/Qobuz, which is my current source.
With my current hardware, and infrastructure, itâs what Iâve been waiting for, for the past year tbh.
Iâve got the previous version of HQPlayer desktop, but maybe the new version for my new Holo Red, arriving soon? Would the embedded be better suited to the Holo, as itâs a NAA?
Hi Jussi,
Thank you so much for your work on UAC2 Gadget support. This end of the week, I finally had time to play with it; overall Iâm excited with, but i still have to figure out a few issues:
- there is a small playback hickup when input rate jumps between samplerate families - 1 second gap at the start of the track (1s sound â 1s no sound â sound)
note: in my Proof-of-Concept setup of CamillaDSP + gaudio_ctl (executing a python script to reconfigure CamillaDSPâs samplerates on the fly) around 2 weeks ago, i donât remember a similar issue; but i will retest to be sure - ocasionally, when samplerate changes, audio is garbled and i can only fix it if by playing a 44100 track; not sure yet if this is a Capture Side issue or it has somthing to do with my Topping D50s DAC; but iâm more inclined to blame USB Gadget for it; i also had this issue while testing CamillaDSP
- when using networkaudiod/NAA as UAC2 input, auto rate switcing doesnât work for me (networkaudiod doesnât report rate changes in its logs, and hqplayerd is not notified about it either); i tested using networkaudiod running on same RPi as hqplayerd - hqplayerd.xml config entry below; naa-start-uac-gadget.sh script is not executed, so i had to run it manually
<input address="HQPlayer" ipv6="1" name="USB Audio (RPi4)" device="hw:CARD=UAC2Gadget,DEV=0" samplerate="0" channels="2" format="pcm" period_time="100" type="network"/>
My test setup was:
- (input) iPhone 8 (running VOX.app music player) connected to RPi 4, running your HQPlayer Emebedded 5.3.1 image
- (output) Topping D50s connected to RPi4, running RoPieeee with NAA 4.5.0
- mode: pcm; filters: poly-sinc-gauss-long (1x), poly-sinc-gauses-hires-lp; dither: LNS15; max samplerate 768000, dac-bits 32 but (i should probably limit it to 24 with my DAC); any base rate enabled
Improvement suggestion for naa-start-uac-gadget.sh & hqplayer-start-uac-gadget.sh scripts:
- setting p_chmask to 0, disables Playback device; i donât think we care about playback in this scenario anyway
- because i donât think we can have more than one UDC, we could use âls /sys/class/udc > âŚ/UDCâ instead of passing it as a command line argument
Yes, this is normal, in particular with first rate change, as the DSP pipeline with all the algorithms will need to be reinitialized. And if you you have auto rate / adaptive rate then the DAC needs to be restarted with a different rate as well.
Did you have all the same DSP there, such as upsampling? And same I/O path?
I have not encountered such on my testing. But I got few stops when using iPad and Apple Music as source when iOS was changing output rate quickly back and forth multiple times like 48k â 44.1k â 48k â 44.1k and one of the changes happened between rate change notification and restarting the gadget input at new rate.
This is the issue⌠You are pointing to the gadget device and not to the virtual input deviceâŚ
This is what I have:
<input address="hqplayer" channel_offset="0" device="USB Audio (RPi4)"
format="auto" ipv6="1" pack_sdm="1" period_time="0" samplerate="0"
short_buffer="0" type="network6"/>
Thus the networkaudiod doesnât have the necessary configuration for the input. Add the ânameâ item to make it named, above works also with HQPlayer Desktop, but there it is selectable straight.
Yes, makes senseâŚ
Not 100% sure about the hardware possibilities, I wanted to play safe with the few tested cases.
But that may be good idea in future when the test coverage over different hardware is a bit wider.
I can imagine some newer Atom hardware and maybe ARM SoCâs having more than one. Of course I could modify the NAA / hqplayerd config to cover that case as well by default.
This is the issue I had with previous couple years UAC2 input.
I made an Apple Music playlist with these exact family rate changes just to test this
Will test soon and report back
thank you so much for sharing the hqlayerd.xml config entry - i missed completely that i should use a virtual input device (if capture is done on NAA); now every thing works fine (USB Gadget configured automatically, auto rate switching âŚ)
Not as complex as HQPlayer - in my testing, CamillaDSP was configured to (Synchronous) resample to 705600 / 768000 with a -3 dB gain to avoid clipping. Capture & playback on same RPi4; other than the fact that I had my DAC connected to the RPi instead of the (RoPieee as) NAA, the HW setup was identical to what I used to test UAC2 input with HQPlayer Emebeded 5.3.1 Image.
Everything was glued together (arround CamillaDSP & pyCamillaDSP v2.0) with gaudio_ctl & a modified set_samplerate.py script by stemag on ASR forum (updated for pyCamillaDSP v2.0 and to change both capture & playback samplerates based on capture samplerate); pyCamillaDSP & gaudio_ctl compiled / installed from source
Click to see camilladsp / gaudio_ctl commands used
/usr/local/bin/camilladsp -p 1234 -w
/usr/local/bin/gaudi_ctl -y "/usr/local/bin/set_samplerate.py {R}"
Click to see CamillaDSP config file
title: "CamillaDSP Stereo with 16x Resample"
description: "UAC2 Gadget Capture with resampling and -3dB gain"
devices:
samplerate: 705600
chunksize: 4096
queuelimit: 4
silence_threshold: -60
silence_timeout: 3
target_level: 500
adjust_period: 10
enable_rate_adjust: false
resampler:
type: Synchronous
capture_samplerate: 44100
stop_on_rate_change: false
rate_measure_interval: 1
volume_ramp_time: 400.0
capture:
type: Alsa
channels: 2
device: hw:UAC2Gadget
format: S32LE
playback:
type: Alsa
channels: 2
device: hw:D50s
format: S32LE
mixers:
stereo:
description: "Stereo Mixer (-3dB gain)"
channels:
in: 2
out: 2
mapping:
- dest: 0
mute : false
sources:
- channel: 0
gain: -3
inverted: false
scale: dB
- dest: 1
mute : false
sources:
- channel: 1
gain: -3
inverted: false
scale: dB
pipeline:
- type: Mixer
name: stereo
Click to see modified set_samplerate.py script
#!/usr/bin/python3
# This script must be launched at each sample rate change
# (a gaudio_ctl daemon will do the trick).
# To this end, it updates the samplerate parameter of the current configuration
# according to the sample rate of the signal being captured. Then it
# sends the updated parameter to camilladsp via a websocket.
# If camilladsp has not a current valid configuration, a standard
# configuration is loaded from file.
# Note 1: camilladsp must be launched in wait mode.
# Note 2: the parameter samplerate in the standard configuration is not relevant,
# as it will be changed right after the file is loaded anyway.
#
# This script derives from the work of @audiofun on ASR forum.
import camilladsp
import sys
cdsp = camilladsp.CamillaClient("127.0.0.1", 1234)
msg = ""
try:
cdsp.connect()
capturerate = int(sys.argv[1])
config = cdsp.config.active()
if config is None:
config = cdsp.config.read_and_parse_file("/usr/local/etc/camilladsp-active.yml")
if 705600 % capturerate == 0:
rate = 705600
else:
rate = 768000
config['devices']['samplerate'] = rate
config['devices']['capture_samplerate'] = capturerate
cdsp.config.set_active(config)
msg = "Capture Sample Rate {} & Playback Sample Rate {} successfully set".format(capturerate, rate)
except ConnectionRefusedError as e:
msg = "Can't connect to CamillaDSP, is it running? Error:" + str(e)
retry = True
except camilladsp.CamillaError as e:
msg = "CamillaDSP replied with error:" + str(e)
retry = True
except IOError as e:
msg = "Websocket is not connected:" + str(e)
retry = True
finally:
print(msg)
cdsp.disconnect()
for a moment i thought i âdiscoveredâ why during playback i hear a short glitch (music is audible for ~1 sec, abruptly/discompfortably stops for ~1 sec, and resumes perfectly) at the begining of a track if input samplerate jumps between rate families.
note: with short_buffer enabled (in engine section), the glitch is less discomfortable / i donât even notice it sometimes
+ 2023/12/26 10:35:30 ALSA input engine running...
2023/12/26 10:35:30 enter streaming mode
2023/12/26 10:39:18 ALSA input rate change detected: 192000 -> 176400
2023/12/26 10:39:18 ALSA input rate change detected: 192000 -> 176400
2023/12/26 10:39:18 leave streaming mode
- 2023/12/26 10:39:18 stop
- 2023/12/26 10:39:18 ALSA input engine stopping...
- 2023/12/26 10:39:19 ALSA input engine stop request...
- 2023/12/26 10:39:19 ALSA input engine stopped
+ 2023/12/26 10:39:22 start 176400/32/2 [pcm]
2023/12/26 10:39:22 ALSA input set channels: 2 (2)
# 2023/12/26 10:39:22 start: clAudioEngine::SetSampleRate(): requested rate not available
? 2023/12/26 10:39:22 starting audio failed, attempting to reinitialize...
2023/12/26 10:39:22 ALSA input attempting to uninitialize...
- 2023/12/26 10:39:22 ALSA input backend uninitialized
2023/12/26 10:39:22 ALSA input attempting to initialize...
[ . . . ]
+ 2023/12/26 10:39:22 ALSA input backend initialized
2023/12/26 10:39:22 ALSA input set sampling rate: 176400 (176400)
2023/12/26 10:39:22 ALSA input set channels: 2 (2)
2023/12/26 10:39:22 ALSA input set sampling rate: 176400 (176400)
+ 2023/12/26 10:39:22 ALSA input engine starting...
but networkaudiod generates similar logs for all samplerate transitions, so i discovered nothing;
the only things i find odd are:
- that âALSA input rate change detectedâ is reported twice
- and that when input engine is started with the new samplerate, clAudioEngine::SetSampleRate fails and we need to re-initialize the backend; maybe we should re-initialize input backend every time a samplerate change is detected (at least for UAC2Gadget)
Yeah, RPi4 is very slow for running HQPlayer. And especially any arbitrary precision calculations become really slow. But it is usable for some really basic playback scenarios, like doing up to 192k PCM output. But I wouldnât really use RPi4 for doing any serious DSP.
Probably RPi5 is better for the DSP part, but I havenât got time to do any testing on it yet.
This is normal with for example 6.1 and newer kernels. 5.15 and older kernels was better. ALSA changed things so that changing sample rate is now much bigger operation than before. The code still supports the earlier way as well that was quicker.
So ALSA kind of followed the path Microsoft took in WASAPI in Windows 8. And recently Apple has taken similar path with CoreAudio as well, but only on Intel CPUs (probably more of bug there, maybe they just donât bother to test on Intel hardware carefully).
This line is in your hqplayerd.xml file right?
And input address=âhqplayerâ refers to the NAA name?
So I would change âhqplayerâ to whatever the NAA name is? Otherwise I have two different âhqplayerâ machines clashing?
Currently testing with RPi4 running latest HQP OS image but hqplayerd is disabled on HQP OS on the Pi4.