bluetoothで使われてるaptXコーデックとは何だ

例えばaptXでググるとこのような記事が最初の方に出る

僕はこの記事をどう解釈していいかはわからないが、これが本当ならまるでaptXをつかってなにかやろうと血道をあげていた僕が馬鹿みたいじゃないか。

僕がaptXに期待しているもの

それはもちろん低遅延性である。CD並とか言われてもブラインドテストしたらわかんないだろうけど(少なくとも僕はわからないと思う)、無線の遅延に関しては気づく人結構居ると思うし、それだけ大変な問題だ。なので遅延が小さいと言われているaptXに期待するわけだけど、aptXがSBCと比べて低遅延と言われるのには理由がある。SBCではフレームという単位で音源を転送するのだが、このフレームがbluetoothのパケットにまたがってしまうことがあり、そうなると次のパケットを待つ必要がある。一方でaptXはワードというフレームに比べて小さい単位(まあフレームみたいなものなのには違いないだろうが)を使って転送するためにこのようなことが起こらず、遅延が解消されるという。実際どうなのかわからないが、理屈としてはそのはずだ。

aptXのフレーム(?)

ではフレームの大きさが実際どのくらい違うか見てみよう。と思ったがよい資料が見つからないのでgoogle先生に頼ってfluorideのソースを見ることにした。fluorideとはgoogle先生がbroadcomに作らせてたbluedroidから派生したbluetoothスタックであり、そこかしこにbluedroidのかほりが残っている。あとアンドロイドでも使われているらしい。bluedroid時代を含めると長らくSBCコーデックにしか対応してなかったはずだが、最近aptXのエンコーダーに関してはオープンソース化(?)が行われ、送信側はaptX/aptX HDに対応した。

注目したいのは"bt/stack/a2dp/"ディレクトリの中身だ。ここにある"a2dp_sbc_encoder.cc"やら、"a2dp_vendor_aptx_encoder.cc"はまさに、生データをフレームごとにエンコードしているコードだ。なんともわかりにくいのだが、aptXの場合サンプルレート48kHzだとだいたい1フレーム14msで672個分のサンプルが含まれるようだ。ちなみに44.1kHZだと1フレーム15msで661.5個サンプルになるが、基本は660個サンプルをとって1/8で672個とるという処理で実現してるらしい。(660 * 7 + 672 = 661.5 * 8)なんかやけに大きいがこれは本当なのだろうか。というかこのソースで書かれてるフレームってなんなんだろう。ワードとは違うのか?

aptXだと16bit(=2byte)のPCMが1/4に圧縮されるので、ステレオ(左右でデータ量2倍)だと1frameあたりのデータ量はそのまま672byteになる。なにを隠そうこれはA2DPのパケット(2-DH5)にすっぽり入るサイズらしい。

SBCのフレーム

じゃあSBCのフレームはこれに比べてどうなのよという話だが、コードを見るまでもなくここで計算することができる。案の定というかaptXのフレームより小さい計算になるのでなんだかなぁという感じである。本当のところ遅延がどうなのかはよくわからない…わからないんだ。

追記

ESP32というマイコンの開発環境ではbluedroidが使われているのだが、その中のSBCコーデックの実装には5 frame で 100ms だとか書いてあるし、実装としては30msごとにタイマーでSBCのフレームをいくつか送る処理が起動するみたいだ。とにかくESP32の実装としては30msごとに何フレームか送るようになっているので、14msできっかり1frame(?)おくるaptXのが早そうだ。まあSBCの場合はビットプールでフレーム長が変わってしまい、しかもビットプールは平たく言えば送信側の都合だけで決まらないので、フレームをパケットに合わせることなんてできないのはしかたないのだけど。

実際のところESP32はbluedroidを使っているのでaptXは実装されていない。なのでこのマイコンでどっちがどうのとか言ってもどうしようもないのだが。

この記事が気に入ったらサポートをしてみませんか?