blob: 516ebe8d7a1e76d80441c73b38fb7ef4aea7835e [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>>
135 supportedDeviceSetting = {std::make_tuple(stereoAudio, 2, 1),
136 std::make_tuple(monoAudio, 1, 2),
137 std::make_tuple(monoAudio, 1, 1)};
138
139template <class T>
140bool BluetoothAudioCodecs::ContainedInVector(
141 const std::vector<T>& vector, const typename identity<T>::type& target) {
142 return std::find(vector.begin(), vector.end(), target) != vector.end();
143}
144
145bool BluetoothAudioCodecs::IsOffloadSbcConfigurationValid(
146 const CodecConfiguration::CodecSpecific& codec_specific) {
147 if (codec_specific.getTag() != CodecConfiguration::CodecSpecific::sbcConfig) {
148 LOG(WARNING) << __func__
149 << ": Invalid CodecSpecific=" << codec_specific.toString();
150 return false;
151 }
152 const SbcConfiguration sbc_data =
153 codec_specific.get<CodecConfiguration::CodecSpecific::sbcConfig>();
154
155 if (ContainedInVector(kDefaultOffloadSbcCapability.sampleRateHz,
156 sbc_data.sampleRateHz) &&
157 ContainedInVector(kDefaultOffloadSbcCapability.blockLength,
158 sbc_data.blockLength) &&
159 ContainedInVector(kDefaultOffloadSbcCapability.numSubbands,
160 sbc_data.numSubbands) &&
161 ContainedInVector(kDefaultOffloadSbcCapability.bitsPerSample,
162 sbc_data.bitsPerSample) &&
163 ContainedInVector(kDefaultOffloadSbcCapability.channelMode,
164 sbc_data.channelMode) &&
165 ContainedInVector(kDefaultOffloadSbcCapability.allocMethod,
166 sbc_data.allocMethod) &&
167 sbc_data.minBitpool <= sbc_data.maxBitpool &&
168 kDefaultOffloadSbcCapability.minBitpool <= sbc_data.minBitpool &&
169 kDefaultOffloadSbcCapability.maxBitpool >= sbc_data.maxBitpool) {
170 return true;
171 }
172 LOG(WARNING) << __func__
173 << ": Unsupported CodecSpecific=" << codec_specific.toString();
174 return false;
175}
176
177bool BluetoothAudioCodecs::IsOffloadAacConfigurationValid(
178 const CodecConfiguration::CodecSpecific& codec_specific) {
179 if (codec_specific.getTag() != CodecConfiguration::CodecSpecific::aacConfig) {
180 LOG(WARNING) << __func__
181 << ": Invalid CodecSpecific=" << codec_specific.toString();
182 return false;
183 }
184 const AacConfiguration aac_data =
185 codec_specific.get<CodecConfiguration::CodecSpecific::aacConfig>();
186
187 if (ContainedInVector(kDefaultOffloadAacCapability.sampleRateHz,
188 aac_data.sampleRateHz) &&
189 ContainedInVector(kDefaultOffloadAacCapability.bitsPerSample,
190 aac_data.bitsPerSample) &&
191 ContainedInVector(kDefaultOffloadAacCapability.channelMode,
192 aac_data.channelMode) &&
193 ContainedInVector(kDefaultOffloadAacCapability.objectType,
194 aac_data.objectType) &&
195 (!aac_data.variableBitRateEnabled ||
196 kDefaultOffloadAacCapability.variableBitRateSupported)) {
197 return true;
198 }
199 LOG(WARNING) << __func__
200 << ": Unsupported CodecSpecific=" << codec_specific.toString();
201 return false;
202}
203
204bool BluetoothAudioCodecs::IsOffloadLdacConfigurationValid(
205 const CodecConfiguration::CodecSpecific& codec_specific) {
206 if (codec_specific.getTag() !=
207 CodecConfiguration::CodecSpecific::ldacConfig) {
208 LOG(WARNING) << __func__
209 << ": Invalid CodecSpecific=" << codec_specific.toString();
210 return false;
211 }
212 const LdacConfiguration ldac_data =
213 codec_specific.get<CodecConfiguration::CodecSpecific::ldacConfig>();
214
215 if (ContainedInVector(kDefaultOffloadLdacCapability.sampleRateHz,
216 ldac_data.sampleRateHz) &&
217 ContainedInVector(kDefaultOffloadLdacCapability.bitsPerSample,
218 ldac_data.bitsPerSample) &&
219 ContainedInVector(kDefaultOffloadLdacCapability.channelMode,
220 ldac_data.channelMode) &&
221 ContainedInVector(kDefaultOffloadLdacCapability.qualityIndex,
222 ldac_data.qualityIndex)) {
223 return true;
224 }
225 LOG(WARNING) << __func__
226 << ": Unsupported CodecSpecific=" << codec_specific.toString();
227 return false;
228}
229
230bool BluetoothAudioCodecs::IsOffloadAptxConfigurationValid(
231 const CodecConfiguration::CodecSpecific& codec_specific) {
232 if (codec_specific.getTag() !=
233 CodecConfiguration::CodecSpecific::aptxConfig) {
234 LOG(WARNING) << __func__
235 << ": Invalid CodecSpecific=" << codec_specific.toString();
236 return false;
237 }
238 const AptxConfiguration aptx_data =
239 codec_specific.get<CodecConfiguration::CodecSpecific::aptxConfig>();
240
241 if (ContainedInVector(kDefaultOffloadAptxCapability.sampleRateHz,
242 aptx_data.sampleRateHz) &&
243 ContainedInVector(kDefaultOffloadAptxCapability.bitsPerSample,
244 aptx_data.bitsPerSample) &&
245 ContainedInVector(kDefaultOffloadAptxCapability.channelMode,
246 aptx_data.channelMode)) {
247 return true;
248 }
249 LOG(WARNING) << __func__
250 << ": Unsupported CodecSpecific=" << codec_specific.toString();
251 return false;
252}
253
254bool BluetoothAudioCodecs::IsOffloadAptxHdConfigurationValid(
255 const CodecConfiguration::CodecSpecific& codec_specific) {
256 if (codec_specific.getTag() !=
257 CodecConfiguration::CodecSpecific::aptxConfig) {
258 LOG(WARNING) << __func__
259 << ": Invalid CodecSpecific=" << codec_specific.toString();
260 return false;
261 }
262 const AptxConfiguration aptx_data =
263 codec_specific.get<CodecConfiguration::CodecSpecific::aptxConfig>();
264
265 if (ContainedInVector(kDefaultOffloadAptxHdCapability.sampleRateHz,
266 aptx_data.sampleRateHz) &&
267 ContainedInVector(kDefaultOffloadAptxHdCapability.bitsPerSample,
268 aptx_data.bitsPerSample) &&
269 ContainedInVector(kDefaultOffloadAptxHdCapability.channelMode,
270 aptx_data.channelMode)) {
271 return true;
272 }
273 LOG(WARNING) << __func__
274 << ": Unsupported CodecSpecific=" << codec_specific.toString();
275 return false;
276}
277
278bool BluetoothAudioCodecs::IsOffloadLc3ConfigurationValid(
279 const CodecConfiguration::CodecSpecific& codec_specific) {
280 if (codec_specific.getTag() != CodecConfiguration::CodecSpecific::lc3Config) {
281 LOG(WARNING) << __func__
282 << ": Invalid CodecSpecific=" << codec_specific.toString();
283 return false;
284 }
285 const Lc3Configuration lc3_data =
286 codec_specific.get<CodecConfiguration::CodecSpecific::lc3Config>();
287
Josh Wu75462aa2022-01-21 21:51:21 -0800288 if (ContainedInVector(kDefaultA2dpOffloadLc3Capability.samplingFrequencyHz,
Josh Wu20bac522021-12-29 23:52:39 -0800289 lc3_data.samplingFrequencyHz) &&
Josh Wu75462aa2022-01-21 21:51:21 -0800290 ContainedInVector(kDefaultA2dpOffloadLc3Capability.frameDurationUs,
Josh Wu20bac522021-12-29 23:52:39 -0800291 lc3_data.frameDurationUs) &&
Josh Wu75462aa2022-01-21 21:51:21 -0800292 ContainedInVector(kDefaultA2dpOffloadLc3Capability.channelMode,
Josh Wu20bac522021-12-29 23:52:39 -0800293 lc3_data.channelMode)) {
294 return true;
295 }
296 LOG(WARNING) << __func__
297 << ": Unsupported CodecSpecific=" << codec_specific.toString();
298 return false;
299}
300
301bool BluetoothAudioCodecs::IsOffloadLeAudioConfigurationValid(
302 const SessionType& session_type, const LeAudioConfiguration&) {
303 if (session_type !=
304 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
305 session_type !=
306 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
307 return false;
308 }
309 return true;
310}
311
312std::vector<PcmCapabilities>
313BluetoothAudioCodecs::GetSoftwarePcmCapabilities() {
314 return {kDefaultSoftwarePcmCapabilities};
315}
316
317std::vector<CodecCapabilities>
318BluetoothAudioCodecs::GetA2dpOffloadCodecCapabilities(
319 const SessionType& session_type) {
320 if (session_type != SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
321 return {};
322 }
323 std::vector<CodecCapabilities> offload_a2dp_codec_capabilities =
324 kDefaultOffloadA2dpCodecCapabilities;
325 for (auto& codec_capability : offload_a2dp_codec_capabilities) {
326 switch (codec_capability.codecType) {
327 case CodecType::SBC:
328 codec_capability.capabilities
329 .set<CodecCapabilities::Capabilities::sbcCapabilities>(
330 kDefaultOffloadSbcCapability);
331 break;
332 case CodecType::AAC:
333 codec_capability.capabilities
334 .set<CodecCapabilities::Capabilities::aacCapabilities>(
335 kDefaultOffloadAacCapability);
336 break;
337 case CodecType::LDAC:
338 codec_capability.capabilities
339 .set<CodecCapabilities::Capabilities::ldacCapabilities>(
340 kDefaultOffloadLdacCapability);
341 break;
342 case CodecType::APTX:
343 codec_capability.capabilities
344 .set<CodecCapabilities::Capabilities::aptxCapabilities>(
345 kDefaultOffloadAptxCapability);
346 break;
347 case CodecType::APTX_HD:
348 codec_capability.capabilities
349 .set<CodecCapabilities::Capabilities::aptxCapabilities>(
350 kDefaultOffloadAptxHdCapability);
351 break;
352 case CodecType::LC3:
353 codec_capability.capabilities
354 .set<CodecCapabilities::Capabilities::lc3Capabilities>(
Josh Wu75462aa2022-01-21 21:51:21 -0800355 kDefaultA2dpOffloadLc3Capability);
Josh Wu20bac522021-12-29 23:52:39 -0800356 break;
357 case CodecType::UNKNOWN:
Alice Kuo79c936d2022-01-20 23:10:10 +0800358 case CodecType::VENDOR:
Josh Wu20bac522021-12-29 23:52:39 -0800359 break;
360 }
361 }
362 return offload_a2dp_codec_capabilities;
363}
364
365bool BluetoothAudioCodecs::IsSoftwarePcmConfigurationValid(
366 const PcmConfiguration& pcm_config) {
367 if (ContainedInVector(kDefaultSoftwarePcmCapabilities.sampleRateHz,
368 pcm_config.sampleRateHz) &&
369 ContainedInVector(kDefaultSoftwarePcmCapabilities.bitsPerSample,
370 pcm_config.bitsPerSample) &&
371 ContainedInVector(kDefaultSoftwarePcmCapabilities.channelMode,
372 pcm_config.channelMode)
373 // data interval is not checked for now
374 // && pcm_config.dataIntervalUs != 0
375 ) {
376 return true;
377 }
378 LOG(WARNING) << __func__
379 << ": Unsupported CodecSpecific=" << pcm_config.toString();
380 return false;
381}
382
383bool BluetoothAudioCodecs::IsOffloadCodecConfigurationValid(
384 const SessionType& session_type, const CodecConfiguration& codec_config) {
385 if (session_type != SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
386 LOG(ERROR) << __func__
387 << ": Invalid SessionType=" << toString(session_type);
388 return false;
389 }
390 const CodecConfiguration::CodecSpecific& codec_specific = codec_config.config;
391 switch (codec_config.codecType) {
392 case CodecType::SBC:
393 if (IsOffloadSbcConfigurationValid(codec_specific)) {
394 return true;
395 }
396 break;
397 case CodecType::AAC:
398 if (IsOffloadAacConfigurationValid(codec_specific)) {
399 return true;
400 }
401 break;
402 case CodecType::LDAC:
403 if (IsOffloadLdacConfigurationValid(codec_specific)) {
404 return true;
405 }
406 break;
407 case CodecType::APTX:
408 if (IsOffloadAptxConfigurationValid(codec_specific)) {
409 return true;
410 }
411 break;
412 case CodecType::APTX_HD:
413 if (IsOffloadAptxHdConfigurationValid(codec_specific)) {
414 return true;
415 }
416 break;
417 case CodecType::LC3:
418 if (IsOffloadLc3ConfigurationValid(codec_specific)) {
419 return true;
420 }
421 break;
422 case CodecType::UNKNOWN:
Alice Kuo79c936d2022-01-20 23:10:10 +0800423 case CodecType::VENDOR:
Josh Wu20bac522021-12-29 23:52:39 -0800424 break;
425 }
426 return false;
427}
428
429UnicastCapability composeUnicastLc3Capability(
430 AudioLocation audioLocation, uint8_t deviceCnt, uint8_t channelCount,
431 const Lc3Capabilities& capability) {
432 return {
433 .codecType = CodecType::LC3,
434 .supportedChannel = audioLocation,
435 .deviceCount = deviceCnt,
436 .channelCountPerDevice = channelCount,
437 .leAudioCodecCapabilities =
438 UnicastCapability::LeAudioCodecCapabilities(capability),
439 };
440}
441
442std::vector<LeAudioCodecCapabilitiesSetting>
443BluetoothAudioCodecs::GetLeAudioOffloadCodecCapabilities(
444 const SessionType& session_type) {
445 if (session_type !=
446 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
447 session_type !=
448 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
449 return std::vector<LeAudioCodecCapabilitiesSetting>(0);
450 }
451
452 if (kDefaultOffloadLeAudioCapabilities.empty()) {
453 for (auto [audioLocation, deviceCnt, channelCount] :
454 supportedDeviceSetting) {
455 for (auto capability : supportedLc3CapabilityList) {
456 UnicastCapability lc3Capability = composeUnicastLc3Capability(
457 audioLocation, deviceCnt, channelCount, capability);
458 UnicastCapability lc3MonoDecodeCapability =
459 composeUnicastLc3Capability(monoAudio, 1, 1, capability);
460
461 // Adds the capability for encode only
462 kDefaultOffloadLeAudioCapabilities.push_back(
463 {.unicastEncodeCapability = lc3Capability,
464 .unicastDecodeCapability = kInvalidUnicastCapability,
465 .broadcastCapability = kInvalidBroadcastCapability});
466
467 // Adds the capability for decode only
468 kDefaultOffloadLeAudioCapabilities.push_back(
469 {.unicastEncodeCapability = kInvalidUnicastCapability,
470 .unicastDecodeCapability = lc3Capability,
471 .broadcastCapability = kInvalidBroadcastCapability});
472
473 // Adds the capability for the case that encode and decode exist at the
474 // same time
475 kDefaultOffloadLeAudioCapabilities.push_back(
476 {.unicastEncodeCapability = lc3Capability,
477 .unicastDecodeCapability = lc3MonoDecodeCapability,
478 .broadcastCapability = kInvalidBroadcastCapability});
479 }
480 }
481 }
482
483 return kDefaultOffloadLeAudioCapabilities;
484}
485
486} // namespace audio
487} // namespace bluetooth
488} // namespace hardware
489} // namespace android
490} // namespace aidl