psst
psst copied to clipboard
Sound Is Cracking When CPU Is Under Load
Describe the bug Sound is cracking when computer is under load.
To Reproduce Spin up some heavy load.
Expected behavior Sound should not be cracking.
Screenshots Not applicable.
Environment
- OS: Windows 10 Pro
- Version: 10.0.19043 Build 19043
Additional context Solution: Start psst with higher priority automatically. This has proven to work in the past couple days I've used psst. Probable enchancement: Make the audio buffer larger. I guess this might help. Not sure though.
Yes I've noticed this as well. We use audio buffer of 128KB, but I guess that increasing this would just help with some short spikes? There's also a couple of crates for raising the thread priority.
@myphs can you try the latest master please?
I just tried and it still was cracking.
Ok, I "fixed" this. It was an issue with my mouse and my headset, which were both connected via USB 3. When I moved the mouse the sound started crackling. I didn't realize this earlier, but it happens with other software, too. It just happend, that I switched USB ports for my mouse and headset just after I got psst and I was listening to music via psst when doing CPU intensive work. But just a few minutes ago I listened music with foobar2000 and it happened, too, for some reason. Of course it would never happen, when I was watching movies, because I wouldn't move the mouse. So. When both, mouse and headset, are connected to USB 3 on my docking station, the bandwidth is apparently diminished as such, that the USB soundcard for my headset won't get enough data and hence the crackling sound. Connecting the mouse to a USB 2 port instead fixed the issue, because afaik USB 2 and 3 use different controllers.
Haha, wow 😅 Happy you worked it out and thanks for letting me know!
Sadly I have to reopen this because apparently it's both: the mouse but also when under load (or something else? 🤔).
The crackling happens when I e. g. open up a few tabs in Firefox at the same time. Zero crackling with Foobar2000. Also I ran a stress test assuming the crackling should be constant and actually it wasn't that bad but still happening every few seconds.
When setting the priority in Task Manager to 'higher than normal' it's working fine no matter what.
For the record, the issue lies in cpal
, which does not set a high/real-time priority on its playback thread on Windows.
(Was part of the reason why I decided to drop cpal in my projects and roll my own)
A possible fix using the winapi
crate looks roughly like this:
use winapi::um::processthreadsapi::{
GetCurrentProcessorNumber, GetCurrentThread, SetThreadIdealProcessor, SetThreadPriority,
};
use winapi::um::winbase;
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setthreadpriority
#[repr(u32)]
pub enum Priority {
// BackgroundModeBegin = winbase::THREAD_MODE_BACKGROUND_BEGIN,
// BackgroundModeEnd = winbase::THREAD_MODE_BACKGROUND_END,
//
// Idle = winbase::THREAD_PRIORITY_IDLE,
// Lowest = winbase::THREAD_PRIORITY_LOWEST,
// BelowNormal = winbase::THREAD_PRIORITY_BELOW_NORMAL,
// Normal = winbase::THREAD_PRIORITY_NORMAL,
// AboveNormal = winbase::THREAD_PRIORITY_ABOVE_NORMAL,
// Highest = winbase::THREAD_PRIORITY_HIGHEST,
TimeCritical = winbase::THREAD_PRIORITY_TIME_CRITICAL,
}
pub fn pin(priority: Priority) {
unsafe {
let cpu = GetCurrentProcessorNumber();
let thread = GetCurrentThread();
SetThreadIdealProcessor(thread, cpu);
SetThreadPriority(thread, priority as i32);
}
}
But I'm fairly certain that needs to be applied in cpal
which does not give its user ownership over the actual thread. A hackaround would be to invoke that (once) in the buffer filling callback you give to cpal
- since that's run in the relevant thread - but that's obviously far from optimal.