Repository navigation
t2bce_audio: playback crackle builds up over minutes and resets on stream restart (timer-driven copy drifts against the T2 read position) — MacBookPro16,2, linux-t2 7.2.4 #28
Description
Activity
Confirming this on MacBookPro16,1 (16" 2019), same kernel and driver version as your report.
Model: MacBookPro16,1 (Mac-E1008331FDC96864) Kernel: 7.2.4-arch1-Watanare-T2-2-t2 Driver: t2bce_audio 0.02 (staging), srcversion A4BC0767B62E451D7DF4BD7 Userspace: PipeWire 1.6.8, WirePlumber 0.5.17 DSP graph: /usr/share/t2-linux-audio/16_1/graph.jsonSymptoms match yours exactly: playback starts clean, a crackle appears after several minutes and grows, and pausing for more than ~5 seconds clears it completely for another few minutes.
One extra data point that supports the timer-drift analysis: userspace sees nothing wrong while the crackle is plainly audible. Captured during an active episode:
$ pw-top -b -n 2 R 34 1024 48000 1.4ms 71.8us 0.06 0.00 0 S24_32 6 48000 alsa_output.hw_Audio_0 R 78 0 0 6.1us 1.2ms 0.00 0.05 0 F32P 6 0 + effect_output.t2-161-speakers R 143 1024 48000 28.0us 29.5us 0.00 0.00 0 F32LE 2 48000 + Google ChromeERRis 0 on every node, and the ALSA buffer never comes close to draining:$ cat /proc/asound/card0/pcm0p/sub0/status state: RUNNING delay : 1892 avail : 14748 avail_max : 15660 (buffer_size 16640)journalctl --user -u pipewire -u wireplumberstays completely silent for the whole episode. So no xrun is ever reported upward, which is what you would expect if the position is synthesised fromCLOCK_MONOTONICrather than read back from the T2. The fabricated period is visible in hw_params too:period_size: 1 buffer_size: 16640Two things ruled out locally, in case it saves anyone else the detour:
- Not thermal. This machine idles hot (~70C, dGPU drives the internal panel and cannot runtime-suspend) and that was my first suspicion. It reproduces on a cold machine at idle temperatures, so package throttling is not required.
- Not userspace scheduling. PipeWire runs
SCHED_OTHERnice 0 on every thread here includingdata-loop.0, becausertkit-daemonis masked on this install. Even so, no node reports a missed deadline during an episode and the DSP chain uses ~1.2ms of a 21.3ms budget, so the audio thread is comfortably keeping up. Whatever is corrupting the stream is below PipeWire.
I also briefly suspected output level, since the sink was at 1.00 while the 16,1 DSP profile ships
state.default-volume = 0.75. A single drop to 0.55 coincided with it clearing, but that was not a controlled test and I would not read anything into it, especially given your note that it reproduces on the raw PCM with the DSP chain bypassed.Happy to test a patch on 16,1 if that would help confirm the fix across models.
Reacted by michelkroonConfirm, same happening in here. Macbook Pro 16inch, 2019 model. Linux Debian 13 with KDE.
Kernel : 7.2.6-1-t2-trixieSame issue here. Macbook Pro 13inch 2020 model. Fedora 44 with GNOME.
Kernel: 7.2.6-300.t2.fc44I moved back to Kernel: 7.1.9-200.t2.fc44.x86_64 where the issue was not present.
Don't know what to do for debugging or providing the correct information for the dev's to find the issue unfortunately.
Same problem here, Macbook Air 2019. Bluefin/Fedora atomic from kansei-os repo. Image includes "t2linux-audio-2.2.0-1.20260917git9527bff.fc44.noarch"
I found that by changing the power plan to the latency-performance setting (
sudo tuned-adm profile latency-performance) I was able to play music from MPV for four hours without detectable distortion.Update: Over the past few days it's started so power plans just delay it if anything
same syndrome here: kernel 7.2.4-arch1-Watanare-T2-2-t2
Everyone wiith the issue
Getting PID:
$ ps -eo pid,rtprio,comm | grep bce_dma ### 50 irq/45-bce_dmaThe ### is the PID.
Boost it's scheduling priority:
$ sudo chrt -f -p 15 ###It's not permanent (won't survive a reboot, so jjust do that if you want to undo it), but it can be made permanent if it helps. And I can't promise that it'll get rid if the issue for people who have audio playing endlessly; as it should extend the time needed to kick in, so it's a simple bandage until a kernel patch can solve the bug. For me it at least delays it long enough that I can play streaming audio for five hours without popping and glitching. And it's less obsusive than the only other option I could think of (a timer in cron resetting pipewire every hour, an inelegeant solution.)
This is fixed on latest Kait2en's t2bce_audio and will be pulled to t2linux soon.
Reacted by RomanB and Hajoo Chung
Hardware: MacBookPro16,2 (13" 2020, T2). Kernel: linux-t2 7.2.4.arch1-2 (Watanare),
t2bce_audiov0.02 (staging).Userspace: PipeWire 1.6.8, WirePlumber 0.5.17, t2-apple-audio-dsp 16_2 graph (also reproduces on the raw PCM without DSP).
Symptom
Playback starts clean. After some minutes a crackle appears, grows steadily, becomes louder than the programme material, and vanishes instantly whenever the stream stops and restarts (e.g. a YouTube ad, loading a new video, pause/resume > 5 s). Then it builds up again.
Evidence
/proc/asound/card0/pcm0p/sub0/statussampled every 5 s for a minute), CPU idle.hw_params:period_size: 1,buffer_size: 16640,SNDRV_PCM_INFO_NO_PERIOD_WAKEUP.tstamp.Root cause (from
t2bce_audio/pcm.cat AdityaGarg8/t2bce525498b5, "Update 1", 2026-09-13)t2audio_playback_timer()runs every 1 ms (T2AUDIO_PLAYBACK_TICK_NS) and doesframes = elapsed_ns * runtime->rate / NSEC_PER_SEC, thent2audio_playback_copy()copies that many frames from the ALSA ring into the BCE shared buffer (buf->ptr) atbridge_pos, andt2audio_pcm_pointer()returnsplayback_frames % buffer_size.The host-side write position is therefore driven purely by CLOCK_MONOTONIC, while the T2 consumes the shared buffer on its own audio clock. There is no feedback from the T2 on the playback path. Commit
ab4b0ac2("correlate host and remote clock") only feeds the remote timestamps into the capture pointer (time_from_start = ktime_get_boottime() - stream->remote_timestamp); the playback branch oft2audio_pcm_pointer()still returns the timer-drivenplayback_frames. Any ppm difference between the two clocks accumulates: the copy position slowly walks into the T2's read position, first producing partial-buffer reads (crackle that grows with signal level), then full overlap. A stop/start (startedcleared,bridge_pos/playback_framesreset) realigns the two positions, which is why the symptom resets on every stream restart. With a ~70 ms host lead and tens of ppm of drift, onset after 10-30 minutes matches what is observed.Suggested fix
Rate-correct the host copy against T2 feedback (consumed position or the same remote timestamps the capture path already uses), or expose a real DMA position instead of a timer estimate; alternatively track the T2's read position and clamp
bridge_posso the host never overtakes it. Also consider a largerperiod_size(the current 1-frame period makes the ALSA core register a ~21 us CPU latency PM-QoS while the PCM is open, which blocks C2/C3 and heats the machine).Workaround
Pausing playback for >5 s (so PipeWire stops/restarts the PCM) clears the crackle.
Filed here because issues are disabled on
AdityaGarg8/t2bceanddeqrocks/t2bce. Happy to test patches on this machine (Arch,linux-t2from the arch-mact2 repo).