Even with jack, when I use the VM instance to play music, I can still hear the terrible ticking sound.
Did you set the sample rate in jack and in the guest to 48KHz? and have you tried increasing the period size jackd is using?
@gnif, did you manage to find a workaround to the 65kHz sample rate limitation in versions beyond v6? I have a Steinberg UR22C (192kHz/32-bit) that I want to work with, and Iâd like to not hold it back if I canâŚ
P.S. Your patchbay screencap is so busy, I love it!
My understanding is that the patch was upstreamed so me being on qemu 5.2 on arch shouldnât change much. However I was having a strange issue with audio. it is somewhat spedup while clipping and popping like I have a sample rate mismatch. however jack is set to 48khz and my windows vm is set to 48khz.
When I set my windows vm to around 16khz is when the audio starts to sound closer to normal. Unsure what I should try doing differently.
There is no workaround
, the QEMU resampler needs to be replaced/rewritten to support it.
Popping/clicking can be caused by too small/short of a period, not enough periods, etc. Lack of CPU pinning, or starving jack of CPU time. Also make sure that jack is running with RT priority, and QEMU can also start itâs jack client with RT priority also.
I am using csets at the moment for pinning and my host only had a couple of terminals cadence and carla open so I am not too sure that it was getting starved for cpu however it is possible I guess.
I tried changing the periods. setting the buffer size in cadence to 2048 and 4096 with no real change in result. I set the periods up from 2 to 4 to 16 then 32 without any change.
When I checked to see if jack is running with realtime priority just to verify cadence was doing its job it was. one of jackdbusâs processes was set to
pid 38860âs current scheduling policy: SCHED_FIFO
pid 38860âs current scheduling priority: 90
2 of qemuâs processes were set the same except the scheduling priority was 85 instead of 90.
Its very possible one of those things is still the issue I am just not sure what my next move should be.
Should I try to run jack without cadence at all?
Edit:
I decided to try without cadence running at all. That seemed to solve it.
I will try more in the morning. However this seems promising. Thank you for the advice.
All i did that time was configure the period and nperiods with jack_control instead of letting cadence start jack.
Wish me luck.
Please note that csets
is no replacement for isolcpus
, and jack is very timing sensitive as such being serviced late by the kernel will cause clicks/pops. You may not be starved of CPU cycles, but rather the scheduler is working too hard and canât service the jack thread again within a decent timeframe.
Hello and thank you for creating this qemu âextensionâ.
I have managed to make it work, sort of:
Despite following all available tutorials and wiki pages, the jack client created by Qemu is not able to run with real time privileges. The libvirtd guest log shows the following;
jack: E: Cannot use real-time scheduling (RR/68) (1: Operation not permitted)
jack: E: JackClient::AcquireSelfRealTime error
jack: JACK output configured for 48000Hz (512 samples)
jack: E: Cannot use real-time scheduling (RR/68) (1: Operation not permitted)
jack: E: JackClient::AcquireSelfRealTime error
I am running Qemu as a normal user, have edited qemu.conf accordingly, my user is added to real time group, and jack is started by qjackctrl under the same user.
Have you guys checked whether the jack client started by the VM can run in realtime?
Thank you.
PS: the following test seems to indicate that the basics are all available:
perl ./realTimeConfigQuickScan.pl
== GUI-enabled checks ==
Checking if you are root... no - good
Checking filesystem 'noatime' parameter... 5.10.2 kernel - good
(relatime is default since 2.6.30)
Checking CPU Governors... CPU 0: 'performance' CPU 1: 'performance' CPU 10: 'performance' CPU 11: 'performance' CPU 2: 'performance' CPU 3: 'performance' CPU 4: 'performance' CPU 5: 'performance' CPU 6: 'performance' CPU 7: 'performance' CPU 8: 'performance' CPU 9: 'performance' - good
Checking swappiness... 10 - good
Checking for resource-intensive background processes... none found - good
Checking checking sysctl inotify max_user_watches... >= 524288 - good
Checking whether you're in the 'audio' group... yes - good
Checking for multiple 'audio' groups... no - good
Checking the ability to prioritize processes with chrt... yes - good
Checking kernel support for high resolution timers... found - good
Kernel with Real-Time Preemption... 'threadirqs' kernel parameter - good
Checking if kernel system timer is high-resolution... found - good
Checking kernel support for tickless timer... found - good
For more information, see http://wiki.linuxaudio.org/wiki/system_configuration#filesystems
Checking for devices at IRQ 153... did not find multiple. ok.
It certainly can, but permissions can be a pita.
You do know that even root applications canât use realtime unless itâs configured in /etc/security/limits.conf
?
Hello @gnif
Thanks for taking the time to answer.
I do understand that realtime users have to be configured yes.
However I did nothing to configure realtime permissions for root.
Do you suggest I should even though jack and qemu are running under non-root username?
I am not sure if this is what you mean.
Thank you.
PS:
At this point I created the following files:
bat /etc/security/limits.d/*
â File: /etc/security/limits.d/10-audio.conf
1 â @audio - rtprio 95
2 â @audio - memlock unlimited
3 â @audio - nice -19
â File: /etc/security/limits.d/10-gamemode.conf
1 â @gamemode - nice -10
â File: /etc/security/limits.d/10-gcr.conf
1 â @users - memlock 1024
â File: /etc/security/limits.d/99-realtime-privileges.conf
1 â @realtime - rtprio 99
2 â @realtime - memlock unlimited
3 â @realtime - nice -19
username is member of both realtime and audio groups:
⯠grep real /etc/group
realtime:x:962:username
⯠grep audio /etc/group
audio:x:995:username
Limits are as follow for my user:
ulimit -a
-t: cpu time (seconds) unlimited
-f: file size (blocks) unlimited
-d: data seg size (kbytes) unlimited
-s: stack size (kbytes) 8192
-c: core file size (blocks) unlimited
-m: resident set size (kbytes) unlimited
-u: processes 126065
-n: file descriptors 1024
-l: locked-in-memory size (kbytes) unlimited
-v: address space (kbytes) unlimited
-x: file locks unlimited
-i: pending signals 126065
-q: bytes in POSIX msg queues 819200
-e: max nice 36
-r: max rt priority 95
-N 15: unlimited
Both pulseaudio and jackdbus are running under my username:
ps axHo user,lwp,pid,rtprio,ni,command | grep -e pulsea
username 3100 3100 - -16 /usr/bin/pulseaudio --daemonize=no --log-target=journal
username 3101 3100 84 - /usr/bin/pulseaudio --daemonize=no --log-target=journal
username 3102 3100 84 - /usr/bin/pulseaudio --daemonize=no --log-target=journal
username 3103 3100 80 - /usr/bin/pulseaudio --daemonize=no --log-target=journal
username 3104 3100 68 - /usr/bin/pulseaudio --daemonize=no --log-target=journal
username 3105 3100 84 - /usr/bin/pulseaudio --daemonize=no --log-target=journal
username 3106 3100 80 - /usr/bin/pulseaudio --daemonize=no --log-target=journal
username 3107 3100 68 - /usr/bin/pulseaudio --daemonize=no --log-target=journal
ps axHo user,lwp,pid,rtprio,ni,command | grep -e jack
username 2762 2762 - 0 /usr/bin/jackdbus auto
username 3092 2762 - 0 /usr/bin/jackdbus auto
username 3093 2762 73 - /usr/bin/jackdbus auto
username 3094 2762 - 0 /usr/bin/jackdbus auto
username 3028 3028 - 0 qjackctl
username 3029 3028 - 0 qjackctl
username 3030 3028 - 0 qjackctl
username 3031 3028 - 0 qjackctl
username 3032 3028 - 0 qjackctl
username 3033 3028 - 0 qjackctl
username 3035 3028 - 0 qjackctl
username 3095 3028 - 0 qjackctl
username 3096 3028 - 0 qjackctl
username 52132 3028 0 19 qjackctl
username 52133 3028 0 19 qjackctl
username 52134 3028 0 19 qjackctl
username 52135 3028 0 19 qjackctl
Reading through some online resources, I found indication that jackdbus is run as a dbus service and therefore systemd --user services need to be able to raise priority:
systemctl --user edit dbus.service
LimitNICE=-16
LimitRTPRIO=95
Here is the libvirt/qemu config:
batgrep username /etc/libvirt/qemu.conf
File: /etc/libvirt/qemu.conf
user = "username"
batgrep seccomp /etc/libvirt/qemu.conf
File: /etc/libvirt/qemu.conf
seccomp_sandbox = 0
Here are the limits applied to jackdbus:
cat /proc/`pidof jackdbus`/limits
Limit Soft Limit Hard Limit Units
Max cpu time unlimited unlimited seconds
Max file size unlimited unlimited bytes
Max data size unlimited unlimited bytes
Max stack size 8388608 unlimited bytes
Max core file size unlimited unlimited bytes
Max resident set unlimited unlimited bytes
Max processes 126065 126065 processes
Max open files 1024 524288 files
Max locked memory unlimited unlimited bytes
Max address space unlimited unlimited bytes
Max file locks unlimited unlimited locks
Max pending signals 126065 126065 signals
Max msgqueue size 819200 819200 bytes
Max nice priority 36 36
Max realtime priority 95 95
Max realtime timeout unlimited unlimited us
Also the pulseaudio jack client is started as follows:
Jan 02 17:25:20 mycomputer pulseaudio[3100]: JACK thread starting up.
Jan 02 17:25:20 mycomputer pulseaudio[3100]: SCHED_RR|SCHED_RESET_ON_FORK worked.
Jan 02 17:25:20 mycomputer pulseaudio[3100]: Successfully enabled SCHED_RR scheduling for thread, with priority 84.
Jan 02 17:25:20 mycomputer pulseaudio[3100]: Thread starting up
Jan 02 17:25:20 mycomputer pulseaudio[3100]: SCHED_RR|SCHED_RESET_ON_FORK worked.
Jan 02 17:25:20 mycomputer pulseaudio[3100]: Successfully enabled SCHED_RR scheduling for thread, with priority 80.
Jan 02 17:25:20 mycomputer pulseaudio[3100]: JACK buffer size changed.
Jan 02 17:25:20 mycomputer pulseaudio[3100]: JACK thread starting up.
Jan 02 17:25:20 mycomputer pulseaudio[3100]: SCHED_RR|SCHED_RESET_ON_FORK worked.
Jan 02 17:25:20 mycomputer pulseaudio[3100]: Successfully enabled SCHED_RR scheduling for thread, with priority 84.
Jan 02 17:25:20 mycomputer pulseaudio[3100]: JACK thread starting up.
Jan 02 17:25:20 mycomputer pulseaudio[3100]: SCHED_RR|SCHED_RESET_ON_FORK worked.
Jan 02 17:25:20 mycomputer pulseaudio[3100]: Successfully enabled SCHED_RR scheduling for thread, with priority 84.
Jan 02 17:25:20 mycomputer pulseaudio[3100]: Connecting PulseAudio JACK Sink:front-left to system:playback_1
Jan 02 17:25:20 mycomputer pulseaudio[3100]: Connecting PulseAudio JACK Sink:front-right to system:playback_2
Jan 02 17:25:20 mycomputer pulseaudio[3100]: jack_out: state: INIT -> IDLE
However all the libvirt guests show that their respective jack client does not start with real time privileges:
jack: E: Cannot use real-time scheduling (RR/68) (1: Operation not permitted)
jack: E: JackClient::AcquireSelfRealTime error
jack: JACK output configured for 48000Hz (512 samples)
jack: E: Cannot use real-time scheduling (RR/68) (1: Operation not permitted)
jack: E: JackClient::AcquireSelfRealTime error
My guests are configured as follows:
<qemu:commandline>
<qemu:arg value="-audiodev"/>
<qemu:arg value="jack,id=ad0,in.client-name=guestvm,out.client-name=guestvm,out.start-server=on,in.start-server=on"/>
<qemu:arg value="-device"/>
<qemu:arg value="ich9-intel-hda"/>
<qemu:arg value="-device"/>
<qemu:arg value="hda-duplex,audiodev=ad0"/>
</qemu:commandline>
Any suggestion would be most welcome and appreciated
Sorry but I do not use libvirt for my Jack system. I do know however that things libvirt does such as sandboxing and runas
mess with things. QEMU creates the audio threads before it drops privs IIRC as such you must allow the user that spawns QEMU RT access.
In short you will need to experiment I am sorry. If you figure it out please be sure to post the method here for others.
Sorry for being so late for replying. the holidays got slightly busy. I think I found my problem which was likely some configuration issue because when I stopped using cadence and just used jack_control the issues with jack and qemu disappeared. Thanks for spending the time try and help me. I will try isolcpus in a day or two and see how it feels audiowise but right now I think I am happy.
Have a great day.
Hello @gnif
Thank you for your answer.
I have tried starting a VM with QEMU only and it does not display the same error.
Therefore it is indeed a libvirt issue.
After spending many more hours experimenting and investigating this issue, I have determined that the correct way to resolve this problem is indeed to edit systemd services to allow them to acquire real time priority.
The reason is systemd services ignore the contents of /etc/security/limits and PAM.
This is something I had tried before however I had made a syntax error.
I was unable to edit my previous post to correct that. Here is the appropriate syntax so that other people trying the same are not misinformed:
So in order to allow realtime priorities of a systemd service XXX, one has to add the following lines:
systemctl --edit XXX
[Service]
LimitRTPRIO=95
LimitNICE=-16
LimitMEMLOCK=infinity
Source: www freedesktop org/software systemd/man/systemd.exec.html#Process%20Properties
I am running pulseaudio and jack as a user, so I used the following commands:
systemctl --user edit pulseaudio.service #for pulse
systemctl --user edit dbus.service #for jackdbus
systemctl edit libvirtd.service # for libvirt
and added the above lines.
Everything works now.
@Al_Jazz
I can confirm that this was required to get it working on my end as well, not to mention adjustments needed to be made to AppArmorâs profile for libvirt so that it was able to access the /dev/shm devices required for JACK.
Also the default settings for jackd (technically launched via jackdbus) had the buffer size set at 1024 with 2 periods which still caused some clipping from the VMâs output, setting that lower (to 128 buffer size) still at 44100Hz rate has fixed that entirely. I still get a few XRUN events here and there, but they are almost non-noticeable now and relatively low in frequency (approx 20 every 2hr or so, slightly more when the system is under heavier load).
I would also echo what others have said, thank you @gnif, not only for this patch but for looking-glass as well. Itâs been working fantastically so far, especially once I got the issues ironed out through use of your vendor reset module.
Is anyone able to get JACK output working on Pipewire?
Switching from a working JACK to Pipewire gives me the following in the logs:
2021-04-21 08:13:46.868+0000: Domain id=1 is tainted: custom-argv
char device redirected to /dev/pts/5 (label charserial0)
audio: Device hda: audiodev default parameter is deprecated, please specify audiodev=sound0
jack: jack_client_open failed: status = 0x11
jack: unable to connect to JACK server
jack: jack_client_open failed: status = 0x11
jack: unable to connect to JACK server
audio: Failed to create voice `dac'
I added the following to libvirt-qemu AppArmor profile to silence the obvious access control issue:
/etc/pipewire/* r,
capability bpf,
capability perfmon,
Also tried with AppArmor disabled, but same result.
Yes, when I used pipewire instead of pulseaudio and jack, I found that the jack output of QEMU didnât seem to work for me.
@gnif Are there any plans to develop âqemu-native-pipewire-audio-supportâ?
Iâm using pipewire with qemu jack backend few months now
Itâs amazing, almost zero delay even over network.
Iâm using libvirt so I can provide you only my XML, no cmdline.
<domain>
[...]
<devices>
<sound model='ich9'>
<codec type='micro'/>
<audio id='1'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x1b' function='0x0'/>
</sound>
<audio id='1' type='jack'>
<input mixingEngine='yes' fixedSettings='yes' clientName='vm-win'>
<settings frequency='48000' channels='1' format='f32'/>
</input>
<output mixingEngine='yes' fixedSettings='yes' clientName='vm-win'>
<settings frequency='48000' channels='2' format='f32'/>
</output>
</audio>
[...]
</devices>
[...]
<qemu:commandline>
[...]
<qemu:env name='PIPEWIRE_RUNTIME_DIR' value='/run/user/0'/>
</qemu:commandline>
</domain>
You also need symlinks to make pipewire default jack lib provider or in case of Arch Linux pipewire-jack-dropin
package from AUR.
Debian doesnât use symlinks for pipewire-jack client libs, but uses ld-config to assign a higher priority for them.
The environment variable is interesting though, will try when I test pipewire again when I have time.