Bluetoothイヤホンに向けてエンコードするビットレートはどんなもんなのか

BluetoothイヤホンとAndroid本体がペアリングしたときの様子を見てみよう

Google Pixel 3 と Anker SoundBuds Slim

まずは Google Pixel 3 の A2DP について ハードウェアオフロードを disable にしてソフトウェアでエンコードする場合。 Google Pixel 3 と Anker SoundBuds Slim をペアリングしたとき吐き出されるデバッグログを見てみよう(端っこの方は切ってます)

D/A2dpStateMachine: processMsg: Connected
D/A2dpStateMachine: Connected process message(E8:07:BF:69:58:E2): STACK_EVENT
D/A2dpStateMachine: Connected: stack event: A2dpStackEvent {type:EVENT_TYPE_CODEC_CONFIG_CHANGED,
D/A2dpStateMachine: A2DP Codec Config: {codecName:SBC,mCodecType:0,mCodecPriority:1000000,mSample
D/A2dpStateMachine: A2DP Codec Local Capability: {codecName:SBC,mCodecType:0,mCodecPriority:1001,
D/A2dpStateMachine: A2DP Codec Local Capability: {codecName:LDAC,mCodecType:4,mCodecPriority:5001
D/A2dpStateMachine: A2DP Codec Local Capability: {codecName:aptX HD,mCodecType:3,mCodecPriority:4
D/A2dpStateMachine: A2DP Codec Local Capability: {codecName:aptX,mCodecType:2,mCodecPriority:3001
D/A2dpStateMachine: A2DP Codec Local Capability: {codecName:AAC,mCodecType:1,mCodecPriority:2001,
D/A2dpStateMachine: A2DP Codec Selectable Capability: {codecName:SBC,mCodecType:0,mCodecPriority:
D/A2dpStateMachine: A2DP Codec Selectable Capability: {codecName:AAC,mCodecType:1,mCodecPriority:
D/A2dpService: broadcastCodecConfig(E8:07:BF:69:58:E2): {mCodecConfig:{codecName:SBC,mCodecType:0

おおっ、本体で使えるコーデックを提示して、選択可能なコーデックをリストアップして、その中から選ぶんだね。とりあえず SBC が選ばれてるぞ。 その後出てくるのを見てると

D/a2dp_sbc_encoder: a2dp_sbc_encoder_update: sample_rate=44100 bits_per_sample=16 channel_count=2
D/a2dp_sbc_encoder: a2dp_sbc_feeding_reset: PCM bytes per tick 3528
D/a2dp_sbc_encoder: a2dp_sbc_encoder_update: MTU=883, peer_mtu=883 min_bitpool=8 max_bitpool=53
D/a2dp_sbc_encoder: a2dp_sbc_encoder_update: ChannelMode=3, NumOfSubBands=8, NumOfBlocks=16, AllocationMethod=0, BitRate=328, SamplingFreq=44100 BitPool=0
D/a2dp_sbc_encoder: a2dp_sbc_encoder_update: bitpool candidate: 53 (328 kbps)
D/a2dp_sbc_encoder: a2dp_sbc_encoder_update: final bit rate 328, final bit pool 53

SBCでビットレート328kbpsでやりましょうとなっているね。

開発者メニューから AAC を選んでみるとどうなるかな。

D/a2dp_codec: setCodecUserConfig: Configuring: codec: AAC priority: 0 sample_rate: 44100 bits_per_sample: 16 channel_mode: STEREO
D/a2dp_aac_encoder: a2dp_aac_encoder_update: sample_rate=44100 bits_per_sample=16 channel_count=2
D/a2dp_aac_encoder: a2dp_aac_feeding_reset: PCM bytes per tick 3528
D/a2dp_aac_encoder: a2dp_aac_encoder_update: MTU=1008, peer_mtu=1008
D/a2dp_aac_encoder: a2dp_aac_encoder_update: sample_rate: 44100 channel_mode: 4
D/a2dp_aac_encoder: a2dp_aac_encoder_update: MTU = 1008 Sampling Frequency = 44100 Bit Rate = 320000
D/a2dp_aac_encoder: a2dp_aac_encoder_update: AAC frame_length = 1024 input_channels_n = 2 max_encoded_buffer_bytes = 1536

AAC の場合は 320kbps でやりますよ、となっているね。おもしろい。

次に Google Pixel 3 の A2DP について ハードウェアオフロードを enable にしてエンコードをハードウェアにお任せする場合。

D/A2dpStateMachine: A2DP Codec Local Capability: {codecName:LDAC,mCodecType:4,mCodecPriority:5001,
D/A2dpStateMachine: A2DP Codec Local Capability: {codecName:aptX HD,mCodecType:3,mCodecPriority:40
D/A2dpStateMachine: A2DP Codec Local Capability: {codecName:aptX,mCodecType:2,mCodecPriority:3001,
D/A2dpStateMachine: A2DP Codec Local Capability: {codecName:AAC,mCodecType:1,mCodecPriority:2001,m
D/A2dpStateMachine: A2DP Codec Local Capability: {codecName:SBC,mCodecType:0,mCodecPriority:1001,m
D/A2dpStateMachine: A2DP Codec Selectable Capability: {codecName:AAC,mCodecType:1,mCodecPriority:2
D/A2dpStateMachine: A2DP Codec Selectable Capability: {codecName:SBC,mCodecType:0,mCodecPriority:1

コーデックの選択肢を提示してイヤホン側で使えるのをリストアップするところまでは同じだね。

ここまでは何も変わらないように思える。それでは音楽を再生してみると。

D/a2dp_offload: audio_extn_a2dp_start_playback: start
D/a2dp_offload: audio_extn_a2dp_start_playback: calling Bluetooth module stream start
D/a2dp_offload: configure_a2dp_encoder_format: start
D/a2dp_offload: configure_a2dp_encoder_format: Received AAC encoder supported Bluetooth device
D/a2dp_offload: a2dp_set_bit_format: set AFE input bit format = 16
D/a2dp_offload: audio_extn_a2dp_start_playback: Start playback successful to Bluetooth IPC library
D/a2dp_offload: audio_extn_a2dp_start_playback: start A2DP playback total active sessions :1

曲を流し始めたらエンコードから先の処理は別のハードウェアにオフロードしますね、ってことだろうね。 ところで AFE とは何ぞ?Analog Front End だとしたら アンプ、フィルタ、ADコンバータ を含むようなものだろうけど、今回扱うデータはINもOUTもデジタルじゃないだろうか…

P20lite と Anker SoundBuds Slim

P20lite と Anker SoundBuds Slim を繋いだ場合の処理内容を見てみようね。

画面イメージはこの辺→Bluetoothイヤホン 【改善版】Anker SoundBuds Slim + P20lite (2)

Google公式の AndroidHuawei カスタマイズの EMUI なので比べると少しログの出方が違う&ものすごい量のデバッグログが出るのですぐ流れてしまう…

D/a2dp_sbc_encoder: a2dp_sbc_encoder_update: sample_rate=44100 bits_per_sample=16 channel_count=2
D/a2dp_sbc_encoder: a2dp_sbc_feeding_reset: PCM bytes per tick 3528
D/a2dp_sbc_encoder: a2dp_sbc_encoder_update: MTU=1008, peer_mtu=1008 min_bitpool=8 max_bitpool=53
D/a2dp_sbc_encoder: a2dp_sbc_encoder_update: ChannelMode=3, NumOfSubBands=8, NumOfBlocks=16, AllocationMethod=0, BitRate=229, SamplingFreq=44100 BitPool=0
D/a2dp_sbc_encoder: a2dp_sbc_encoder_update: bitpool candidate: 35 (229 kbps)
D/a2dp_sbc_encoder: a2dp_sbc_encoder_update: final bit rate 229, final bit pool 35

おおっ? Google Pixel3 よりビットレート低いですね。SBC だと 229kbps でエンコードするとなっている。 設定で AAC に変えてみよう。

D/a2dp_aac_encoder: a2dp_aac_encoder_update: sample_rate=44100 bits_per_sample=16 channel_count=2
D/a2dp_aac_encoder: a2dp_aac_feeding_reset: PCM bytes per tick 3528
D/a2dp_aac_encoder: a2dp_aac_encoder_update: Restricting AVDTP MTU size from 1008 to 663
D/a2dp_aac_encoder: a2dp_aac_encoder_update: MTU=663, peer_mtu=663
D/a2dp_aac_encoder: a2dp_aac_encoder_update: sample_rate: 44100 channel_mode: 4
D/a2dp_aac_encoder: a2dp_aac_encoder_update: MTU = 663 Sampling Frequency = 44100 Bit Rate = 192000
D/a2dp_aac_encoder: a2dp_aac_encoder_update: AAC frame_length = 1024 input_channels_n = 2 max_encoded_buffer_bytes = 1536

なんと AAC でも 192kbps になっちまった。再起動してもペアリングし直してもこれ以上にならない。同じAACといえどもエンコードビットレートがここまで違うと音楽の聞こえっぷりも結構変わってくるわ。おもしろいねー。