Reduce mixer and Bluetooth buffers from 500 ms to 200 ms
SBC medium, not the larger buffer, removed the headphone relay dropouts, so cut dmix, bluealsa-aplay and alsaloop buffers to 200 ms and the Shairport backend buffer to 0.15 s. Verified by listening (iPhone -> headphones, with AirPlay mixed in) with no RTP loss or underruns. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -21,7 +21,7 @@ Mac/iPhone의 AirPlay 2 ── Shairport Sync ─┐
|
||||
- Bluetooth: Debian의 BlueALSA 패키지. 기준 보드 버전 **4.3.1**.
|
||||
- 수신과 송신은 A2DP 음악 프로필을 사용합니다. 기준 보드에서는 SBC로 연결됐습니다.
|
||||
- SBC 송신 품질은 medium입니다. 기준 보드에서 high로 동시 수신·송신 시 끊겨
|
||||
전송량을 줄였습니다. 송신 버퍼는 500 ms이며, 이 조합에서 끊김 없는 청취를 확인했습니다.
|
||||
전송량을 줄였습니다. 믹서·입력·송신 버퍼는 각 200 ms이며, 이 조합에서 끊김 없는 청취를 확인했습니다.
|
||||
- DAC 출력은 44.1 kHz / 스테레오 / 16비트, 블루투스용 가상 믹서는 48 kHz입니다.
|
||||
- 각 입력을 3 dB 낮춥니다. 여러 입력의 큰 소리가 겹쳐 찢어지면 입력 볼륨을 낮추세요. 지연 없는 실시간 녹음/악기 모니터링용 구성은 아닙니다.
|
||||
- 각 송신 기기의 볼륨으로 믹스 비율을 바꿉니다.
|
||||
|
||||
+4
-1
@@ -112,7 +112,10 @@ sudo journalctl -u radxa-mixer-web -n 40 --no-pager
|
||||
기준 보드에서는 버퍼만 500 ms로 늘려서는 끊김이 남았고, 송신 SBC 품질을
|
||||
high에서 medium으로 낮춘 뒤(`bluealsa --sbc-quality=medium`) 해결됐습니다.
|
||||
같은 컨트롤러로 수신과 송신을 동시에 하므로 송신 전송량이 수신 손실에 영향을 줍니다.
|
||||
현재 송신 버퍼는 500 ms이며 그만큼 지연이 추가됩니다.
|
||||
SBC medium 적용 후에는 500 ms 버퍼가 필요 없어 믹서(dmix), Bluetooth 입력
|
||||
(`bluealsa-aplay`), 헤드폰 송신(`alsaloop`) 버퍼를 각각 200 ms로 줄였습니다.
|
||||
버퍼를 다시 늘리면 지연이 그만큼 늘어나므로, 끊김이 생기면 먼저 로그로
|
||||
수신 손실인지 버퍼 오류인지 구분하세요.
|
||||
|
||||
청취 확인 시에는 `bluealsa-aplay -l`의 PLAYBACK 목록에 헤드폰이 있는지 먼저 봅니다.
|
||||
없으면 헤드폰이 휴대폰에 직접 연결돼 Radxa를 거치지 않은 소리일 수 있습니다.
|
||||
|
||||
+11
-1
@@ -55,13 +55,23 @@ SBC 품질 변경으로 컨트롤러 오류가 해결됐다고 보지는 않습
|
||||
로그에서 `Missing RTP packets`, underrun/overrun, HCI 시간 초과는 없었습니다.
|
||||
따라서 SBC medium + 500 ms 버퍼 조합으로 끊김이 해소된 것으로 판단합니다.
|
||||
장시간 재생 안정성은 아직 확인하지 않았습니다.
|
||||
|
||||
### 지연 축소
|
||||
|
||||
500 ms 버퍼는 끊김 해결에 기여하지 않았으므로 지연을 줄였습니다.
|
||||
1단계로 헤드폰 송신(`alsaloop -t`)을 200 ms로 줄여 사용자가 끊김 없음을 확인했습니다.
|
||||
2단계로 dmix 버퍼 500 → 200 ms, `bluealsa-aplay --pcm-buffer-time` 500 → 200 ms,
|
||||
Shairport 출력 버퍼 0.5 → 0.15 s로 줄였습니다. iPhone Bluetooth → 보스 청취에서
|
||||
사용자가 끊김 없음을 확인했고, `Missing RTP packets`·underrun은 0건이었습니다.
|
||||
같은 구간의 AirPlay 동시 재생 통계에서도 Missing/Late 프레임은 0이었습니다.
|
||||
경로 전체 지연은 측정하지 않았으며, 버퍼 합계 기준 약 0.6 s 줄었습니다.
|
||||
이미 영구 등록된 휴대폰 등록은 재부팅 후 유지됐습니다.
|
||||
|
||||
## 실제 청취로 확인한 범위
|
||||
|
||||
사용자가 AirPlay 재생, AirPlay + 아이폰 Bluetooth 입력의 DAC 믹스 재생을
|
||||
정상 청취했다고 확인했습니다. iPhone Bluetooth 입력 → 보스 헤드폰 출력도
|
||||
SBC medium / 500 ms 버퍼 설정에서 끊김 없이 청취했다고 확인했습니다.
|
||||
SBC medium / 200 ms 버퍼 설정에서 끊김 없이 청취했다고 확인했습니다.
|
||||
|
||||
## 아직 검증하지 않은 범위
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
사용자가 정상 청취를 확인했습니다. Bose 헤드폰은 페어링/신뢰 등록 및
|
||||
A2DP SBC 48 kHz 출력 연결과 가상 믹서 전송까지 확인했습니다.
|
||||
사용자는 이후 iPhone → 보스 경로의 소리 끊김을 보고했습니다. 수신 패킷 손실과
|
||||
버퍼 오류를 확인했습니다. 500 ms 버퍼와 SBC medium 송신 설정을 적용하고
|
||||
버퍼 오류를 확인했습니다. SBC medium 송신 설정과 200 ms 버퍼(지연 축소)를 적용하고
|
||||
보스를 영구 등록한 뒤, iPhone → Radxa → 보스 경로의 정상 청취를 확인했습니다.
|
||||
|
||||
기존 설정 백업은 보드의 `/root/audio-mixer-backup-20261012-162401/`와
|
||||
|
||||
@@ -80,7 +80,7 @@ pcm.radxa_dmix {{
|
||||
channels 2
|
||||
period_time 0
|
||||
period_size {rate // 100}
|
||||
buffer_size {rate // 2}
|
||||
buffer_size {rate // 5}
|
||||
}}
|
||||
bindings {{ 0 0 1 1 }}
|
||||
}}
|
||||
@@ -105,7 +105,7 @@ def templates(c):
|
||||
name = {json.dumps(c['name'], ensure_ascii=False)};
|
||||
service_type = "airplay2";
|
||||
output_backend = "alsa";
|
||||
audio_backend_buffer_desired_length_in_seconds = 0.5;
|
||||
audio_backend_buffer_desired_length_in_seconds = 0.15;
|
||||
}};
|
||||
alsa = {{
|
||||
output_device = "radxa_mix";
|
||||
@@ -126,7 +126,7 @@ Group=audio
|
||||
PrivateUsers=false
|
||||
RemoveIPC=false
|
||||
ExecStart=
|
||||
ExecStart=/usr/bin/bluealsa-aplay -S --pcm=radxa_mix --volume=software --pcm-period-time=10000 --pcm-buffer-time=500000
|
||||
ExecStart=/usr/bin/bluealsa-aplay -S --pcm=radxa_mix --volume=software --pcm-period-time=10000 --pcm-buffer-time=200000
|
||||
''',
|
||||
'/etc/modules-load.d/radxa-audio-loopback.conf': 'snd-aloop\n',
|
||||
'/etc/modprobe.d/radxa-audio-loopback.conf': 'options snd-aloop pcm_substreams=1\n',
|
||||
@@ -143,7 +143,7 @@ StartLimitIntervalSec=0
|
||||
User=shairport-sync
|
||||
Group=audio
|
||||
ExecStartPre=-/usr/bin/bluetoothctl --timeout 8 connect {addr} a2dp-sink
|
||||
ExecStart=/usr/bin/alsaloop -C hw:Loopback,1,0 -P bluealsa:DEV={addr},PROFILE=a2dp -c 2 -r 48000 -f S16_LE -t 500000 -S 4 -A 2
|
||||
ExecStart=/usr/bin/alsaloop -C hw:Loopback,1,0 -P bluealsa:DEV={addr},PROFILE=a2dp -c 2 -r 48000 -f S16_LE -t 200000 -S 4 -A 2
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
TimeoutStartSec=30
|
||||
|
||||
@@ -52,7 +52,7 @@ class ManagerTests(unittest.TestCase):
|
||||
self.assertIn('Loopback', f['/etc/asound.conf'])
|
||||
self.assertIn('rate 48000',f['/etc/asound.conf'])
|
||||
self.assertIn('--sbc-quality=medium',f['/etc/systemd/system/bluealsa.service.d/10-radxa-sink.conf'])
|
||||
self.assertIn('-t 500000',unit)
|
||||
self.assertIn('-t 200000',unit)
|
||||
|
||||
def test_name_quotes_are_escaped(self):
|
||||
f=m.templates(self.config(name='Desk "Two"'))
|
||||
|
||||
Reference in New Issue
Block a user