-
Notifications
You must be signed in to change notification settings - Fork 108
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SID plugin stutters when plays sid files with PipeWire Output plugin #1401
Comments
Confirmed with Fedora 40 and 4.4-beta1. This is interesting considering that the input plugin is "output plugin agnostic", i.e. it uses Audacious' audio output API and doesn't distinguish between e.g. Pipewire and PulseAudio itself. |
It is probably a buffer size issue. Some of the emulator plugins produce audio in large chunks, then do CPU-heavy processing without producing any more audio for a while, then produce another large chunk. If the output buffer isn't large enough, then you get underruns. |
I tried all the other available Output plugins (PulseAudio, ALSA, SDL and Jack) and only the PipeWire Output plugin presents this issue. I think the problem is strictly caused by the PipeWire Output plugin. |
The buffer size is indeed much smaller than in other output plugins. Sizes for a 44100 Hz stereo file:
pipewire: m_stride = FMT_SIZEOF(m_aud_format) * m_channels; // 4 * 2 = 8
m_frames = aud::clamp<int>(64, ceilf(2048 * m_rate / 48000.0f), 8192); // 2048 * 44100 / 48000 = 1882
m_buffer_size = m_frames * m_stride; // 8 * 1882 = 15056 pulseaudio: int buffer_ms = aud_get_int("output_buffer_size"); // 500
size_t buffer_size = pa_usec_to_bytes ((pa_usec_t) 1000 * buffer_ms, & ss);
// (((time * rate) / PA_USEC_PER_SEC)) * (size_table[spec->format] * spec->channels)
// 1000 * 500 * 44100 / 1000000 * 4 * 2 = 176400 jack: int buffer_time = aud_get_int("output_buffer_size"); // 500
int buffer_size = aud::rescale (buffer_time, 1000, rate) * channels; // 22050 * 2 = 44100 sdl: int buffer_ms = aud_get_int ("output_buffer_size"); // 500
int buffer_size = 2 * chan * aud::rescale (buffer_ms, 1000, rate); // 2 * 2 * 22050 = 88200 @jlindgren90: I don't know what buffer size would be good for PipeWire. Should we use the same value and calculation as for PulseAudio (see patch below)? Are the values even comparable or did I compare apples with oranges? 😃 diff --git a/src/pipewire/pipewire.cc b/src/pipewire/pipewire.cc
index f1d58800e..1fbce6deb 100644
--- a/src/pipewire/pipewire.cc
+++ b/src/pipewire/pipewire.cc
@@ -343,9 +343,11 @@ bool PipeWireOutput::init_core()
return false;
}
+ int buffer_size = aud_get_int("output_buffer_size");
+
m_stride = FMT_SIZEOF(m_aud_format) * m_channels;
m_frames = aud::clamp<int>(64, ceilf(2048 * m_rate / 48000.0f), 8192);
- m_buffer_size = m_frames * m_stride;
+ m_buffer_size = buffer_size * m_rate / 1000 * m_stride;
m_buffer = new unsigned char[m_buffer_size];
return true; |
@radioactiveman the buffer size should indeed respect the "output_buffer_size" setting. That is in milliseconds, so you need to convert to audio frames first based on the sample rate. It looks like the
|
By the way, these are all about correct for the default 500ms buffer size, but there is some unit confusion:
|
@jlindgren90 While that change fixes the stuttering, it breaks the main window's spectrum analyzer in the bottom right corner, which slows down so much it isn't in sync with the audio anymore. |
Probably the delay calculation in the pipewire plugin is not correct. |
I performed several tests modifying the "Buffer size" and the "Bit depth" settings from the UI and the stuttering issue was always present using the PipeWire Output plugin. Even using a Buffer size of 10,000 ms (ten seconds) did not solve the problem. It seems the Buffer size setting is completely ignored by the PipeWire Output plugin. |
Yes, this is what we are discussing how to fix. |
@mschwendt: Can you please try the patch below? It fixes the stuttering for me without impact on the visualizations. @jlindgren90: Are you fine with including this fix as workaround for 4.4? For 4.4.1 we can look for a proper solution. diff --git a/src/pipewire/pipewire.cc b/src/pipewire/pipewire.cc
index f1d58800e..597fb5c08 100644
--- a/src/pipewire/pipewire.cc
+++ b/src/pipewire/pipewire.cc
@@ -343,9 +343,11 @@ bool PipeWireOutput::init_core()
return false;
}
+ // TODO: Respect buffer size setting from libaudcore ("output_buffer_size")
+ // See also: #1401
m_stride = FMT_SIZEOF(m_aud_format) * m_channels;
m_frames = aud::clamp<int>(64, ceilf(2048 * m_rate / 48000.0f), 8192);
- m_buffer_size = m_frames * m_stride;
+ m_buffer_size = 4 * m_frames * m_stride;
m_buffer = new unsigned char[m_buffer_size];
return true; |
I don't think changing m_buffer_size without changing m_frames is correct - it looks like they are supposed to be in sync. But I did not write this code so maybe I am missing something. |
Here it also breaks the main spectrum analyzer in the aforementioned way. For all input plugins. |
Yes, I spoke too soon, sorry. 4 times the size affects the visualizations. And with 2 times it is probably the same, but less noticeable. Since there is another workaround (use the PulseAudio output plugin), this issue should be no blocker for Audacious 4.4. |
Hi @trialuser02, Could you clarify this question please as Qmmp developer and author of its PipeWire plugin? m_frames = aud::clamp<int>(64, ceilf(2048 * m_rate / 48000.0f), 8192); P.S. https://sourceforge.net/p/qmmp-dev/code/11337/ needs a version check (see audacious-media-player/audacious-plugins@932e1bc) or let CMake check for version 0.3.33. |
Hi @radioactiveman |
What's so ununsual here is that compared with 30 years ago, SID emulation doesn't create high load anymore. Sure, the modern libsidplay versions are "cycle-based" under the hood as to offer realtime emulation capabilities. But within the Audacious input plugin it's still only a "fill this buffer with samples" call as far as I know, and that will be done quickly enough. When PulseAudio was new, there were plenty of buffering issues, too, compared with ALSA output. |
Describe the bug
When you play any SID file using the PipeWire Output plugin, the audio stutters every second.
If you switch to the PulseAudio Output plugin the SID playing is smooth with no stuttering.
Steps to reproduce
Expected behavior
SID audio should be played without stuttering.
Additional information
The text was updated successfully, but these errors were encountered: