Commit ca60a90
windows: STOP_AUDIO is what breaks stereo — never leave mic mode mid-session
Root cause, proven live over the l2cap-tx pipe: sending `STOP_AUDIO` (leaving
hi-res mic mode) is what leaves the AirPods rendering audio on ONE SIDE only.
It self-heals after minutes; re-sending `START_AUDIO` restores stereo instantly,
which proves mic mode itself is fine and only the EXIT is broken.
So we never leave mic mode during a session. Clearing `mic_on` is enough: the
receive loop stops decoding the 0x58 uplink and the virtual mic goes silent,
which is what "off" means to the user. The buds keep the uplink armed until the
session ends (a disconnect resets them anyway).
This also retires `a2dp::reset()`. It never fixed a mono A2DP negotiation —
btvs captures show every AVDTP SET_CONFIGURATION and all 2891 SBC frames are
0x03 JointStereo, always, with no RECONFIGURE and no SCO/HFP anywhere. It only
"worked" because it rebuilt the audio link right after the bad exit, at the cost
of killing the AAP channel and bricking the driver into Code 38. The comment
atop a2dp.rs claiming playback "degrades to mono/right" is wrong and predates
the virtual-mic driver. Dropping it also removes a ~2.65 s dropout per release.
Why only we hit this: Linux sends STOP_AUDIO too, but PulseAudio switches the
card into HFP for mic use and back to A2DP after, and that profile switch
rebuilds the stream and wipes the bad state. macOS never takes this path — its
mic rides HFP/eSCO with a custom codec (AT+BCS=128) and is call-scoped. Our
virtual mic deliberately never leaves A2DP, so we are the first to get stuck.
Also fixes the zombie AAP channel. The channel can sit OPEN but silent for as
long as Windows still sees the AirPods (observed: 56 minutes) — `status_fails`
resets every pass, so the loop never releases or rebuilds, and the in-place
re-arm was gated behind `mic_on`. Attached to the PC, but not to the daemon.
Now: after 30 s of silence with the mic off we set `link_stale` and nudge in
place by re-asserting the noise mode we already believe is active (a write the
buds accept, nothing audible, and a live link answers with a 0x0D that clears
the flag). We deliberately do NOT drop + reopen the driver — that is what
"Repair connection" does, and repeated churn is what bricks it into Code 38.
`link_stale` rides the Snapshot (serde/JSON default, so older snapshots load).
The app now offers Repair while disconnected OR stale, and paints the status dot
orange in that state. Before, `connected` stayed true forever, so the Repair
button was hidden exactly when it was needed and the only way to surface it was
to turn Bluetooth off.
Mic card text now describes what it actually does, and the "Microphone released"
notification is gone: nothing is released any more, so announcing it was both
wrong and noise.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UAAKZFpHoNY9pskrdvLKaP1 parent 393c651 commit ca60a90
8 files changed
Lines changed: 125 additions & 36 deletions
File tree
- windows
- daemon/src
- ipc/src
- winui/LibrePods.WinUI
- Controls
- Ipc
- Strings
- en-US
- es-ES
- fr-FR
- pt-PT
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
| 9 | + | |
| 10 | + | |
9 | 11 | | |
10 | 12 | | |
11 | 13 | | |
| |||
450 | 452 | | |
451 | 453 | | |
452 | 454 | | |
453 | | - | |
| 455 | + | |
454 | 456 | | |
455 | 457 | | |
456 | 458 | | |
457 | 459 | | |
458 | 460 | | |
459 | 461 | | |
460 | | - | |
| 462 | + | |
461 | 463 | | |
462 | | - | |
463 | | - | |
464 | | - | |
465 | | - | |
466 | | - | |
467 | | - | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
| 478 | + | |
| 479 | + | |
| 480 | + | |
| 481 | + | |
| 482 | + | |
| 483 | + | |
| 484 | + | |
| 485 | + | |
| 486 | + | |
| 487 | + | |
| 488 | + | |
| 489 | + | |
468 | 490 | | |
469 | 491 | | |
470 | 492 | | |
| |||
895 | 917 | | |
896 | 918 | | |
897 | 919 | | |
898 | | - | |
| 920 | + | |
| 921 | + | |
| 922 | + | |
| 923 | + | |
| 924 | + | |
899 | 925 | | |
900 | 926 | | |
901 | 927 | | |
| |||
951 | 977 | | |
952 | 978 | | |
953 | 979 | | |
| 980 | + | |
| 981 | + | |
| 982 | + | |
| 983 | + | |
| 984 | + | |
| 985 | + | |
| 986 | + | |
| 987 | + | |
| 988 | + | |
| 989 | + | |
954 | 990 | | |
955 | 991 | | |
956 | 992 | | |
| |||
996 | 1032 | | |
997 | 1033 | | |
998 | 1034 | | |
| 1035 | + | |
| 1036 | + | |
| 1037 | + | |
| 1038 | + | |
| 1039 | + | |
| 1040 | + | |
999 | 1041 | | |
1000 | 1042 | | |
1001 | 1043 | | |
| |||
1076 | 1118 | | |
1077 | 1119 | | |
1078 | 1120 | | |
1079 | | - | |
| 1121 | + | |
1080 | 1122 | | |
1081 | 1123 | | |
1082 | 1124 | | |
| |||
1333 | 1375 | | |
1334 | 1376 | | |
1335 | 1377 | | |
| 1378 | + | |
| 1379 | + | |
| 1380 | + | |
| 1381 | + | |
| 1382 | + | |
| 1383 | + | |
| 1384 | + | |
| 1385 | + | |
| 1386 | + | |
| 1387 | + | |
| 1388 | + | |
| 1389 | + | |
| 1390 | + | |
| 1391 | + | |
| 1392 | + | |
| 1393 | + | |
| 1394 | + | |
| 1395 | + | |
| 1396 | + | |
| 1397 | + | |
| 1398 | + | |
| 1399 | + | |
| 1400 | + | |
| 1401 | + | |
| 1402 | + | |
| 1403 | + | |
| 1404 | + | |
| 1405 | + | |
1336 | 1406 | | |
1337 | 1407 | | |
1338 | 1408 | | |
| |||
1389 | 1459 | | |
1390 | 1460 | | |
1391 | 1461 | | |
1392 | | - | |
| 1462 | + | |
1393 | 1463 | | |
1394 | 1464 | | |
1395 | 1465 | | |
1396 | 1466 | | |
1397 | 1467 | | |
1398 | 1468 | | |
1399 | 1469 | | |
1400 | | - | |
1401 | | - | |
1402 | | - | |
1403 | | - | |
1404 | | - | |
1405 | | - | |
| 1470 | + | |
| 1471 | + | |
| 1472 | + | |
1406 | 1473 | | |
1407 | 1474 | | |
1408 | 1475 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
43 | 43 | | |
44 | 44 | | |
45 | 45 | | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
46 | 54 | | |
47 | 55 | | |
48 | 56 | | |
| |||
Lines changed: 11 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
42 | 42 | | |
43 | 43 | | |
44 | 44 | | |
| 45 | + | |
| 46 | + | |
45 | 47 | | |
46 | | - | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
47 | 51 | | |
48 | | - | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
49 | 57 | | |
50 | 58 | | |
51 | | - | |
| 59 | + | |
52 | 60 | | |
53 | 61 | | |
54 | 62 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
29 | 35 | | |
30 | 36 | | |
31 | 37 | | |
| |||
Lines changed: 4 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
115 | 115 | | |
116 | 116 | | |
117 | 117 | | |
118 | | - | |
119 | | - | |
| 118 | + | |
| 119 | + | |
120 | 120 | | |
121 | 121 | | |
122 | 122 | | |
| |||
202 | 202 | | |
203 | 203 | | |
204 | 204 | | |
205 | | - | |
206 | | - | |
| 205 | + | |
| 206 | + | |
207 | 207 | | |
208 | 208 | | |
209 | 209 | | |
| |||
Lines changed: 4 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
106 | 106 | | |
107 | 107 | | |
108 | 108 | | |
109 | | - | |
110 | | - | |
| 109 | + | |
| 110 | + | |
111 | 111 | | |
112 | 112 | | |
113 | 113 | | |
| |||
193 | 193 | | |
194 | 194 | | |
195 | 195 | | |
196 | | - | |
197 | | - | |
| 196 | + | |
| 197 | + | |
198 | 198 | | |
199 | 199 | | |
200 | 200 | | |
| |||
Lines changed: 4 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
106 | 106 | | |
107 | 107 | | |
108 | 108 | | |
109 | | - | |
110 | | - | |
| 109 | + | |
| 110 | + | |
111 | 111 | | |
112 | 112 | | |
113 | 113 | | |
| |||
193 | 193 | | |
194 | 194 | | |
195 | 195 | | |
196 | | - | |
197 | | - | |
| 196 | + | |
| 197 | + | |
198 | 198 | | |
199 | 199 | | |
200 | 200 | | |
| |||
Lines changed: 4 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
106 | 106 | | |
107 | 107 | | |
108 | 108 | | |
109 | | - | |
110 | | - | |
| 109 | + | |
| 110 | + | |
111 | 111 | | |
112 | 112 | | |
113 | 113 | | |
| |||
193 | 193 | | |
194 | 194 | | |
195 | 195 | | |
196 | | - | |
197 | | - | |
| 196 | + | |
| 197 | + | |
198 | 198 | | |
199 | 199 | | |
200 | 200 | | |
| |||
0 commit comments