blob: fc54c701588c701a28cd0e181f6e30787363ae65 [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>
29#include <aidl/android/hardware/bluetooth/audio/SbcCapabilities.h>
30#include <aidl/android/hardware/bluetooth/audio/SbcChannelMode.h>
31#include <android-base/logging.h>
32
33namespace aidl {
34namespace android {
35namespace hardware {
36namespace bluetooth {
37namespace audio {
38
39static const PcmCapabilities kDefaultSoftwarePcmCapabilities = {
40 .sampleRateHz = {16000, 24000, 44100, 48000, 88200, 96000},
41 .channelMode = {ChannelMode::MONO, ChannelMode::STEREO},
42 .bitsPerSample = {16, 24, 32},
43 .dataIntervalUs = {},
44};
45
46static const SbcCapabilities kDefaultOffloadSbcCapability = {
47 .sampleRateHz = {44100},
48 .channelMode = {SbcChannelMode::MONO, SbcChannelMode::JOINT_STEREO},
49 .blockLength = {4, 8, 12, 16},
50 .numSubbands = {8},
51 .allocMethod = {SbcAllocMethod::ALLOC_MD_L},
52 .bitsPerSample = {16},
53 .minBitpool = 2,
54 .maxBitpool = 53};
55
56static const AacCapabilities kDefaultOffloadAacCapability = {
57 .objectType = {AacObjectType::MPEG2_LC},
58 .sampleRateHz = {44100},
59 .channelMode = {ChannelMode::STEREO},
60 .variableBitRateSupported = true,
61 .bitsPerSample = {16}};
62
63static const LdacCapabilities kDefaultOffloadLdacCapability = {
64 .sampleRateHz = {44100, 48000, 88200, 96000},
65 .channelMode = {LdacChannelMode::DUAL, LdacChannelMode::STEREO},
66 .qualityIndex = {LdacQualityIndex::HIGH},
67 .bitsPerSample = {16, 24, 32}};
68
69static const AptxCapabilities kDefaultOffloadAptxCapability = {
70 .sampleRateHz = {44100, 48000},
71 .channelMode = {ChannelMode::STEREO},
72 .bitsPerSample = {16},
73};
74
75static const AptxCapabilities kDefaultOffloadAptxHdCapability = {
76 .sampleRateHz = {44100, 48000},
77 .channelMode = {ChannelMode::STEREO},
78 .bitsPerSample = {24},
79};
80
Josh Wu75462aa2022-01-21 21:51:21 -080081static const Lc3Capabilities kDefaultA2dpOffloadLc3Capability = {
Josh Wu20bac522021-12-29 23:52:39 -080082 .samplingFrequencyHz = {44100, 48000},
83 .frameDurationUs = {7500, 10000},
84 .channelMode = {ChannelMode::MONO, ChannelMode::STEREO},
85};
86
87const std::vector<CodecCapabilities> kDefaultOffloadA2dpCodecCapabilities = {
88 {.codecType = CodecType::SBC, .capabilities = {}},
89 {.codecType = CodecType::AAC, .capabilities = {}},
90 {.codecType = CodecType::LDAC, .capabilities = {}},
91 {.codecType = CodecType::APTX, .capabilities = {}},
92 {.codecType = CodecType::APTX_HD, .capabilities = {}},
93 {.codecType = CodecType::LC3, .capabilities = {}}};
94
95std::vector<LeAudioCodecCapabilitiesSetting> kDefaultOffloadLeAudioCapabilities;
96
97static const UnicastCapability kInvalidUnicastCapability = {
98 .codecType = CodecType::UNKNOWN};
99
100static const BroadcastCapability kInvalidBroadcastCapability = {
101 .codecType = CodecType::UNKNOWN};
102
103// Default Supported Codecs
104// LC3 16_1: sample rate: 16 kHz, frame duration: 7.5 ms, octets per frame: 30
105static const Lc3Capabilities kLc3Capability_16_1 = {
106 .samplingFrequencyHz = {16000},
107 .frameDurationUs = {7500},
108 .octetsPerFrame = {30}};
109
110// Default Supported Codecs
111// LC3 16_2: sample rate: 16 kHz, frame duration: 10 ms, octets per frame: 40
112static const Lc3Capabilities kLc3Capability_16_2 = {
113 .samplingFrequencyHz = {16000},
114 .frameDurationUs = {10000},
115 .octetsPerFrame = {40}};
116
117// Default Supported Codecs
118// LC3 48_4: sample rate: 48 kHz, frame duration: 10 ms, octets per frame: 120
119static const Lc3Capabilities kLc3Capability_48_4 = {
120 .samplingFrequencyHz = {48000},
121 .frameDurationUs = {10000},
122 .octetsPerFrame = {120}};
123
124static const std::vector<Lc3Capabilities> supportedLc3CapabilityList = {
125 kLc3Capability_48_4, kLc3Capability_16_2, kLc3Capability_16_1};
126
127static AudioLocation stereoAudio = static_cast<AudioLocation>(
128 static_cast<uint8_t>(AudioLocation::FRONT_LEFT) |
129 static_cast<uint8_t>(AudioLocation::FRONT_RIGHT));
130static AudioLocation monoAudio = AudioLocation::UNKNOWN;
131
132// Stores the supported setting of audio location, connected device, and the
133// channel count for each device
134std::vector<std::tuple<AudioLocation, uint8_t, uint8_t>>
Patty03cbe712022-02-10 10:07:17 +0800135 supportedDeviceSetting = {
136 // Stereo, two connected device, one for L one for R
137 std::make_tuple(stereoAudio, 2, 1),
138 // Stereo, one connected device for both L and R
139 std::make_tuple(stereoAudio, 1, 2),
140 // Mono
141 std::make_tuple(monoAudio, 1, 1)};
Josh Wu20bac522021-12-29 23:52:39 -0800142
143template <class T>
144bool BluetoothAudioCodecs::ContainedInVector(
145 const std::vector<T>& vector, const typename identity<T>::type& target) {
146 return std::find(vector.begin(), vector.end(), target) != vector.end();
147}
148
149bool BluetoothAudioCodecs::IsOffloadSbcConfigurationValid(
150 const CodecConfiguration::CodecSpecific& codec_specific) {
151 if (codec_specific.getTag() != CodecConfiguration::CodecSpecific::sbcConfig) {
152 LOG(WARNING) << __func__
153 << ": Invalid CodecSpecific=" << codec_specific.toString();
154 return false;
155 }
156 const SbcConfiguration sbc_data =
157 codec_specific.get<CodecConfiguration::CodecSpecific::sbcConfig>();
158
159 if (ContainedInVector(kDefaultOffloadSbcCapability.sampleRateHz,
160 sbc_data.sampleRateHz) &&
161 ContainedInVector(kDefaultOffloadSbcCapability.blockLength,
162 sbc_data.blockLength) &&
163 ContainedInVector(kDefaultOffloadSbcCapability.numSubbands,
164 sbc_data.numSubbands) &&
165 ContainedInVector(kDefaultOffloadSbcCapability.bitsPerSample,
166 sbc_data.bitsPerSample) &&
167 ContainedInVector(kDefaultOffloadSbcCapability.channelMode,
168 sbc_data.channelMode) &&
169 ContainedInVector(kDefaultOffloadSbcCapability.allocMethod,
170 sbc_data.allocMethod) &&
171 sbc_data.minBitpool <= sbc_data.maxBitpool &&
172 kDefaultOffloadSbcCapability.minBitpool <= sbc_data.minBitpool &&
173 kDefaultOffloadSbcCapability.maxBitpool >= sbc_data.maxBitpool) {
174 return true;
175 }
176 LOG(WARNING) << __func__
177 << ": Unsupported CodecSpecific=" << codec_specific.toString();
178 return false;
179}
180
181bool BluetoothAudioCodecs::IsOffloadAacConfigurationValid(
182 const CodecConfiguration::CodecSpecific& codec_specific) {
183 if (codec_specific.getTag() != CodecConfiguration::CodecSpecific::aacConfig) {
184 LOG(WARNING) << __func__
185 << ": Invalid CodecSpecific=" << codec_specific.toString();
186 return false;
187 }
188 const AacConfiguration aac_data =
189 codec_specific.get<CodecConfiguration::CodecSpecific::aacConfig>();
190
191 if (ContainedInVector(kDefaultOffloadAacCapability.sampleRateHz,
192 aac_data.sampleRateHz) &&
193 ContainedInVector(kDefaultOffloadAacCapability.bitsPerSample,
194 aac_data.bitsPerSample) &&
195 ContainedInVector(kDefaultOffloadAacCapability.channelMode,
196 aac_data.channelMode) &&
197 ContainedInVector(kDefaultOffloadAacCapability.objectType,
198 aac_data.objectType) &&
199 (!aac_data.variableBitRateEnabled ||
200 kDefaultOffloadAacCapability.variableBitRateSupported)) {
201 return true;
202 }
203 LOG(WARNING) << __func__
204 << ": Unsupported CodecSpecific=" << codec_specific.toString();
205 return false;
206}
207
208bool BluetoothAudioCodecs::IsOffloadLdacConfigurationValid(
209 const CodecConfiguration::CodecSpecific& codec_specific) {
210 if (codec_specific.getTag() !=
211 CodecConfiguration::CodecSpecific::ldacConfig) {
212 LOG(WARNING) << __func__
213 << ": Invalid CodecSpecific=" << codec_specific.toString();
214 return false;
215 }
216 const LdacConfiguration ldac_data =
217 codec_specific.get<CodecConfiguration::CodecSpecific::ldacConfig>();
218
219 if (ContainedInVector(kDefaultOffloadLdacCapability.sampleRateHz,
220 ldac_data.sampleRateHz) &&
221 ContainedInVector(kDefaultOffloadLdacCapability.bitsPerSample,
222 ldac_data.bitsPerSample) &&
223 ContainedInVector(kDefaultOffloadLdacCapability.channelMode,
224 ldac_data.channelMode) &&
225 ContainedInVector(kDefaultOffloadLdacCapability.qualityIndex,
226 ldac_data.qualityIndex)) {
227 return true;
228 }
229 LOG(WARNING) << __func__
230 << ": Unsupported CodecSpecific=" << codec_specific.toString();
231 return false;
232}
233
234bool BluetoothAudioCodecs::IsOffloadAptxConfigurationValid(
235 const CodecConfiguration::CodecSpecific& codec_specific) {
236 if (codec_specific.getTag() !=
237 CodecConfiguration::CodecSpecific::aptxConfig) {
238 LOG(WARNING) << __func__
239 << ": Invalid CodecSpecific=" << codec_specific.toString();
240 return false;
241 }
242 const AptxConfiguration aptx_data =
243 codec_specific.get<CodecConfiguration::CodecSpecific::aptxConfig>();
244
245 if (ContainedInVector(kDefaultOffloadAptxCapability.sampleRateHz,
246 aptx_data.sampleRateHz) &&
247 ContainedInVector(kDefaultOffloadAptxCapability.bitsPerSample,
248 aptx_data.bitsPerSample) &&
249 ContainedInVector(kDefaultOffloadAptxCapability.channelMode,
250 aptx_data.channelMode)) {
251 return true;
252 }
253 LOG(WARNING) << __func__
254 << ": Unsupported CodecSpecific=" << codec_specific.toString();
255 return false;
256}
257
258bool BluetoothAudioCodecs::IsOffloadAptxHdConfigurationValid(
259 const CodecConfiguration::CodecSpecific& codec_specific) {
260 if (codec_specific.getTag() !=
261 CodecConfiguration::CodecSpecific::aptxConfig) {
262 LOG(WARNING) << __func__
263 << ": Invalid CodecSpecific=" << codec_specific.toString();
264 return false;
265 }
266 const AptxConfiguration aptx_data =
267 codec_specific.get<CodecConfiguration::CodecSpecific::aptxConfig>();
268
269 if (ContainedInVector(kDefaultOffloadAptxHdCapability.sampleRateHz,
270 aptx_data.sampleRateHz) &&
271 ContainedInVector(kDefaultOffloadAptxHdCapability.bitsPerSample,
272 aptx_data.bitsPerSample) &&
273 ContainedInVector(kDefaultOffloadAptxHdCapability.channelMode,
274 aptx_data.channelMode)) {
275 return true;
276 }
277 LOG(WARNING) << __func__
278 << ": Unsupported CodecSpecific=" << codec_specific.toString();
279 return false;
280}
281
282bool BluetoothAudioCodecs::IsOffloadLc3ConfigurationValid(
283 const CodecConfiguration::CodecSpecific& codec_specific) {
284 if (codec_specific.getTag() != CodecConfiguration::CodecSpecific::lc3Config) {
285 LOG(WARNING) << __func__
286 << ": Invalid CodecSpecific=" << codec_specific.toString();
287 return false;
288 }
289 const Lc3Configuration lc3_data =
290 codec_specific.get<CodecConfiguration::CodecSpecific::lc3Config>();
291
Josh Wu75462aa2022-01-21 21:51:21 -0800292 if (ContainedInVector(kDefaultA2dpOffloadLc3Capability.samplingFrequencyHz,
Josh Wu20bac522021-12-29 23:52:39 -0800293 lc3_data.samplingFrequencyHz) &&
Josh Wu75462aa2022-01-21 21:51:21 -0800294 ContainedInVector(kDefaultA2dpOffloadLc3Capability.frameDurationUs,
Josh Wu20bac522021-12-29 23:52:39 -0800295 lc3_data.frameDurationUs) &&
Josh Wu75462aa2022-01-21 21:51:21 -0800296 ContainedInVector(kDefaultA2dpOffloadLc3Capability.channelMode,
Josh Wu20bac522021-12-29 23:52:39 -0800297 lc3_data.channelMode)) {
298 return true;
299 }
300 LOG(WARNING) << __func__
301 << ": Unsupported CodecSpecific=" << codec_specific.toString();
302 return false;
303}
304
305bool BluetoothAudioCodecs::IsOffloadLeAudioConfigurationValid(
306 const SessionType& session_type, const LeAudioConfiguration&) {
307 if (session_type !=
308 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
309 session_type !=
Josh Wu5d50dc02022-02-15 08:41:53 -0800310 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH &&
311 session_type !=
312 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
Josh Wu20bac522021-12-29 23:52:39 -0800313 return false;
314 }
315 return true;
316}
317
318std::vector<PcmCapabilities>
319BluetoothAudioCodecs::GetSoftwarePcmCapabilities() {
320 return {kDefaultSoftwarePcmCapabilities};
321}
322
323std::vector<CodecCapabilities>
324BluetoothAudioCodecs::GetA2dpOffloadCodecCapabilities(
325 const SessionType& session_type) {
Alice Kuoadcceec2022-03-28 13:28:43 +0800326 if (session_type != SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
327 session_type != SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
Josh Wu20bac522021-12-29 23:52:39 -0800328 return {};
329 }
330 std::vector<CodecCapabilities> offload_a2dp_codec_capabilities =
331 kDefaultOffloadA2dpCodecCapabilities;
332 for (auto& codec_capability : offload_a2dp_codec_capabilities) {
333 switch (codec_capability.codecType) {
334 case CodecType::SBC:
335 codec_capability.capabilities
336 .set<CodecCapabilities::Capabilities::sbcCapabilities>(
337 kDefaultOffloadSbcCapability);
338 break;
339 case CodecType::AAC:
340 codec_capability.capabilities
341 .set<CodecCapabilities::Capabilities::aacCapabilities>(
342 kDefaultOffloadAacCapability);
343 break;
344 case CodecType::LDAC:
345 codec_capability.capabilities
346 .set<CodecCapabilities::Capabilities::ldacCapabilities>(
347 kDefaultOffloadLdacCapability);
348 break;
349 case CodecType::APTX:
350 codec_capability.capabilities
351 .set<CodecCapabilities::Capabilities::aptxCapabilities>(
352 kDefaultOffloadAptxCapability);
353 break;
354 case CodecType::APTX_HD:
355 codec_capability.capabilities
356 .set<CodecCapabilities::Capabilities::aptxCapabilities>(
357 kDefaultOffloadAptxHdCapability);
358 break;
359 case CodecType::LC3:
360 codec_capability.capabilities
361 .set<CodecCapabilities::Capabilities::lc3Capabilities>(
Josh Wu75462aa2022-01-21 21:51:21 -0800362 kDefaultA2dpOffloadLc3Capability);
Josh Wu20bac522021-12-29 23:52:39 -0800363 break;
364 case CodecType::UNKNOWN:
Alice Kuo79c936d2022-01-20 23:10:10 +0800365 case CodecType::VENDOR:
Sagar Vermad13bbb32022-01-08 20:09:04 +0530366 case CodecType::APTX_ADAPTIVE:
Josh Wu20bac522021-12-29 23:52:39 -0800367 break;
368 }
369 }
370 return offload_a2dp_codec_capabilities;
371}
372
373bool BluetoothAudioCodecs::IsSoftwarePcmConfigurationValid(
374 const PcmConfiguration& pcm_config) {
375 if (ContainedInVector(kDefaultSoftwarePcmCapabilities.sampleRateHz,
376 pcm_config.sampleRateHz) &&
377 ContainedInVector(kDefaultSoftwarePcmCapabilities.bitsPerSample,
378 pcm_config.bitsPerSample) &&
379 ContainedInVector(kDefaultSoftwarePcmCapabilities.channelMode,
380 pcm_config.channelMode)
381 // data interval is not checked for now
382 // && pcm_config.dataIntervalUs != 0
383 ) {
384 return true;
385 }
386 LOG(WARNING) << __func__
387 << ": Unsupported CodecSpecific=" << pcm_config.toString();
388 return false;
389}
390
391bool BluetoothAudioCodecs::IsOffloadCodecConfigurationValid(
392 const SessionType& session_type, const CodecConfiguration& codec_config) {
Alice Kuoadcceec2022-03-28 13:28:43 +0800393 if (session_type != SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
394 session_type != SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
Josh Wu20bac522021-12-29 23:52:39 -0800395 LOG(ERROR) << __func__
396 << ": Invalid SessionType=" << toString(session_type);
397 return false;
398 }
399 const CodecConfiguration::CodecSpecific& codec_specific = codec_config.config;
400 switch (codec_config.codecType) {
401 case CodecType::SBC:
402 if (IsOffloadSbcConfigurationValid(codec_specific)) {
403 return true;
404 }
405 break;
406 case CodecType::AAC:
407 if (IsOffloadAacConfigurationValid(codec_specific)) {
408 return true;
409 }
410 break;
411 case CodecType::LDAC:
412 if (IsOffloadLdacConfigurationValid(codec_specific)) {
413 return true;
414 }
415 break;
416 case CodecType::APTX:
417 if (IsOffloadAptxConfigurationValid(codec_specific)) {
418 return true;
419 }
420 break;
421 case CodecType::APTX_HD:
422 if (IsOffloadAptxHdConfigurationValid(codec_specific)) {
423 return true;
424 }
425 break;
426 case CodecType::LC3:
427 if (IsOffloadLc3ConfigurationValid(codec_specific)) {
428 return true;
429 }
430 break;
Sagar Vermad13bbb32022-01-08 20:09:04 +0530431 case CodecType::APTX_ADAPTIVE:
Josh Wu20bac522021-12-29 23:52:39 -0800432 case CodecType::UNKNOWN:
Alice Kuo79c936d2022-01-20 23:10:10 +0800433 case CodecType::VENDOR:
Josh Wu20bac522021-12-29 23:52:39 -0800434 break;
435 }
436 return false;
437}
438
439UnicastCapability composeUnicastLc3Capability(
440 AudioLocation audioLocation, uint8_t deviceCnt, uint8_t channelCount,
441 const Lc3Capabilities& capability) {
442 return {
443 .codecType = CodecType::LC3,
444 .supportedChannel = audioLocation,
445 .deviceCount = deviceCnt,
446 .channelCountPerDevice = channelCount,
447 .leAudioCodecCapabilities =
448 UnicastCapability::LeAudioCodecCapabilities(capability),
449 };
450}
451
452std::vector<LeAudioCodecCapabilitiesSetting>
453BluetoothAudioCodecs::GetLeAudioOffloadCodecCapabilities(
454 const SessionType& session_type) {
455 if (session_type !=
456 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
457 session_type !=
Josh Wu5d50dc02022-02-15 08:41:53 -0800458 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH &&
459 session_type !=
460 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
Josh Wu20bac522021-12-29 23:52:39 -0800461 return std::vector<LeAudioCodecCapabilitiesSetting>(0);
462 }
463
464 if (kDefaultOffloadLeAudioCapabilities.empty()) {
465 for (auto [audioLocation, deviceCnt, channelCount] :
466 supportedDeviceSetting) {
467 for (auto capability : supportedLc3CapabilityList) {
468 UnicastCapability lc3Capability = composeUnicastLc3Capability(
469 audioLocation, deviceCnt, channelCount, capability);
470 UnicastCapability lc3MonoDecodeCapability =
471 composeUnicastLc3Capability(monoAudio, 1, 1, capability);
472
473 // Adds the capability for encode only
474 kDefaultOffloadLeAudioCapabilities.push_back(
475 {.unicastEncodeCapability = lc3Capability,
476 .unicastDecodeCapability = kInvalidUnicastCapability,
477 .broadcastCapability = kInvalidBroadcastCapability});
478
479 // Adds the capability for decode only
480 kDefaultOffloadLeAudioCapabilities.push_back(
481 {.unicastEncodeCapability = kInvalidUnicastCapability,
482 .unicastDecodeCapability = lc3Capability,
483 .broadcastCapability = kInvalidBroadcastCapability});
484
485 // Adds the capability for the case that encode and decode exist at the
486 // same time
487 kDefaultOffloadLeAudioCapabilities.push_back(
488 {.unicastEncodeCapability = lc3Capability,
489 .unicastDecodeCapability = lc3MonoDecodeCapability,
490 .broadcastCapability = kInvalidBroadcastCapability});
491 }
492 }
493 }
494
495 return kDefaultOffloadLeAudioCapabilities;
496}
497
498} // namespace audio
499} // namespace bluetooth
500} // namespace hardware
501} // namespace android
Sagar Vermad13bbb32022-01-08 20:09:04 +0530502} // namespace aidl