[alsa-lib] — package the PCM meter scope fixes (not for merge as-is)#24
[alsa-lib] — package the PCM meter scope fixes (not for merge as-is)#24Gjuju wants to merge 1 commit into
Conversation
d6a0509 to
f20e0eb
Compare
|
Interesting. Assuming the S16 fix is in place, won't MPD perform DSD to PCM on-the-fly conversion with Peppy in the audio chain bypassing the proposed DSD level analysis? |
|
On your question: you're right about this #24, the bit-density decode. It only fires when the DAC takes native DSD and The s16 scope produces the S16 buffer; libpeppyalsa consumes it. #23 can only act if that buffer exists and holds something — alsa-lib decides both. #23 — libpeppyalsa Worth stating plainly: none of this applies unless Peppy is enabled. The
What #24 adds to #23: a crash #23 cannot reach — different component, and it kills the process before libpeppyalsa runs — plus the native-DSD case #23 excludes by design. No overlap. The two are independent: #23 is a leaf package at no system cost, #24 asks moOde to ship and hold its own libasound. |
|
Sorry, I edited many times , was hard to explain ;-) |
|
No prob. From my memory on DSD and Peppy: The user @ArthurDent42 reports playing DSD native and MPD converting to PCM w/o experiencing any errors. I think this may be due to his config having either SoX on at 16bit or CamillaDSP enabled. Both of these will allow MPD to do on-the-fly conversion to PCM and avoid the ""Socket open failed" error. Also, there is a solution that implements an MPD configuration with two parallel audio outputs:
Something like this in mpd.conf I recall testing this but deferring any work on it because of the messiness of manipulating the configs and audio chain setup. |
|
I had a hard investigation day... at first I couldn't reproduce the bug this PR fixes — my test box turned out to be running the patched lib without me knowing (leftover LD_LIBRARY_PATH from an earlier test session). So I wiped everything and validated on a freshly flashed Pi. Now I know exactly why I had to solve this bug, and it matters for 10.3.1. The crash is exposed by #769 (Peppy: bind the softvol control to the hardware mixer element — my own PR). Before #769, the softvol control name never matched a hardware element, so softvol stayed active in the Peppy chain. Softvol only accepts linear PCM (S16/S24/S32) — it refuses DSD at negotiation — so MPD always converted DSD to PCM upstream and the meter only ever saw PCM. That softvol was acting, by accident, as a shield. After #769, alsa-lib recognises the hardware control and softvol removes itself from the chain ("hardware control - no need for softvol" in pcm_softvol.c). The chain becomes transparent — which is what we wanted for the double attenuation — but now, with a DSD-capable DAC + hardware volume + The UI shows "Socket open failed", and with a DSD album queued it's a crash loop. Reproduced end-to-end on a freshly flashed Pi 3B, everything stock, same box, same DAC, same .dsf, minutes apart:
Conditions: Peppy enabled + DSD-capable DAC + hardware volume + The alsa-lib patch in this PR fixes the crash (silent buffer instead of abort) and the second patch gives real needles on native DSD as a bonus. The alternative, if holding a patched libasound is too heavy, is a moOde-side guard: make Peppy + |
|
Got it. That explains the MPD error now w/native DSD+peppy. I don't think its a big enough issue to hold back shipping 10.3.1 though because I really need to get our users those RB bug fixes :-) I can mention the DSD thing in the release announcement. I'm not opposed to deploying these patches after testing but I'm a little unclear.
|
|
Good timing for that question, because the answer is "no — it's the opposite", and it splits into the two options on the table. The alsa-lib patch does NOT make MPD convert. With it, native DSD flows bit-perfect through the whole chain to the DAC — nothing converts anywhere. What changes is inside the meter: the s16 scope stops aborting when it meets a format it cannot convert (that's the crash fix), and it reads the level directly from the DSD bit density (that's the second patch — the needles move on native DSD itself). MPD's own on-the-fly conversion only ever triggers when something in the chain refuses DSD — a PCM-only DAC, a DSP. The alsa-lib patch removes the last reason for that refusal, it doesn't add one. The thing that makes MPD convert when Peppy is in the chain is a different, moode-side fix — and since you're shipping 10.3.1 without holding it, it's exactly what it was designed for. One file, So the two compose:
Both were validated yesterday on a freshly flashed Pi 3B, each variable isolated. The guard can ship in 10.3.1 or right after with zero risk to anything else in the chain; this PR is the full fix for whenever you're ready to test it, and the guard's file comment already says to remove it then. |
|
Still confused. Currently with 10.3.1 (+769 patch), Hardware volume, Peppy on and a native DSD DAC, playing a DSD file throws the MPD error. With just the alsa-lib patch what happens? |
|
It plays — bit-perfect native DSD, and the needles move: the first patch stops the abort, the second reads the level from the DSD bit density. Measured yesterday on a freshly flashed Pi 3B (stock everything except this PR's libasound), Hardware volume, Peppy on, So: same DSD reaching the DAC as today, minus the crash, plus working needles — nothing else in the chain changes. Before #769 the stray softvol refused native DSD so MPD silently converted to PCM (needles moved, but the DAC never got native DSD); with this patch the chain stays transparent — native DSD reaches the DAC bit-perfect, the meter no longer aborts, and the needles move from the DSD bit density itself. |
|
I don't understand this regarding just the alsa-lib patch If MPD is playing native DSD then how can PCM peppy needles move? |
|
That's exactly what the peppyalsa never sees the raw stream — it only reads the S16 buffer alsa-lib's scope produces, and on native DSD that scope had no conversion, so it asserted before peppyalsa ever ran (that's the crash). |
moOde uses the distro's alsa-lib, whose `type meter` scope - the one libpeppyalsa taps for the VU meter - has two defects that show up on DSD. The first is a crash, and it is not DSD-specific. s16_enable() returns -EINVAL for any format it cannot convert to S16: the DSD formats, the 3-byte packed ones (S24_3LE and friends, which plenty of USB DACs expose natively), float. The failure is swallowed, the buffer is never allocated, and the accessor that scopes call then asserts on it - so MPD dies mid-playback with "Socket open failed". alsa-lib does this to its own level scope too. The patch hands out a silent buffer instead. The second is the missing feature behind it: with the crash gone, needles still sit still on DSD because the scope has no conversion for it. DSD carries no sample values, only a bit density - over a short window the proportion of ones is the amplitude - so one S16 sample per frame can be recovered by counting bits. The scale follows the format: 0 dBFS in DSD is a 50% modulation index. Verified on the same master in both formats: native DSD64 reads min 2 / max 21 / mean 7.1 where its FLAC 96/24 reads min 2 / max 22 / mean 7.6. The DAC keeps receiving DSD_U32_BE bit-perfect - the meter is a passive tap and neither patch touches what is played. Both are submitted upstream as alsa-project/alsa-lib #516 and #517. Drop this package once they are released and reach the distro. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
f20e0eb to
d2b65cc
Compare
|
Ok, makes sense now. |
What changed
moOde #769 (binding the Peppy softvol control to the real hardware mixer element) made the ALSA chain correct: on a hardware-volume DAC, softvol now removes itself and the chain is transparent. Before #769, that stray softvol silently refused DSD, so MPD always converted upstream and native DSD never actually reached the DAC while Peppy was enabled — the old chain only looked like it played DSD.
Correctness exposed a latent alsa-lib defect: with the chain transparent, native DSD reaches the
type meter, whose s16 scope has no DSD conversion — and instead of failing gracefully it asserts and kills the caller:Conditions: Peppy enabled + DSD-capable DAC + hardware volume +
dop "no"(the default) + a DSD file. Verified on a virgin Pi: the stock 10.3.0 image (pre-#769) plays the same file fine; after deploying develop, same box, same DAC, same file, MPD aborts. 10.3.1 ships this combination.What each patch does — measured, one variable at a time
The recipe carries the two patches as separate files, mirroring alsa-project #516/#517 (both reopened upstream):
dop=no(native DSD)dop=yes(DoP)alsa_lib_scope_no_abort.patchis the release fix — no abort, regardless of format or DSD settings (it also coversS24_3LE/float, which crash the same way).alsa_lib_scope_dsd_levels.patchis the feature on top — real needles on native DSD. Since any decision means rebuilding alsa-lib once, both ship in one build here; if you want a crash-fix-only package, drop the secondrbl_patchline and the .deb is minimal.The honest cost, unchanged
This is still
libasound, the library everything links, and the package needsapt-mark holduntil the upstream fixes reach a base OS (years, not months). The alternative that also protects 10.3.1 without a held library is a moOde-side guard — refuse or convert when Peppy is enabled withdop "no"on a DSD-capable DAC — at the price of no meter on native DSD. Your call; the DoP column is covered either way by the peppy-alsa patch in #23.