2019-02-12

Pixel 3でマイクの音がどうやら取れないらしい

I’m genuinely sorry for the trouble! Can you go into User Settings > Voice & Video > Low-Latency Hardware Acceleration > Force calls to use OpenSL ES, then restart Discord?

If that doesn’t work, could you send us a support ticket here?: https://t.co/CLfpGOYyn0

— Discord (@discordapp) December 6, 2018

最近,Discordをはじめとする一部のアプリでマイクから音が取れない問題が発生している.

最初,筆者はOpenSL ESの問題かと思ったが,そうではないらしい.

Discordでは,この解決策として,OpenSL ESを有効にすると治るらしいがなぜだろうか?

まずはじめにDiscordは通話にWebRTCを使っている.

How Discord Handles Two and Half Million Concurrent Voice Users using WebRTC

もしWebRTCの組み込みにlibwebrtcを使っているとする前提で話を進める.

Androidにはオーディオ処理システムにAudioFlingerをデフォルトで使っている.AudioFlingerはアプリケーション層(ART)からハードウェア抽象化層(HAL)を経由してALSAに命令を出すため,とても複雑であり,それゆえに遅延が避けられない.これは10ms問題とも呼ばれている.AudioFlingerはAudioRecordやAudioTrackを使うと呼び出される.

これを避けるためにAndroid 2.3から追加されたのが OpenSL ESである.AudioFlingerとの違いは,今までJava経由だったため,VMへのバッファメモリを確保する必要があり,そこがボトルネックになっていた.OpenSL ESはAndroid NDKを使い,直接HALにバッファをキューすることにより遅延を減らすことに成功した.

ただ,OpenSL ESも全ての端末がサポートするわけではなく,ベンダーによってはサポートされなかったり,出力に不具合が生じることが多い.

そう言う事情もあり,Android OからAAudioがサポートされた.AAudioもAndroid NDKを使うが,OpenSL ESの違いはOSレベルでサポートされたことである.これにより,全端末にてAAudioが使うことが可能になった.AAudioはAndroidで長年問題だった遅延問題を全力で解決するために生まれたもので,これにより安定して低遅延再生などを実現できるようになった.

AAudioの特徴として,データの読み書きにストリームを使っており,1つのオーディオデバイスにつき1つのストリームが用意される.排他利用もできる.

OpenSL ESとAAudioであるが,中身は全く別のCのライブラリであるため,これを普通に実装しようとするとなかなか面倒である.

そのため,GoogleはOboeと呼ばれるOpenSL ESとAAudioのラッパーをGitHubで公開し,開発者はOpenSL ESとAAudioのAPIを気にせずに組み込むことが出来るようになった.

github.com

さて,話を戻そう.libwebrtcはAudioFlingerとOpenSL ESとAAudioの全てをサポートしている.しかし,AAudioに関してはSDK Version 26以降でないとサポートされない.そのためDiscordはAudioFlingerとOpenSL ESのみを使っていそうだ.

Pixel 3で音が出ない問題はなんだったのだろうか.

これにはDiscordのAndroidエンジニアがRedditにて回答している.

www.reddit.com

We actually included a fix on beta. If you go to voice settings -> low-latency hardware acceleration and switch OpenSLES to ON, your mic should work. Unfortunately this has some negative side-effects on certain devices so we didn’t default it to true until we work out a more robust whitelist/blacklist.

これによると,OpenSL ESはホワイトリストで管理されているようにみえる.Pixel 3は発売して間もないため,デフォルトだと使わないように設定されていた(明示的に使うことは可能).しかし,AudioFlingerでマイクが反応しないため,OpenSL ESがデフォルトで使うようになったとみられる.

ただ,AudioFlingerでマイクが反応しないのはとても興味深い.これに関してはDiscordの問題というよりもPixel 3のハードウェアの問題な気がしている.

この件に関しては,Discord以外にもWhatsAppでも実際に問題になっている.

Googleはこの問題について早急に解消してほしいと願っている.

参考までに.

www.bgr.in