blob: d37825a2a1f9bc4fcb32c45a9a2adca888972cc4 [file] [log] [blame]
Josh Wu20bac522021-12-29 23:52:39 -08001/*
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "BTAudioCodecsAidl"
18
19#include "BluetoothAudioCodecs.h"
20
21#include <aidl/android/hardware/bluetooth/audio/AacCapabilities.h>
22#include <aidl/android/hardware/bluetooth/audio/AacObjectType.h>
23#include <aidl/android/hardware/bluetooth/audio/AptxCapabilities.h>
24#include <aidl/android/hardware/bluetooth/audio/ChannelMode.h>
25#include <aidl/android/hardware/bluetooth/audio/LdacCapabilities.h>
26#include <aidl/android/hardware/bluetooth/audio/LdacChannelMode.h>
27#include <aidl/android/hardware/bluetooth/audio/LdacQualityIndex.h>
28#include <aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.h>
Omer Osmana2587da2022-05-01 03:54:11 +000029#include <aidl/android/hardware/bluetooth/audio/OpusCapabilities.h>
30#include <aidl/android/hardware/bluetooth/audio/OpusConfiguration.h>
Josh Wu20bac522021-12-29 23:52:39 -080031#include <aidl/android/hardware/bluetooth/audio/SbcCapabilities.h>
32#include <aidl/android/hardware/bluetooth/audio/SbcChannelMode.h>
33#include <android-base/logging.h>
34
Bao Dofbc99e02023-11-15 03:21:03 +000035#include "BluetoothLeAudioAseConfigurationSettingProvider.h"
shihchienc8ed901a2022-09-06 08:44:44 +000036#include "BluetoothLeAudioCodecsProvider.h"
37
Josh Wu20bac522021-12-29 23:52:39 -080038namespace aidl {
39namespace android {
40namespace hardware {
41namespace bluetooth {
42namespace audio {
43
44static const PcmCapabilities kDefaultSoftwarePcmCapabilities = {
Yuyang Huangaa70c112023-10-26 16:01:45 -070045 .sampleRateHz = {8000, 16000, 24000, 32000, 44100, 48000, 88200, 96000},
Josh Wu20bac522021-12-29 23:52:39 -080046 .channelMode = {ChannelMode::MONO, ChannelMode::STEREO},
47 .bitsPerSample = {16, 24, 32},
48 .dataIntervalUs = {},
49};
50
51static const SbcCapabilities kDefaultOffloadSbcCapability = {
52 .sampleRateHz = {44100},
53 .channelMode = {SbcChannelMode::MONO, SbcChannelMode::JOINT_STEREO},
54 .blockLength = {4, 8, 12, 16},
55 .numSubbands = {8},
56 .allocMethod = {SbcAllocMethod::ALLOC_MD_L},
57 .bitsPerSample = {16},
58 .minBitpool = 2,
59 .maxBitpool = 53};
60
61static const AacCapabilities kDefaultOffloadAacCapability = {
62 .objectType = {AacObjectType::MPEG2_LC},
63 .sampleRateHz = {44100},
64 .channelMode = {ChannelMode::STEREO},
65 .variableBitRateSupported = true,
66 .bitsPerSample = {16}};
67
68static const LdacCapabilities kDefaultOffloadLdacCapability = {
69 .sampleRateHz = {44100, 48000, 88200, 96000},
70 .channelMode = {LdacChannelMode::DUAL, LdacChannelMode::STEREO},
71 .qualityIndex = {LdacQualityIndex::HIGH},
72 .bitsPerSample = {16, 24, 32}};
73
74static const AptxCapabilities kDefaultOffloadAptxCapability = {
75 .sampleRateHz = {44100, 48000},
76 .channelMode = {ChannelMode::STEREO},
77 .bitsPerSample = {16},
78};
79
80static const AptxCapabilities kDefaultOffloadAptxHdCapability = {
81 .sampleRateHz = {44100, 48000},
82 .channelMode = {ChannelMode::STEREO},
83 .bitsPerSample = {24},
84};
85
Omer Osmana2587da2022-05-01 03:54:11 +000086static const OpusCapabilities kDefaultOffloadOpusCapability = {
87 .samplingFrequencyHz = {48000},
88 .frameDurationUs = {10000, 20000},
Josh Wu20bac522021-12-29 23:52:39 -080089 .channelMode = {ChannelMode::MONO, ChannelMode::STEREO},
90};
91
92const std::vector<CodecCapabilities> kDefaultOffloadA2dpCodecCapabilities = {
93 {.codecType = CodecType::SBC, .capabilities = {}},
94 {.codecType = CodecType::AAC, .capabilities = {}},
95 {.codecType = CodecType::LDAC, .capabilities = {}},
96 {.codecType = CodecType::APTX, .capabilities = {}},
97 {.codecType = CodecType::APTX_HD, .capabilities = {}},
Omer Osmana2587da2022-05-01 03:54:11 +000098 {.codecType = CodecType::OPUS, .capabilities = {}}};
Josh Wu20bac522021-12-29 23:52:39 -080099
100std::vector<LeAudioCodecCapabilitiesSetting> kDefaultOffloadLeAudioCapabilities;
Bao Do6aeb5d72023-12-11 10:53:18 +0000101std::unordered_map<SessionType, std::vector<CodecInfo>>
102 kDefaultOffloadLeAudioCodecInfoMap;
Josh Wu20bac522021-12-29 23:52:39 -0800103
Josh Wu20bac522021-12-29 23:52:39 -0800104template <class T>
105bool BluetoothAudioCodecs::ContainedInVector(
106 const std::vector<T>& vector, const typename identity<T>::type& target) {
107 return std::find(vector.begin(), vector.end(), target) != vector.end();
108}
109
110bool BluetoothAudioCodecs::IsOffloadSbcConfigurationValid(
111 const CodecConfiguration::CodecSpecific& codec_specific) {
112 if (codec_specific.getTag() != CodecConfiguration::CodecSpecific::sbcConfig) {
113 LOG(WARNING) << __func__
114 << ": Invalid CodecSpecific=" << codec_specific.toString();
115 return false;
116 }
117 const SbcConfiguration sbc_data =
118 codec_specific.get<CodecConfiguration::CodecSpecific::sbcConfig>();
119
120 if (ContainedInVector(kDefaultOffloadSbcCapability.sampleRateHz,
121 sbc_data.sampleRateHz) &&
122 ContainedInVector(kDefaultOffloadSbcCapability.blockLength,
123 sbc_data.blockLength) &&
124 ContainedInVector(kDefaultOffloadSbcCapability.numSubbands,
125 sbc_data.numSubbands) &&
126 ContainedInVector(kDefaultOffloadSbcCapability.bitsPerSample,
127 sbc_data.bitsPerSample) &&
128 ContainedInVector(kDefaultOffloadSbcCapability.channelMode,
129 sbc_data.channelMode) &&
130 ContainedInVector(kDefaultOffloadSbcCapability.allocMethod,
131 sbc_data.allocMethod) &&
132 sbc_data.minBitpool <= sbc_data.maxBitpool &&
133 kDefaultOffloadSbcCapability.minBitpool <= sbc_data.minBitpool &&
134 kDefaultOffloadSbcCapability.maxBitpool >= sbc_data.maxBitpool) {
135 return true;
136 }
137 LOG(WARNING) << __func__
138 << ": Unsupported CodecSpecific=" << codec_specific.toString();
139 return false;
140}
141
142bool BluetoothAudioCodecs::IsOffloadAacConfigurationValid(
143 const CodecConfiguration::CodecSpecific& codec_specific) {
144 if (codec_specific.getTag() != CodecConfiguration::CodecSpecific::aacConfig) {
145 LOG(WARNING) << __func__
146 << ": Invalid CodecSpecific=" << codec_specific.toString();
147 return false;
148 }
149 const AacConfiguration aac_data =
150 codec_specific.get<CodecConfiguration::CodecSpecific::aacConfig>();
151
152 if (ContainedInVector(kDefaultOffloadAacCapability.sampleRateHz,
153 aac_data.sampleRateHz) &&
154 ContainedInVector(kDefaultOffloadAacCapability.bitsPerSample,
155 aac_data.bitsPerSample) &&
156 ContainedInVector(kDefaultOffloadAacCapability.channelMode,
157 aac_data.channelMode) &&
158 ContainedInVector(kDefaultOffloadAacCapability.objectType,
159 aac_data.objectType) &&
160 (!aac_data.variableBitRateEnabled ||
161 kDefaultOffloadAacCapability.variableBitRateSupported)) {
162 return true;
163 }
164 LOG(WARNING) << __func__
165 << ": Unsupported CodecSpecific=" << codec_specific.toString();
166 return false;
167}
168
169bool BluetoothAudioCodecs::IsOffloadLdacConfigurationValid(
170 const CodecConfiguration::CodecSpecific& codec_specific) {
171 if (codec_specific.getTag() !=
172 CodecConfiguration::CodecSpecific::ldacConfig) {
173 LOG(WARNING) << __func__
174 << ": Invalid CodecSpecific=" << codec_specific.toString();
175 return false;
176 }
177 const LdacConfiguration ldac_data =
178 codec_specific.get<CodecConfiguration::CodecSpecific::ldacConfig>();
179
180 if (ContainedInVector(kDefaultOffloadLdacCapability.sampleRateHz,
181 ldac_data.sampleRateHz) &&
182 ContainedInVector(kDefaultOffloadLdacCapability.bitsPerSample,
183 ldac_data.bitsPerSample) &&
184 ContainedInVector(kDefaultOffloadLdacCapability.channelMode,
185 ldac_data.channelMode) &&
186 ContainedInVector(kDefaultOffloadLdacCapability.qualityIndex,
187 ldac_data.qualityIndex)) {
188 return true;
189 }
190 LOG(WARNING) << __func__
191 << ": Unsupported CodecSpecific=" << codec_specific.toString();
192 return false;
193}
194
195bool BluetoothAudioCodecs::IsOffloadAptxConfigurationValid(
196 const CodecConfiguration::CodecSpecific& codec_specific) {
197 if (codec_specific.getTag() !=
198 CodecConfiguration::CodecSpecific::aptxConfig) {
199 LOG(WARNING) << __func__
200 << ": Invalid CodecSpecific=" << codec_specific.toString();
201 return false;
202 }
203 const AptxConfiguration aptx_data =
204 codec_specific.get<CodecConfiguration::CodecSpecific::aptxConfig>();
205
206 if (ContainedInVector(kDefaultOffloadAptxCapability.sampleRateHz,
207 aptx_data.sampleRateHz) &&
208 ContainedInVector(kDefaultOffloadAptxCapability.bitsPerSample,
209 aptx_data.bitsPerSample) &&
210 ContainedInVector(kDefaultOffloadAptxCapability.channelMode,
211 aptx_data.channelMode)) {
212 return true;
213 }
214 LOG(WARNING) << __func__
215 << ": Unsupported CodecSpecific=" << codec_specific.toString();
216 return false;
217}
218
219bool BluetoothAudioCodecs::IsOffloadAptxHdConfigurationValid(
220 const CodecConfiguration::CodecSpecific& codec_specific) {
221 if (codec_specific.getTag() !=
222 CodecConfiguration::CodecSpecific::aptxConfig) {
223 LOG(WARNING) << __func__
224 << ": Invalid CodecSpecific=" << codec_specific.toString();
225 return false;
226 }
227 const AptxConfiguration aptx_data =
228 codec_specific.get<CodecConfiguration::CodecSpecific::aptxConfig>();
229
230 if (ContainedInVector(kDefaultOffloadAptxHdCapability.sampleRateHz,
231 aptx_data.sampleRateHz) &&
232 ContainedInVector(kDefaultOffloadAptxHdCapability.bitsPerSample,
233 aptx_data.bitsPerSample) &&
234 ContainedInVector(kDefaultOffloadAptxHdCapability.channelMode,
235 aptx_data.channelMode)) {
236 return true;
237 }
238 LOG(WARNING) << __func__
239 << ": Unsupported CodecSpecific=" << codec_specific.toString();
240 return false;
241}
242
Omer Osmana2587da2022-05-01 03:54:11 +0000243bool BluetoothAudioCodecs::IsOffloadOpusConfigurationValid(
Josh Wu20bac522021-12-29 23:52:39 -0800244 const CodecConfiguration::CodecSpecific& codec_specific) {
Omer Osmana2587da2022-05-01 03:54:11 +0000245 if (codec_specific.getTag() !=
246 CodecConfiguration::CodecSpecific::opusConfig) {
Josh Wu20bac522021-12-29 23:52:39 -0800247 LOG(WARNING) << __func__
248 << ": Invalid CodecSpecific=" << codec_specific.toString();
249 return false;
250 }
Omer Osmana2587da2022-05-01 03:54:11 +0000251 std::optional<OpusConfiguration> opus_data =
252 codec_specific.get<CodecConfiguration::CodecSpecific::opusConfig>();
Josh Wu20bac522021-12-29 23:52:39 -0800253
Omer Osmana2587da2022-05-01 03:54:11 +0000254 if (opus_data.has_value() &&
255 ContainedInVector(kDefaultOffloadOpusCapability.samplingFrequencyHz,
256 opus_data->samplingFrequencyHz) &&
257 ContainedInVector(kDefaultOffloadOpusCapability.frameDurationUs,
258 opus_data->frameDurationUs) &&
259 ContainedInVector(kDefaultOffloadOpusCapability.channelMode,
260 opus_data->channelMode)) {
Josh Wu20bac522021-12-29 23:52:39 -0800261 return true;
262 }
263 LOG(WARNING) << __func__
264 << ": Unsupported CodecSpecific=" << codec_specific.toString();
265 return false;
266}
267
Josh Wu20bac522021-12-29 23:52:39 -0800268std::vector<PcmCapabilities>
269BluetoothAudioCodecs::GetSoftwarePcmCapabilities() {
270 return {kDefaultSoftwarePcmCapabilities};
271}
272
273std::vector<CodecCapabilities>
274BluetoothAudioCodecs::GetA2dpOffloadCodecCapabilities(
275 const SessionType& session_type) {
Alice Kuoadcceec2022-03-28 13:28:43 +0800276 if (session_type != SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
277 session_type != SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
Josh Wu20bac522021-12-29 23:52:39 -0800278 return {};
279 }
280 std::vector<CodecCapabilities> offload_a2dp_codec_capabilities =
281 kDefaultOffloadA2dpCodecCapabilities;
282 for (auto& codec_capability : offload_a2dp_codec_capabilities) {
283 switch (codec_capability.codecType) {
284 case CodecType::SBC:
285 codec_capability.capabilities
286 .set<CodecCapabilities::Capabilities::sbcCapabilities>(
287 kDefaultOffloadSbcCapability);
288 break;
289 case CodecType::AAC:
290 codec_capability.capabilities
291 .set<CodecCapabilities::Capabilities::aacCapabilities>(
292 kDefaultOffloadAacCapability);
293 break;
294 case CodecType::LDAC:
295 codec_capability.capabilities
296 .set<CodecCapabilities::Capabilities::ldacCapabilities>(
297 kDefaultOffloadLdacCapability);
298 break;
299 case CodecType::APTX:
300 codec_capability.capabilities
301 .set<CodecCapabilities::Capabilities::aptxCapabilities>(
302 kDefaultOffloadAptxCapability);
303 break;
304 case CodecType::APTX_HD:
305 codec_capability.capabilities
306 .set<CodecCapabilities::Capabilities::aptxCapabilities>(
307 kDefaultOffloadAptxHdCapability);
308 break;
Omer Osmana2587da2022-05-01 03:54:11 +0000309 case CodecType::OPUS:
Josh Wu20bac522021-12-29 23:52:39 -0800310 codec_capability.capabilities
Omer Osmana2587da2022-05-01 03:54:11 +0000311 .set<CodecCapabilities::Capabilities::opusCapabilities>(
312 kDefaultOffloadOpusCapability);
Josh Wu20bac522021-12-29 23:52:39 -0800313 break;
314 case CodecType::UNKNOWN:
Alice Kuo79c936d2022-01-20 23:10:10 +0800315 case CodecType::VENDOR:
Omer Osmana2587da2022-05-01 03:54:11 +0000316 case CodecType::LC3:
Sagar Vermad13bbb32022-01-08 20:09:04 +0530317 case CodecType::APTX_ADAPTIVE:
Sagar Verma62df9102022-12-07 17:56:04 +0530318 case CodecType::APTX_ADAPTIVE_LE:
319 case CodecType::APTX_ADAPTIVE_LEX:
Josh Wu20bac522021-12-29 23:52:39 -0800320 break;
321 }
322 }
323 return offload_a2dp_codec_capabilities;
324}
325
326bool BluetoothAudioCodecs::IsSoftwarePcmConfigurationValid(
327 const PcmConfiguration& pcm_config) {
328 if (ContainedInVector(kDefaultSoftwarePcmCapabilities.sampleRateHz,
329 pcm_config.sampleRateHz) &&
330 ContainedInVector(kDefaultSoftwarePcmCapabilities.bitsPerSample,
331 pcm_config.bitsPerSample) &&
332 ContainedInVector(kDefaultSoftwarePcmCapabilities.channelMode,
333 pcm_config.channelMode)
334 // data interval is not checked for now
335 // && pcm_config.dataIntervalUs != 0
336 ) {
337 return true;
338 }
339 LOG(WARNING) << __func__
340 << ": Unsupported CodecSpecific=" << pcm_config.toString();
341 return false;
342}
343
344bool BluetoothAudioCodecs::IsOffloadCodecConfigurationValid(
345 const SessionType& session_type, const CodecConfiguration& codec_config) {
Alice Kuoadcceec2022-03-28 13:28:43 +0800346 if (session_type != SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
347 session_type != SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
Josh Wu20bac522021-12-29 23:52:39 -0800348 LOG(ERROR) << __func__
349 << ": Invalid SessionType=" << toString(session_type);
350 return false;
351 }
352 const CodecConfiguration::CodecSpecific& codec_specific = codec_config.config;
353 switch (codec_config.codecType) {
354 case CodecType::SBC:
355 if (IsOffloadSbcConfigurationValid(codec_specific)) {
356 return true;
357 }
358 break;
359 case CodecType::AAC:
360 if (IsOffloadAacConfigurationValid(codec_specific)) {
361 return true;
362 }
363 break;
364 case CodecType::LDAC:
365 if (IsOffloadLdacConfigurationValid(codec_specific)) {
366 return true;
367 }
368 break;
369 case CodecType::APTX:
370 if (IsOffloadAptxConfigurationValid(codec_specific)) {
371 return true;
372 }
373 break;
374 case CodecType::APTX_HD:
375 if (IsOffloadAptxHdConfigurationValid(codec_specific)) {
376 return true;
377 }
378 break;
Omer Osmana2587da2022-05-01 03:54:11 +0000379 case CodecType::OPUS:
380 if (IsOffloadOpusConfigurationValid(codec_specific)) {
Josh Wu20bac522021-12-29 23:52:39 -0800381 return true;
382 }
383 break;
Sagar Vermad13bbb32022-01-08 20:09:04 +0530384 case CodecType::APTX_ADAPTIVE:
Sagar Verma62df9102022-12-07 17:56:04 +0530385 case CodecType::APTX_ADAPTIVE_LE:
386 case CodecType::APTX_ADAPTIVE_LEX:
Omer Osmana2587da2022-05-01 03:54:11 +0000387 case CodecType::LC3:
Josh Wu20bac522021-12-29 23:52:39 -0800388 case CodecType::UNKNOWN:
Alice Kuo79c936d2022-01-20 23:10:10 +0800389 case CodecType::VENDOR:
Josh Wu20bac522021-12-29 23:52:39 -0800390 break;
391 }
392 return false;
393}
394
Josh Wu20bac522021-12-29 23:52:39 -0800395std::vector<LeAudioCodecCapabilitiesSetting>
396BluetoothAudioCodecs::GetLeAudioOffloadCodecCapabilities(
397 const SessionType& session_type) {
398 if (session_type !=
399 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
400 session_type !=
Josh Wu5d50dc02022-02-15 08:41:53 -0800401 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH &&
402 session_type !=
403 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
Josh Wu20bac522021-12-29 23:52:39 -0800404 return std::vector<LeAudioCodecCapabilitiesSetting>(0);
405 }
406
407 if (kDefaultOffloadLeAudioCapabilities.empty()) {
shihchiencd7f565a2022-10-14 13:45:37 +0000408 auto le_audio_offload_setting =
409 BluetoothLeAudioCodecsProvider::ParseFromLeAudioOffloadSettingFile();
shihchienc8ed901a2022-09-06 08:44:44 +0000410 kDefaultOffloadLeAudioCapabilities =
shihchiencd7f565a2022-10-14 13:45:37 +0000411 BluetoothLeAudioCodecsProvider::GetLeAudioCodecCapabilities(
412 le_audio_offload_setting);
Sagar Verma62df9102022-12-07 17:56:04 +0530413 }
Josh Wu20bac522021-12-29 23:52:39 -0800414 return kDefaultOffloadLeAudioCapabilities;
415}
416
Bao Do6aeb5d72023-12-11 10:53:18 +0000417std::vector<CodecInfo> BluetoothAudioCodecs::GetLeAudioOffloadCodecInfo(
418 const SessionType& session_type) {
419 if (session_type !=
420 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
421 session_type !=
422 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH &&
423 session_type !=
424 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
425 return std::vector<CodecInfo>();
426 }
427
428 if (kDefaultOffloadLeAudioCodecInfoMap.empty()) {
429 auto le_audio_offload_setting =
430 BluetoothLeAudioCodecsProvider::ParseFromLeAudioOffloadSettingFile();
Jakub Tyszkowski0259aaf2024-01-05 12:36:38 +0000431 kDefaultOffloadLeAudioCodecInfoMap =
Bao Do6aeb5d72023-12-11 10:53:18 +0000432 BluetoothLeAudioCodecsProvider::GetLeAudioCodecInfo(
433 le_audio_offload_setting);
434 }
435 auto codec_info_map_iter =
436 kDefaultOffloadLeAudioCodecInfoMap.find(session_type);
437 if (codec_info_map_iter == kDefaultOffloadLeAudioCodecInfoMap.end())
438 return std::vector<CodecInfo>();
439 return codec_info_map_iter->second;
440}
441
Bao Dofbc99e02023-11-15 03:21:03 +0000442std::vector<LeAudioAseConfigurationSetting>
443BluetoothAudioCodecs::GetLeAudioAseConfigurationSettings() {
444 return AudioSetConfigurationProviderJson::
445 GetLeAudioAseConfigurationSettings();
446}
447
Josh Wu20bac522021-12-29 23:52:39 -0800448} // namespace audio
449} // namespace bluetooth
450} // namespace hardware
451} // namespace android
Sagar Vermad13bbb32022-01-08 20:09:04 +0530452} // namespace aidl