3DSのニンテンドーeショップでの販売が今日ちょうど終了しました。
ハードも発売から10年以上が経過していて今では過去の仲間入り。
そんな3DSをワイヤレススピーカー化してみようと思います。

まず、前提条件として改造済み3DSが必要です。 PCはWindowsでもLinuxでもmacOSでも多分OKです。

〜検証環境〜
PC: MacBook Air (2022, M2), macOS Monterey
3DS: 3DS LL, 11.16.0-48J

何が必要?

最初は自作アプリでPCMあたりで直接やり取りしようと考えていたんですが、低レベルな層にアクセスしてごにょごにょできるのがC++しかないみたいなので諦めました。
そして思いついたのが音楽プレイヤーの「LimePlayer3DS」にインターネットラジオを聴く機能があったことです。
これを使えばストリーミングができると思ったので、今回は配信サーバー Icecast とDJソフト Mixxx を用意します。

「なぜDJソフト?」と言われると、GUIでまともそうなのがこれしかなかったからです。他にも、本来ならFFmpegから直接Icecastに流すことができるんですが、自分の検証環境のmacOSのFFmpegだと音声入力がブチブチ途切れるという問題が発生していました。Mixxxは音声入力の垂れ流しに対応しているので心配無用です。

今回はこういう構成になります。

Icecastをインストール・設定

Icecastは、公式サイトから入手できます。
https://icecast.org/download/
また、OSのパッケージとして配布されている場合もあります。Ubuntuだと icecast2 で提供されていると思います。macOSのHomebrewでは icecast のようです。

インストールできたら icecast.xml という設定ファイルを開きます。macOSはHomebrew経由で入れた場合は /opt/homebrew/etc/icecast.xml、Linuxは /etc/icecast.xml にあると思います。

開いたら、<hostname>localhost</hostname> という行を探します。見つけたら、値を PCのローカルIPアドレス に置き換えます。

さらに下にあるbind-addressのコメントアウト (<!-- --> の囲み)を解除して、値を同じくPCのローカルIPアドレスで置き換えます。 そしてさらにその下にこれを書き加えます。localhostでも繋がるようにします。

<listen-socket>
    <port>8000</port>
    <bind-address>127.0.0.1</bind-address>
</listen-socket>

これで設定ファイルの編集はできました。

Icecastはすでに立ち上がっているので再起動しておきます。

最後に3DS側で読み込ませるファイルを作成します。適当にmainとか何でもいいのでファイル名を決めて、拡張子を .m3u にします。
エディタで以下の内容を入力して保存します。

http://PCのローカルIPアドレス:8000/main

このファイルは3DSのSDカードにコピーしておきます。ルート階層に投げるだけでもいいです。

Mixxxをインストール・設定

次は音楽プレイヤー代わりのDJソフトを入れます。
https://mixxx.org/download/ からインストーラーをダウンロードします。
Ubuntuなどはリポジトリが用意されているみたいなので確認しておくといいかもしれません。

インストールして起動したら、最初に音楽フォルダを選ぶように求められると思います。自分は選びましたがキャンセルしてもいいと思います。

先に進むとこのような画面が現れます。いかにもDJソフトって感じで様々なボタンがあります。ワケワカメですね。

上部のメニューバーから設定を開いて、左側のリストから「ライブ放送」を選択します。それから右側に入力していきます。
タイプを「Icecast 2」、ホストアドレスを「127.0.0.1」、ログイン名を「source」、パスワードを「hackme」、マウントポイントを「main」にします。ポート番号は特に変えていないのであれば8000のままにします。

次に右下のエンコーディング設定を変えます。3DSはDSPの性能が高くないし、32kHzでしか出せません。音質が悪くても気づきません。CPUの性能もあまり高くないし、MP3の160kbpsぐらいで十分だと思います。

ここまでできたら設定を保存して閉じます。

Mixxxからストリーミングを始めるには右上にある「ON AIR」ボタンをクリックします。

正常にスタートすればボタンが緑色に変わります。もう一度押すと止まります。

音楽は、最初にフォルダを選択した場合はすでに一番下のリストから選べると思います。選ばなかった場合は左側のリストから「コンピュータ」を探して開いて、そこから自分の音楽を保存しているフォルダを選べばリストに表示されます。

再生したい曲をダブルクリックするとデッキに読み込まれます。すぐには再生されません。

CUEが点灯していることを確認して再生ボタンを押すと始まります。
頭出しは 、 最後に飛ぶには をクリックします。曲のリピートは波形が表示されているところの右側にあるボタンの をクリックします。

ちなみにデフォルトでモニター音声が流れるため、必要ない場合は設定から無効にします。
設定の「サウンドハードウェア」から、出力のマスターを「—」にします。

LimePlayer3DSを3DSにインストール

LimePlayer3DSは純正のニンテンドー3DSサウンドよりも対応しているコーデックが圧倒的に多いです。MP3、WAV、FLAC、Opus、Vorbisに対応しています。

最新版をGitHubからダウンロードして、何らかの方法でインストールしてください。3DSX形式のバイナリがあらかじめ用意されています。CIAは自分でビルドすることもできますが、Universal-Updaterあたりに転がってたと思います。
https://github.com/oreo639/LimePlayer3DS/releases

インストールできたらさっそく起動してみます。

Icecastが起動している状態で、Mixxxを立ち上げストリーミングを開始した状態にしておきます。

先程SDカードにコピーしたm3uファイルを開いて音声が流れれば成功です。

PCの音声を流す

PCで流れている音声を流すには、外部入力ソースを設定します。 設定の「サウンドハードウェア」の入力リストにある「Auxliary 1」のリストから入力デバイスを選びます。ループバックなどを指定すればOKです。

その後画面にAUX 1が追加されます。

PLAYをクリックするとボタンの色が変わり、入力を取り込んでいる状態になります。もう一度クリックすると停止します。

遅延

Icecastはもともとインターネットラジオの配信用に開発されているのでリアルタイム性は確保されていません。そのため2〜5秒のラグが生じます。

さいごに

3DSをワイヤレススピーカー化することができました。Mixxxも結構楽しいので遊んでみてください。