Hi folks!
I recently posted an issue about frequent buzzes/pops/farting noises that now occur after upgrading to Canada Goose when launching/exiting any game or app, which were not present in Goose. (Canada Goose - Buzzing/popping sounds)
This might not be an issue for everyone, or on all devices, but it certainly occurs on my RG35XX Plus and I suspect other similar Ambernic devices will be similarly affected.
I intended for that original issue/post to serve as a starting point for discussion for an investigation/fix, but it was immediately closed. Fair enough, Iām new here, and the first thing I do is ācomplainā with an issue, which has seemingly already caused headaches! However, as this leaves me with nowhere to follow up with my workaround and proposal for a simple system-wide fix, Iām doing it in āgeneralā. Apologies if this is the wrong place for it!
Iāve done some research into whatās causing these buzzes and eliminated 99% of them (on my device at least). As xonglebongle rightly pointed out, itās not likely we can eliminate all of them on all devices and in all software, but I think the fixes below should eliminate the worst offenders for most devices, and I think itās worth addressing for the bread-and-butter stock applications like RetroArch.
Iāll start with a simple workaround for end users, then discuss further fixes in increasing technical detail, explain whatās going on, and how the fixes could be included in muOS (if appropriate).
A few simple config tweaks below result in a nice buzz-free and stable audio output on my RG35XX Plus, with no buzzes/popping (except at power on and power off), with minimal battery drain/performance overhead.
Iād be grateful if people with different devices and software collections could test these fixes and let me know if they work on other systems too. If so, Iāll create a Pull Request on github with the fixes and scripts required to build them into muOS.
And some of you with devices not affected by this are probably wondering WTF Iām talking about ā lucky you, you can probably ignore this post, although testing anyway would be helpful if you are able to lend a hand.
Simple Partial Fix for End-Users
Change the audio sample rate in affected apps to match the muOS front-end standard rate of 48000 Hz. (The switching between playback rates is one of the main culprits causing the buzzes.)
In particular in RetroArch, which defaults to 44100 Hz in muOS. You can do this as an override per core, OR enable RetroArch Config Freedom in ConfigāGeneral SettingsāAdvanced Settings, then save the change to your global RetroArch config file.
You can find the playback rate in RetroArch SettingsāAudioāOutputāOutput Rate (Hz). Set it to 48000 and save your core override (or main configuration file, if you have RetroArch Config Freedom enabled.)
This will fix the buzzes that plague RetroArch launches and exits (provided your core launches within a few seconds), but other apps will still suffer if they use different playback rates (many use CD Audio at 44100 Hz as a default).
Still, if you primarily use your device for retroarch, you now no longer have to suffer the embarrassing farting noises every time you switch games! ![]()
If your other affected apps have sample rate config setting, try setting them to 48000 too and see if that fixes things.
A Better Solution if Youāre Feeling Brave
If you donāt mind editing some behind-the-scenes config files, we can lock our pipewire audio backend to 48000 Hz, so all system audio will be output at a consistent playback rate. (Pipewire will resample application audio produced at other sample rates, without locking applications to that fixed system rate.)
To do this, edit the file /opt/muos/share/conf/pipewire.conf. Change the line for ādefault.clock.allowed-ratesā to be as follows:
default.clock.allowed-rates = [ 48000 ]
(i.e. remove the other allowed rates, leaving only 48000)
Save, and then restart your device. This should eliminate the vast majority of buzzes in most applications and games, regardless of what sample rate they are using. For optimum sound quality and performance you should still try to stick to 48000 Hz wherever possible in apps and cores, but the difference is usually imperceptible.
A Complete Fix(?)
OK, we got pretty far, but we can do better!
The last troublesome apps will be those without audio. e.g. Dingux Commander, those which are slow to load, or stall audio in other ways. Youāll notice they emit a their fart noises a few seconds after launch, and again at exit. This is due to wireplumber shutting off idle audio paths after a few seconds, and re-enabling them when the muOS front-end restarts.
To fix this we need to tell wireplumber not to suspend when idle. Unfortunately, we canāt tell it to disable the shut off mechanism altogether (a timeout value of zero), as this doesnāt work correctly on some systems (including, as it happens, my ambernic), so we set it to a very large value instead.
This can be done with a little more work, but is easily doable if youāre confident manipulating system config files and symbolic links through a shell, e.g. the virtual terminal provided with muOS.
- Create a new text file in /opt/muos/share/conf/wireplumber.lua
- Give it the following contents:
rule = {
matches = {
{
{ "node.name", "matches", "alsa_output.*" },
},
},
apply_properties = {
["session.suspend-timeout-seconds"] = 86400
},
}
table.insert(alsa_monitor.rules, rule)
- Make this file executable with:
chmod ugo+x $MUOS_SHARE_DIR/conf/wireplumber.lua - Create a symbolic link for wireplumber that links to the file we created above with:
ln -s $MUOS_SHARE_DIR/conf/wireplumber.lua /usr/share/wireplumber/main.lua.d/60-muos-wireplumber.lua - Restart your device.
Voila, no more farting noises! ![]()
Well, there will inevitably be some when powering on the system, and shutting it down. This can likely be solved too, but these sorts of buzzes are very hardware specific, and solutions may vary between both models of device, and potentially even individual devices produced at different times. I may investigate this further if I have time, but currently I have limited access to devices, and weāre talking diminishing returns at this point I think.
So⦠Fixed?
Iād be grateful if others could try the above and let me know if any apps/ports, etc. misbehave. Unlike holding open a background alsa audio connection, this approach shouldnāt (in theory) cause timing issues in apps/games, because they all see what looks like an alsa device running at whatever rate they requested, and pipwire/wireplumber resamples all their audio to the system rate of 48000 Hz. But perhaps there are other improvements necessary to get pipewire working seamlessly across the board, and Iāve not checked all the possibilities. Only time and testing can tell!
Including these fixes in muOS
Should the above be deemed an acceptable solution for inclusion within muOS itself, I suggest we modify /opt/share/muos/script/system/pipewire.sh to create the wireplumber link if it doesnāt exist, and keep the muOS wireplumber.lua override code in /opt/share/muos/conf as Iāve done above. This keeps the muOS config almost entirely separate (apart from that one symlink) from the stock library config, which would seem (to my newbie eyes) to be the convention currently used by muOS, and alongside the related pipewire.conf thatās already there. The rest is just simple tweaks to existing files.
An optional nice-to-have might be a user config option to choose between fast-and-dirty resampling (less CPU), standard balanced resampling, or high quality resampling (more CPU). But tbh, these arenāt exactly hi-fi devices, and the stock resampling rate should be perfectly fine.
After making these tweaks, I think it should also be possible to remove the always-on audio channel in the muOS front-end (in golden.c if memory serves), as audio should now remain up regardless of what applications may be doing, but I havenāt tested this.
A More Detailed Explanation of Problems and Proposed Fix
The buzzes/farts/pops introduced in Canada Goose are the result of DAC hardware state changes, which occur when playback rates are changed, and when audio streams go idle/hardware is powered down. The above fixes work by minimizing such state changes and keeping all output at 48 kHz. Audio hardware isnāt supposed to make noises during such state changes, but hey, these are gaming handhelds, not professional audio equipment! We have to work with what weāve got.
These state changes are primarily triggered by:
- most notably: a mismatch between muOS front-end always-on audio stream playback rate (48 kHz) and the RetroArch default value (in muOS at least: 44.1 kHz)
- other similar playback rate mismatches/changes in other apps/ports
- idle audio streams causing sample rate drop-downs
- audio back-end switching rates to match requested application audio rates (not necessary, and unwanted if we want a stable audio output)
- idle audio suspending audio stream processing after a timeout of 5 s (wireplumber default) in applications with no audio, and when there are delays switching between apps or loading cores/ports, or other audio interruptions when apps are busy doing other stuff.
Although it seems muOS devs have gone to some lengths to stick to a standard audio rate of 48000 Hz in the front-end and many config files, this has not been consistently applied everywhere, so there are frequent DAC state changes during normal operation.
The above fixes work by eliminating unnecessary DAC state changes by:
- locking the pipewire/wireplumber output audio path to a fixed 48000 Hz, even when idle, and even when apps/games request different rates. Apps and games will still process audio at their requested rates, but pipewire will invisibly resample audio seamlessly to match the system output. So this should not affect any app that outputs audio through pipewire. If pipewire is correctly configured, it should process all audio output through ALSA, pulse, and OSS (if set up). Itās possible some ports might bypass pipewire (shouldnāt but, hey, ports are a crazy mixed bag!). I havenāt checked all the available configurations/software (I donāt have the time nor resources) so any assistance here by willing testers gratefully received!
- setting commonly-used applications (i.e. RetroArch+cores) to an audio playback rate 48000 Hz, consistent with other parts of the system. Not strictly necessary with the other fixes in place, but technically it will give an optimal audio path.
- Preventing sample rate drop-off when idle, and preventing idle shutdown. This occurs after launching an app that uses no audio, and sometimes between exiting one app and launching another as audio is dropped for brief moments.
There is potentially more we can do to further eliminate all buzzes and pops, but i) itās quite a bit more work, and ii) the above changes are pretty easy and quick to implement and fix 99% of the buzzes and pops that occur during everyday use (on my system at least. YMMV). It also gives a handy place that devs and users can override wireplumber settings, if necessary, without having to compile anything or include a Lua interpreter with muOS.
Itās possible my proposed fixes have knock-on effects elsewhere. I can only test on my device and software setup. However, in theory, this approach should provide a consistent stable audio path for all programs running under muOS, provided their audio is routed through the standard ALSA/pipewire routing. (Itās similar to the approach used by modern Windows audio apps and Mac CoreAudio, so if we can get it configured correctly it should solve the majority of such audio annoyances.)
Itās likely this buzzing issue isnāt being experienced by everyone ā it might affect only certain models or even specific manufacturing batches ā or just not deemed an important enough issue ā and so it might not be worth rolling into muOS itself and risk negatively affecting others with config changes. But if this post stays up, hopefully someone reading this at least gets some benefit from it if they are plagued by a farting device after upgrading to Canada Goose!
If, after testing and/or discussion, people are happy for me to go ahead, Iāll put together a Pull Request on github with my proposed fixes, when I get some more time to work on this and set up a proper dev environment instead of poking around live on my device. (Otherwise, it shouldnāt be too much work for someone who already has a proper muOS dev/build/test environment if they have the time/inclination before me.)
The effects of always-on audio on battery/performance are negligible, and having a nice quiet stable audio output would be worth it anyway. Most games/apps will be playing audio anyway, and the muOS front-end currently keep audio fired up continuously anway. Powering down the DAC is not worth the audio quality issues it causes, IMO.
Even if the fixes above arenāt adopted in muOS, I would humbly request that the default audio rate in the standard muOS config be changed back to 48000 Hz (to match the front-end always-on audio channel, and also the stock RetroArch default value), so at RetroArch least RetroArch can launch/exit silently on affected devices. Maybe thereās a good reason why this was changed, but it wasnāt clear to me when I was poking around in the commit log, or I missed it.
Hopefully the above is clear and I havenāt waffled on too much⦠Iām tired, and I always write too much when Iām tired⦠(apologies in advance for the inevitable typos/mistakes).
Anyway, hope this is useful to somebody!
guzzloid