alsaloop 和 bluez-alsa 不穩定
我有一個樹莓派零 w,它通過 i2s 輸入聲音(使用通用 dmic 驅動程序),並使用 bluez5 連接到藍牙揚聲器。
我設置了 bluez-alsa,以便連接的藍牙設備可以作為 alsa PCM 使用。這有效,我可以使用 aplay 播放文件。
我還可以使用 arecord 記錄輸入。
我現在的要求是:
- 記錄連續的 i2s 輸入並將其通過管道傳輸到藍牙 alsa 輸出。
- 延遲應該盡可能低
- 音質應該不錯。
i2s 輸入的採樣率為 96khz 和 32 位,而大多數藍牙揚聲器最多可以處理 48khz 和 16 位的採樣率。
我嘗試了 alsaloop 和組合的 arecord/aplay 方法。
對於 alsaloop,我使用了這個命令:
alsaloop -C i2s-input -P "bluealsa:DEV=XX" -c 2 -r96000 -fS32_LE -t 20000
在使用時間/緩衝區/週期參數時,我可以將延遲設置為非常低的值,但它非常不穩定。一段時間後,我得到緩衝區溢出和欠載,聲音開始變得奇怪,或者完全失敗。
對於 arecord 和 aplay 我嘗試了類似的東西
arecord -D i2s-device -c2 -r96000 -fS32_LE -traw | aplay -D "bluealsa:DEV=XX" -c2 -r96000 -fS32_LE -traw
效果不錯,但是延遲很高,並且 CPU 負載比 alsaloop 高得多。但我也經常得到 xruns,聲音會破裂。
你有什麼建議我可以改進這個設置嗎?緩衝/週期值應該如何優化設置?
經過一些測試,我找到了解決方案:sox
我沒有使用 alsaloop 或 arecord/aplay,而是使用 sox 建立了一個簡單的管道:
mkfifo /tmp/pipe rec -b 32 -r 96000 --endian little -t raw -e signed-integer /tmp/pipe & sox -b 32 -r 96000 --endian little -t raw -e signed-integer /tmp/pipe -t raw -e signed-integer -p rate 48000 | AUDIODEV="bluealsa:DEV=XX:XX:XX:XX:XX:XX" play -b 32 -r 96000 --endian little -t raw -e signed-integer -p &
這將創建一個命名管道
/tmp/pipe
並rec
用輸入填充它sox
重新採樣音頻數據並play
播放它