Nintendo SwitchはBluetoothスピーカーやBluetoothイヤホンへの音声出力に対応していますが、オーディオ機器の種類によっては実感できるレベルの遅延が発生することがあります。この音声遅延問題を無線機能搭載マイコンボード「Raspberry Pi Pico 2 W」を使って解決してみました。

GitHub - wasdwasd0105/PicoW-usb2bt-audio: Transform your Raspberry Pi Pico W into a USB to Bluetooth Audio Adapter.

https://github.com/wasdwasd0105/PicoW-usb2bt-audio

Connecting to the Internet with Raspberry Pi Pico W-series.: Getting online with C/C++ or MicroPython on W-series devices. - connecting-to-the-internet-with-pico-w.pdf

(PDFファイル)https://datasheets.raspberrypi.com/picow/connecting-to-the-internet-with-pico-w.pdf

・目次

◆1:Nintendo Switchの音声遅延の実例と解決方法

◆2:Raspberry Pi Pico 2 W向けのビルド環境を構築

◆3:Pico W USB Audio to Bluetooth Adapterをビルド

◆4:Raspberry Pi Pico 2 Wに書き込み

◆5:Nintendo Switchの音声遅延を解決

◆おまけ:RISC-Vコアでも動作可能

◆1:Nintendo Switchの音声遅延の実例と解決方法

Nintendo SwitchのBluetooth音声出力は、オーディオ機器の種類によって大きな遅延が発生することがあります。GIGAZINE編集部で試した結果、Bluetoothスピーカー「Anker PowerConf」から音声を出力する際に大きな遅延が発生しました。



「Nintendo Switch本体からの音声出力」と「Bluetoothスピーカーからの音声出力」を比較した動画が以下。Bluetoothスピーカーからの音声はボタン操作からワンテンポ遅れて出力されていることが分かります。

Nintendo SwitchからBluetoothスピーカーに音声出力すると遅延が発生する - YouTube

音声遅延の解決方法を探していたところ、「Nintendo SwitchにRaspberry Pi Pico WをUSBオーディオデバイスとして認識させ、Nintendo Switchの音声をRaspberry Pi Pico W経由でBluetoothスピーカーに出力する」というシステムを構築した人を発見。この手法ならBluetooth処理をNintendo SwitchではなくRaspberry Pi Pico Wで実行できるため、音声の遅延を抑えられるようです。

Raspberry Pi Pico W USB Audio to Bluetooth Adapter: Testing on Switch and Windows - YouTube

上記の動画は、「Pico W USB Audio to Bluetooth Adapter」というソフトウェアをRaspberry Pi Pico Wに書き込むことで実現しています。



というわけで、Pico W USB Audio to Bluetooth Adapterを実際にビルドしてRaspberry Pi Pico 2 Wに書き込んで使ってみることにしました。Raspberry Pi Pico 2 Wがどんなデバイスなのかは以下の記事で確認可能。なお、記事作成時点ではRaspberry Pi Pico 2 Wは技適を取得していないので、「技適未取得機器を用いた実験等の特例制度」の届出を行ったうえで使っています。

Wi-FiとBluetoothを使えるマイコン「Raspberry Pi Pico 2 W」が届いたので速攻フォトレビュー - GIGAZINE



◆2:Raspberry Pi Pico 2 W向けのビルド環境を構築

Raspberry Pi Pico 2 W向けのビルド環境はWindowsでもLinuxでも構築可能。今回はUbuntuマシン上にビルド環境を構築します。



最初に、以下のコマンドを実行してCMakeなどの必要なパッケージをインストールします。

sudo apt install cmake gcc-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib

続いて、GitHubで管理されている「Raspberry Pi Pico SDK」のリポジトリをクローンします。今回はホームディレクトリの直下にクローンしました。

git clone https://github.com/raspberrypi/pico-sdk.git

リポジトリのクローンが完了したら、環境変数を設定します。任意のエディタで「.bashrc」を開いて以下の行を追加すればOK。

export PICO_SDK_PATH=/pico-sdk

「ホームディレクトリ/pico-sdk」に移動してサブモジュールをアップデートすれば、環境構築は完了です。

cd pico-sdk

git submodule update --init

続いて、正しく環境構築できているか確認するためにRaspberry Pi公式のサンプルソフトウェアをビルドしてみます。まず、公式サンプルのリポジトリをホームディレクトリ直下にクローンします。

cd

git clone https://github.com/raspberrypi/pico-examples.git

以下のコマンドを実行してRaspberry Pi Pico Wシリーズ向けのサンプルをビルドします。○○○○にはWi-FiルーターのSSID、△△△△にはWi-Fiのパスワードを入力すればOK。

cd pico-examples

mkdir build-2w

cd build-2w

cmake -DPICO_BOARD=pico2_w -DWIFI_SSID=○○○○ -DWIFI_PASSWORD=△△△△ ..

cd pico_w

make

エラーなくビルドが完了すれば、環境構築は成功です。

◆3:Pico W USB Audio to Bluetooth Adapterをビルド

Pico W USB Audio to Bluetooth Adapterのリポジトリと、ビルドに必要な追加ライブラリを含むリポジトリをホームディレクトリ直下にクローンします。

cd

git clone https://github.com/raspberrypi/pico-extras.git

git clone https://github.com/wasdwasd0105/PicoW-usb2bt-audio.git

「PicoW-usb2bt-audio」の内部に移動。

cd PicoW-usb2bt-audio

「PicoW-usb2bt-audio」ディレクトリの中にビルドに必要な「CMakeLists.txt」が保存されているのですが、記事作成時点では「SDKの保存場所を指定する部分が作者の環境の値で決め打ちされている」という問題があるので、任意のエディタで「CMakeLists.txt」を開いて自分の環境の値で上書きします。

「set(PICO_SDK_PATH "/Users/wasdwasd0105/pico/pico-sdk")」と記された部分が問題の箇所。



「set(PICO_SDK_PATH "ホームディレクトリ/pico/pico-sdk")」に書き換えて上書き保存します。



さらに、「『ホームディレクトリ/pico/pico-sdk/lib/btstack/src/hci.c』の6442行目と6451行目と1万769行目の『le_advertisements_state』という部分を『le_advertisements_todo』に書き換えないとビルドに失敗する」という問題もあるので、任意のエディタで修正します。

6442行目の「le_advertisements_state」となっている部分が書き換え対象です。



「le_advertisements_todo」に書き換えて上書き保存すればOK。同様にして6451行目と1万769行目の「le_advertisements_state」も「le_advertisements_todo」に置換します。



コードの修正が完了したら、作業用ディレクトリを作成してビルドします。今回は「build-2w」という名称のディレクトリ内でビルドしました。

mkdir build-2w

cd build-2w

cmake -DPICO_EXTRAS_PATH=ホームディレクトリ/pico-extras -DPICO_BOARD=pico2_w ..

make

「ホームディレクトリ/PicoW-usb2bt-audio/build-2w」の中に「PicoW_USB_BT_Audio.uf2」というファイルが出力されればビルドは成功です。



◆4:Raspberry Pi Pico 2 Wに書き込み

出力したPicoW_USB_BT_Audio.uf2をRaspberry Pi Pico 2 Wに書き込みます。まず、Raspberry Pi Pico 2 WとUSBケーブルを用意。



Raspberry Pi Pico 2 WにUSBケーブルを挿入します。



次に、Raspberry Pi Pico 2 WのBOOTSELボタンを押します。



BOOTSELボタンを押したままRaspberry Pi Pico 2 WとPCをUSBケーブルで接続します。



BOOTSELボタンから指を離すと、Raspberry Pi Pico 2 Wが「RP2350」という名前のストレージとしてマウントされます。



ファイラーで「ホームディレクトリ/PicoW-usb2bt-audio/build-2w」を開いて、「PicoW_USB_BT_Audio.uf2」を「RP2350」の中にドラッグ&ドロップしてコピーすれば、書き込みは完了です。



書き込みが完了したらRaspberry Pi Pico 2 WをPCから切断しておきます。



◆5:Nintendo Switchの音声遅延を解決

Pico W USB Audio to Bluetooth Adapterを書き込んだRaspberry Pi Pico 2 Wを使ってNintendo Switchの音声遅延問題を解決できるか確かめてみます。まず、「Nintendo Switch」「Bluetoothスピーカー(Anker PowerConf)」「Raspberry Pi Pico 2 W」「Nintendo SwitchとRaspberry Pi Pico 2 Wを接続するためのUSBケーブル」を用意します。「片端がUSB Micro-Bで、片端がUSB Type-Cのケーブル」があれば1本で済みますが、今回は持っていなかったので「片端がUSB Micro-Bで、片端がUSB Type-Aのケーブル」と「USB Type-AとUSB Type-Cの変換ケーブル」を用意しました。



Nintendo SwitchとRaspberry Pi Pico 2 Wをケーブルで接続。



すると、USBオーディオデバイスとして認識されました。



続いて、Bluetoothスピーカーを起動します。Raspberry Pi Pico 2 Wは初期状態でペアリング待ち状態になっているので、Bluetoothスピーカーをペアリングモードにすればペアリングが完了します。



Nintendo SwitchにRaspberry Pi Pico 2 Wを接続してBluetoothスピーカーから音を鳴らすまでの手順をまとめた動画が以下。

Nintendo Switchの音声をRaspberry Pi Pico 2 W経由でBluetooth出力する - YouTube

「Bluetoothスピーカーからの音声出力」と「Raspberry Pi Pico 2 W経由でBluetoothスピーカーから音声出力」の遅延を比較してみました。Pico W USB Audio to Bluetooth Adapterによって遅延が低減されていることが分かります。

Nintendo SwitchのBluetoothオーディオ遅延問題を解決してみた - YouTube

Raspberry Pi Pico 2 WはNintendo Switchドックにも接続可能なので、TVモードでも遅延を低減したBluetooth音声出力を楽しめます。



以下の動画では、Raspberry Pi Pico 2 W経由のBluetooth音声出力をTVモードで実行する様子を確認できます。

Nintendo SwitchのBluetoothオーディオ遅延問題を解決してみた【TVモード】 - YouTube

◆おまけ:RISC-Vコアでも動作可能

Raspberry Pi Pico 2 WにはRaspberry Pi独自開発のマイコン「RP2350」が搭載されており、RP2350にはRISC-Vコアが内蔵されています。今回作ったUSBオーディオデバイスも、CMakeのオプションを以下のように変更してビルドすればRISC-Vコアで動作させられます。

cmake -DPICO_EXTRAS_PATH=ホームディレクトリ/pico-extras -DPICO_TOOLCHAIN_PATH=ホームディレクトリ/corev-openhw-gcc-ubuntu2204-20240530 -DPICO_BOARD=pico2_w -DPICO_PLATFORM=rp2350-riscv ..

ただし、RISC-Vコア向けのビルドには専用のコンパイラなども準備する必要があります。RISC-Vコア向けのビルド方法の詳細は以下の記事を確認してください。

「Raspberry Pi Pico 2」のRISC-VコアでLチカを実行&デバッグしてみた - GIGAZINE