rbn42 / panon

An Audio Visualizer Widget in KDE Plasma
GNU General Public License v3.0
191 stars 31 forks source link

[BUG] Popping caused by panon #36

Closed yuannan closed 3 years ago

yuannan commented 3 years ago

Desktop (please complete the following information):

Describe the bug Running panon causes popping and static to happen with audio streams that are usually fine.

pulseaudio -k // refresh the daemon and kills panon pacmd list-sinks | grep latency outputs: pre panon reinit and just playing music in Tauon music box

current latency: 95.26 ms
configured latency: 90.00 ms; range is 0.50 .. 341.33 ms
analog-output: Analog Output (priority 9900, latency offset 0 usec, available: unknown)

reinit panon > back-end > input device > Monitor of SONATA Audio Analog Stereo

current latency: 10.60 ms
configured latency: 6.94 ms; range is 0.50 .. 341.33 ms
analog-output: Analog Output (priority 9900, latency offset 0 usec, available: unknown)

For some reason when panon is running it will reduce the latency all the way down to 6.94 (and it always seems to be 6.94 when most latencies will change over time)

current latency: 42.61 ms
configured latency: 36.00 ms; range is 36.00 .. 341.33 ms
analog-output: Analog Output (priority 9900, latency offset 0 usec, available: unknown)

This DOES change. It seems like for whatever reason panon triggers a lower constant latency for a certain time. After a while it'll go back to dynamic latency and level out to around 40ms

Interesting observation

1/0.00694
        ~144.09221902017291066282

This seems to be improper handling of the rendering pipeline; polling something at my screen's refresh rate (144Hz). Might be an upstream issue from some libraries used but it does level out eventually and the popping stops. After a bit more testing this is directly related to the FPS set in panon (60fps will give 16.67ms constant for a bit) and not from your display, drivers, or anything else.

My hardware is a SONATA HD PRO at 384KHz and s32le. Don't think there is anything else strange about my setup but here is the pulse config anyway. /etc/pulse/daemon.conf


; daemonize = no
; fail = yes
; allow-module-loading = yes
; allow-exit = yes
; use-pid-file = yes
; system-instance = no
; local-server-type = user
; enable-shm = yes
; enable-memfd = yes
; shm-size-bytes = 0 # setting this 0 will use the system-default, usually 64 MiB
; lock-memory = no
; cpu-limit = no

high-priority = yes
nice-level = -11

realtime-scheduling = yes
realtime-priority = 8

; exit-idle-time = 20
; scache-idle-time = 20

; dl-search-path = (depends on architecture)

; load-default-script-file = yes
; default-script-file = /etc/pulse/default.pa

; log-target = auto
; log-level = notice
; log-meta = no
; log-time = no
; log-backtrace = 0

resample-method = speex-float-10
avoid-resampling = false
; enable-remixing = yes
; remixing-use-all-sink-channels = yes
; remixing-produce-lfe = no
; remixing-consume-lfe = no
; lfe-crossover-freq = 0

; flat-volumes = no

; rescue-streams = yes

; rlimit-fsize = -1
; rlimit-data = -1
; rlimit-stack = -1
; rlimit-core = -1
; rlimit-as = -1
; rlimit-rss = -1
; rlimit-nproc = -1
; rlimit-nofile = 256
; rlimit-memlock = -1
; rlimit-locks = -1
; rlimit-sigpending = -1
; rlimit-msgqueue = -1
; rlimit-nice = 31
; rlimit-rtprio = 9
; rlimit-rttime = 200000

default-sample-format = s32le
default-sample-rate = 384000
alternate-sample-rate = 48000
; default-sample-channels = 2
; default-channel-map = front-left,front-right

default-fragments = 2
default-fragment-size-msec = 10

;enable-deferred-volume = no
;deferred-volume-safety-margin-usec = 8000
; deferred-volume-extra-delay-usec = 0
rbn42 commented 3 years ago

Panon is running python beneath QML. In your case, panon is expected to behave like this piece of code.

import time
import soundcard as sc # Make sure soundcard is installed

for mic in sc.all_microphones(exclude_monitors=False):
    if 'Monitor of SONATA Audio Analog Stereo' in mic.name:
        break
else:
    raise

fps=60 # the FPS set in panon, maybe 144?
stream = mic.recorder(44100,2,blocksize=44100/fps)
# or just stream = mic.recorder(44100,2) , omitting blocksize 
stream.__enter__()

while True:
    time.sleep(1/fps)
    data= stream.read(44100/fps, exception_on_overflow=False)

According to https://github.com/bastibe/SoundCard#latency, omitting blocksize (by removing this line)

https://github.com/rbn42/panon/blob/4959667b2e0065b47c23a7343c29838bafc12575/panon/backend/source.py#L139

will honor your system's default latency configuration, is a possible solution.

rbn42 commented 3 years ago

I did some tests on my system.

  1. It is confirmed that changing panon's fps from 60 to 144 will reduce the latency (shown by pacmd)
  2. Omitting blocksize does not make difference, not like soundcard's doc said.
  3. But reducing latency does not cause popping on my system.
yuannan commented 3 years ago

I did some tests on my system.

1. It is confirmed that changing panon's fps from 60 to 144 will reduce the latency (shown by pacmd)

2. Omitting blocksize does not make difference, not like soundcard's doc said.

3. But reducing latency does not cause popping on my system.

What cpu do you have at what bit rate and depth? I have a 1700 at 3.85Ghz and 384Khz and 32bit deep which I think causes more cycles on the CPU along with a very expensive resampling algorithm on top. This probably only affects me and other people on very high settings and older CPUs. This problem also fixes it self after a while so don't lose sleep after this. Not a big deal.

rbn42 commented 3 years ago

What cpu do you have at what bit rate and depth?

Intel Celeron G1820 (2) @ 2.700GHz and default settings.

This problem also fixes it self

You mean after my commit? Then it is because I did what soundcard's doc told me to do, and it fixed your problem.

yuannan commented 3 years ago

You mean after my commit? Then it is because I did what soundcard's doc told me to do, and it fixed your problem.

No, no. I mean the issue goes away after around a minute or so. The latency goes back up to around 40ms and it's fine. This is not a permanent popping, more of a temporal "recalibration" period. The problem is that panon or some of it's dependencies causes this to occur.

This is why I said it's not a big deal and not high on the priority list as it's annoyance and not anything breaking.