tildearrow / furnace

a multi-system chiptune tracker compatible with DefleMask modules
GNU General Public License v2.0
2.26k stars 200 forks source link

Painful audio playback and high DSP usage on Linux (Pipewire Pulse Audio) #1154

Closed BlastlessAnthony closed 1 year ago

BlastlessAnthony commented 1 year ago

I've been dealing with this issue for a few weeks now, where Furnace just suffers heavily when it comes to playing back audio.

I never had this issue on Windows with WAAPI or JACK but on Linux (Pop OS! Ubuntu 20.04) the audio playback is so broken that it becomes annoying to edit songs; let alone listen to them.

I can't tell if this is just an issue with Pulse Audio, Ubuntu, Pop OS!, or just the hardware I have available but it's seriously annoying me.

I compiled Furnace from source instead of using the pre-built AppImages.

(If this issue sound familiar, its because I had this exact same problem on a old Macbook Pro 2015. The audio DSP was constantly broken making Furnace unusable.)

System Information (If this will help in any way.)

OS: Pop!_OS 22.04 LTS x86_64 
DE: Plasma 5.24.7 
WM: KWin 
CPU: AMD Ryzen 5 1400 (8) @ 3.200GHz 
GPU: AMD ATI Radeon RX 470/480/570/570X/580/580X/590 
Memory: 15928MiB 

Here is an example of the DSP being at maximum load while nothing is playing. image

This is something that I've never incountered when using Furnace on Windows, even when using the maximum amount of channels possible.

tildearrow commented 1 year ago

Buffer size? (Settings > Audio/MIDI)

FavoritoHJS commented 1 year ago

Can confirm something similar, but not quite as severe -- again, Pipewire with SDL selected, and at least 35% usage with any chip.

tildearrow commented 1 year ago

I mean, I want to know what is the "buffer size" setting set to. Additionally, the "sample rate".

FavoritoHJS commented 1 year ago

Buffer size to 512, but changing it doesn't affect usage much (no improvement when higher, and slight worsening when lower)

Sample rate to 48000 Hz, same as system. Lowering it seems to help, though -- overhead seems to lower from 25% to 5% when set to 8kHz.

tildearrow commented 1 year ago

Does enabling low-latency mode improve the situation?

FavoritoHJS commented 1 year ago

no, in fact it doubles the overhead.

tildearrow commented 1 year ago

Output of uname -a in the Terminal? Output of sudo cpupower frequency-info while a song is playing? In htop, find the Furnace process. Check if any of its threads have a negative PRI (priority). In htop, find the PipeWire process(es). Check if any of these have a negative priority. They should.

FavoritoHJS commented 1 year ago
[hjs@nixos:~]$ uname -a
Linux nixos 6.3.3 #1-NixOS SMP PREEMPT_DYNAMIC Wed May 17 12:02:08 UTC 2023 x86_64 GNU/Linux

[hjs@nixos:~]$ sudo cpupower frequency-info
analyzing CPU 2:
  driver: intel_pstate
  CPUs which run at the same hardware frequency: 2
  CPUs which need to have their frequency coordinated by software: 2
  maximum transition latency:  Cannot determine or is not supported.
  hardware limits: 800 MHz - 4.10 GHz
  available cpufreq governors: performance powersave
  current policy: frequency should be within 800 MHz and 4.10 GHz.
                  The governor "powersave" may decide which speed to use
                  within this range.
  current CPU frequency: Unable to call hardware
  current CPU frequency: 800 MHz (asserted by call to kernel)
  boost state support:
    Supported: yes
    Active: yes

Note that frequency ocassionally spikes to 900MHz. Normal for this machine.

There are 2 Furnace processes that use cpu, both have priority 20 nice 0. Their shown CPU usage matches closely with what the Audio load gauge shows. There are 2 Pipewire processes that use cpu -- one priority 9 nice -11 (prob. system) and one priority -21 nice 0 (prob. sandbox). Their CPU usage is, however, small (around 1% each) EDIT: Interestingly, furnace makes them use more CPU than other audio applications.

I'm guessing some waiting that normally should be instantaneous isn't, maybe see what you're doing with SDL? EDIT: I'm guessing something that should be instantaneous with raw pulseaudio just isn't with PW, and your code isn't handling that properly?

tildearrow commented 1 year ago

Hmmm... seems like everything's good except for the clock rate.

My code... You probably mean SDL's code. Can you try playing a song and checking CPU usage in top?

FavoritoHJS commented 1 year ago

seems like about 5-8% cpu, but since top records the sum of all cores and my cpu has 4 cores it's probably using that much of a core.

also appears like sdl is using alsa, i wonder if that's the problen

tildearrow commented 1 year ago

That's not good. Furnace using 32% of a core but audio load being higher than 80%? Sound like an scheduling problem, maybe in SDL but then maybe in PipeWire itself...

FavoritoHJS commented 1 year ago

fyi audio load was also around 30% for me

tildearrow commented 1 year ago

When playing a song or when it is stopped? If the former then that's fine unless there's stuttering/xruns. That doesn't seem to be the 80% you reported at the beginning.

FavoritoHJS commented 1 year ago

i'm not sure if you've noticed, but i'm not the original poster. the high audio load ocurrs whenever furnace would be outputting audio, so while playing a song or after pressing a key

tildearrow commented 1 year ago

Wait.... what?

Sorry!

tildearrow commented 1 year ago

@BlastlessAnthony Buffer size/sample rate? (Settings > Audio/MIDI)

BlastlessAnthony commented 1 year ago

Sorry for taking so long to respond, I was trying out different computer parts to see if the issue was with my computer. Unfortunately nothing changed.

Normally I use 44.1Khz with a Buffer Size of 512 (default). Changing the buffer sizes would make a small difference to the issue. Changing the audio quality to "Low" will make the issue even worse. Changing the playback sample rate wouldn't make a difference.

Just like what @FavoritoHJS said, using Low Latency Mode would make the issue worse.

I still feel as though this is a problem with the way I installed and setup Pipewire, as at some point I did have to reinstall it due to an audio bug.

I might try to reinstall Pipewire to see if that's the issue.

BlastlessAnthony commented 1 year ago

I have found a "work around" to this solution? It involves just changing the buffer size to any other value than the one saved and playback will be fine... until you reopen the program, then it requires the same action(s) to be done again.

Edit: Another work around is to build Furnace with Jack support and use the Jack audio backend, which eliminates the issue completely.

FavoritoHJS commented 1 year ago

interesting... this doesn't happen on pre4-hotfix, right?

tildearrow commented 1 year ago

I have found a "work around" to this solution? It involves just changing the buffer size to any other value than the one saved and playback will be fine... until you reopen the program, then it requires the same action(s) to be done again.

Edit: Another work around is to build Furnace with Jack support and use the Jack audio backend, which eliminates the issue completely.

Hmmmm.... late initialization? I will test something later.

tildearrow commented 1 year ago

Please test again with Git master! I have indeed found a huge regression in the playback code, but it's fixed now.

FavoritoHJS commented 1 year ago

looks like that fixed it!

also FINALLY ARROWS ON THE MERGED INSTRUMENT VIEW THANK YOU THANK YOU

tildearrow commented 1 year ago

@BlastlessAnthony Still waiting for feedback. Please test with 0.6pre7.

I will close this issue next week.

BlastlessAnthony commented 1 year ago

Oh whoops, I forgot about this.

I'm glad to say that the problem is finally fixed (on 0.6pre7)! I can now play on any chip with no X-runs to be heard and no high DSP load to be seen either.

tildearrow commented 1 year ago

Good to hear!

FavoritoHJS commented 1 year ago

just curious, what was the problem?

tildearrow commented 1 year ago

The problem was a poorly optimized MIDI clock/timecode generation code, running 11 million times per buffer.