1 /*
2 * Copyright (C) 2023 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 #include "A2dpOffloadCodecSbc.h"
18
19 #include <algorithm>
20
21 #include "A2dpBits.h"
22
23 namespace aidl::android::hardware::bluetooth::audio {
24
25 /**
26 * SBC Local Capabilities
27 */
28
29 enum : bool {
30 kEnableSamplingFrequency44100 = true,
31 kEnableSamplingFrequency48000 = true,
32 };
33
34 enum : bool {
35 kEnableChannelModeMono = true,
36 kEnableChannelModeDualChannel = true,
37 kEnableChannelModeStereo = true,
38 kEnableChannelModeJointStereo = true,
39 };
40
41 enum : bool {
42 kEnableBlockLength4 = true,
43 kEnableBlockLength8 = true,
44 kEnableBlockLength12 = true,
45 kEnableBlockLength16 = true,
46 };
47
48 enum : bool {
49 kEnableSubbands4 = true,
50 kEnableSubbands8 = true,
51 };
52
53 enum : bool {
54 kEnableAllocationMethodSnr = true,
55 kEnableAllocationMethodLoudness = true,
56 };
57
58 enum : uint8_t {
59 kDefaultMinimumBitpool = 2,
60 kDefaultMaximumBitpool = 250,
61 };
62
63 enum : int {
64 kBitdepth = 16,
65 };
66
67 /**
68 * SBC Signaling format [A2DP - 4.3]
69 */
70
71 // clang-format off
72
73 constexpr A2dpBits::Range kSamplingFrequency ( 0, 3 );
74 constexpr A2dpBits::Range kChannelMode ( 4, 7 );
75 constexpr A2dpBits::Range kBlockLength ( 8, 11 );
76 constexpr A2dpBits::Range kSubbands ( 12, 13 );
77 constexpr A2dpBits::Range kAllocationMethod ( 14, 15 );
78 constexpr A2dpBits::Range kMinimumBitpool ( 16, 23 );
79 constexpr A2dpBits::Range kMaximumBitpool ( 24, 31 );
80 constexpr size_t kCapabilitiesSize = 32/8;
81
82 // clang-format on
83
84 enum {
85 kSamplingFrequency16000 = kSamplingFrequency.first,
86 kSamplingFrequency32000,
87 kSamplingFrequency44100,
88 kSamplingFrequency48000
89 };
90
91 enum {
92 kChannelModeMono = kChannelMode.first,
93 kChannelModeDualChannel,
94 kChannelModeStereo,
95 kChannelModeJointStereo
96 };
97
98 enum {
99 kBlockLength4 = kBlockLength.first,
100 kBlockLength8,
101 kBlockLength12,
102 kBlockLength16
103 };
104
105 enum { kSubbands8 = kSubbands.first, kSubbands4 };
106
107 enum {
108 kAllocationMethodSnr = kAllocationMethod.first,
109 kAllocationMethodLoudness
110 };
111
112 /**
113 * SBC Conversion functions
114 */
115
GetSamplingFrequencyBit(int32_t sampling_frequency)116 static int GetSamplingFrequencyBit(int32_t sampling_frequency) {
117 switch (sampling_frequency) {
118 case 16000:
119 return kSamplingFrequency16000;
120 case 32000:
121 return kSamplingFrequency32000;
122 case 44100:
123 return kSamplingFrequency44100;
124 case 48000:
125 return kSamplingFrequency48000;
126 default:
127 return -1;
128 }
129 }
130
GetSamplingFrequencyValue(int sampling_frequency)131 static int32_t GetSamplingFrequencyValue(int sampling_frequency) {
132 switch (sampling_frequency) {
133 case kSamplingFrequency16000:
134 return 16000;
135 case kSamplingFrequency32000:
136 return 32000;
137 case kSamplingFrequency44100:
138 return 44100;
139 case kSamplingFrequency48000:
140 return 48000;
141 default:
142 return 0;
143 }
144 }
145
GetChannelModeBit(ChannelMode channel_mode)146 static int GetChannelModeBit(ChannelMode channel_mode) {
147 switch (channel_mode) {
148 case ChannelMode::STEREO:
149 return kChannelModeJointStereo | kChannelModeStereo;
150 case ChannelMode::DUALMONO:
151 return kChannelModeDualChannel;
152 case ChannelMode::MONO:
153 return kChannelModeMono;
154 default:
155 return -1;
156 }
157 }
158
GetChannelModeEnum(int channel_mode)159 static ChannelMode GetChannelModeEnum(int channel_mode) {
160 switch (channel_mode) {
161 case kChannelModeMono:
162 return ChannelMode::MONO;
163 case kChannelModeDualChannel:
164 return ChannelMode::DUALMONO;
165 case kChannelModeStereo:
166 case kChannelModeJointStereo:
167 return ChannelMode::STEREO;
168 default:
169 return ChannelMode::UNKNOWN;
170 }
171 }
172
GetBlockLengthValue(int block_length)173 static int32_t GetBlockLengthValue(int block_length) {
174 switch (block_length) {
175 case kBlockLength4:
176 return 4;
177 case kBlockLength8:
178 return 8;
179 case kBlockLength12:
180 return 12;
181 case kBlockLength16:
182 return 16;
183 default:
184 return 0;
185 }
186 }
187
GetSubbandsValue(int subbands)188 static int32_t GetSubbandsValue(int subbands) {
189 switch (subbands) {
190 case kSubbands4:
191 return 4;
192 case kSubbands8:
193 return 8;
194 default:
195 return 0;
196 }
197 }
198
GetAllocationMethodEnum(int allocation_method)199 static SbcParameters::AllocationMethod GetAllocationMethodEnum(
200 int allocation_method) {
201 switch (allocation_method) {
202 case kAllocationMethodSnr:
203 return SbcParameters::AllocationMethod::SNR;
204 case kAllocationMethodLoudness:
205 default:
206 return SbcParameters::AllocationMethod::LOUDNESS;
207 }
208 }
209
GetSamplingFrequencyValue(const A2dpBits & configuration)210 static int32_t GetSamplingFrequencyValue(const A2dpBits& configuration) {
211 return GetSamplingFrequencyValue(
212 configuration.find_active_bit(kSamplingFrequency));
213 }
214
GetBlockLengthValue(const A2dpBits & configuration)215 static int32_t GetBlockLengthValue(const A2dpBits& configuration) {
216 return GetBlockLengthValue(configuration.find_active_bit(kBlockLength));
217 }
218
GetSubbandsValue(const A2dpBits & configuration)219 static int32_t GetSubbandsValue(const A2dpBits& configuration) {
220 return GetSubbandsValue(configuration.find_active_bit(kSubbands));
221 }
222
GetFrameSize(const A2dpBits & configuration,int bitpool)223 static int GetFrameSize(const A2dpBits& configuration, int bitpool) {
224 const int kSbcHeaderSize = 4;
225 int subbands = GetSubbandsValue(configuration);
226 int blocks = GetBlockLengthValue(configuration);
227
228 unsigned bits =
229 ((4 * subbands) << !configuration.get(kChannelModeMono)) +
230 ((blocks * bitpool) << configuration.get(kChannelModeDualChannel)) +
231 ((configuration.get(kChannelModeJointStereo) ? subbands : 0));
232
233 return kSbcHeaderSize + ((bits + 7) >> 3);
234 }
235
GetBitrate(const A2dpBits & configuration,int bitpool)236 static int GetBitrate(const A2dpBits& configuration, int bitpool) {
237 int sampling_frequency = GetSamplingFrequencyValue(configuration);
238 int subbands = GetSubbandsValue(configuration);
239 int blocks = GetBlockLengthValue(configuration);
240 int bits = 8 * GetFrameSize(configuration, bitpool);
241
242 return (bits * sampling_frequency) / (blocks * subbands);
243 }
244
GetBitpool(const A2dpBits & configuration,int bitrate)245 static uint8_t GetBitpool(const A2dpBits& configuration, int bitrate) {
246 int bitpool = 0;
247
248 for (int i = 128; i; i >>= 1)
249 if (bitrate > GetBitrate(configuration, bitpool + i)) {
250 bitpool += i;
251 }
252
253 return std::clamp(bitpool, 2, 250);
254 }
255
256 /**
257 * SBC Class implementation
258 */
259
A2dpOffloadCodecSbc()260 A2dpOffloadCodecSbc::A2dpOffloadCodecSbc()
261 : A2dpOffloadCodec(info_),
262 info_({.id = CodecId(CodecId::A2dp::SBC), .name = "SBC"}) {
263 info_.transport.set<CodecInfo::Transport::Tag::a2dp>();
264 auto& a2dp_info = info_.transport.get<CodecInfo::Transport::Tag::a2dp>();
265
266 /* --- Setup Capabilities --- */
267
268 a2dp_info.capabilities.resize(kCapabilitiesSize);
269 std::fill(begin(a2dp_info.capabilities), end(a2dp_info.capabilities), 0);
270
271 auto capabilities = A2dpBits(a2dp_info.capabilities);
272
273 capabilities.set(kSamplingFrequency44100, kEnableSamplingFrequency44100);
274 capabilities.set(kSamplingFrequency48000, kEnableSamplingFrequency48000);
275
276 capabilities.set(kChannelModeMono, kEnableChannelModeMono);
277 capabilities.set(kChannelModeDualChannel, kEnableChannelModeDualChannel);
278 capabilities.set(kChannelModeStereo, kEnableChannelModeStereo);
279 capabilities.set(kChannelModeJointStereo, kEnableChannelModeJointStereo);
280
281 capabilities.set(kBlockLength4, kEnableBlockLength4);
282 capabilities.set(kBlockLength8, kEnableBlockLength8);
283 capabilities.set(kBlockLength12, kEnableBlockLength12);
284 capabilities.set(kBlockLength16, kEnableBlockLength16);
285
286 capabilities.set(kSubbands4, kEnableSubbands4);
287 capabilities.set(kSubbands8, kEnableSubbands8);
288
289 capabilities.set(kSubbands4, kEnableSubbands4);
290 capabilities.set(kSubbands8, kEnableSubbands8);
291
292 capabilities.set(kAllocationMethodSnr, kEnableAllocationMethodSnr);
293 capabilities.set(kAllocationMethodLoudness, kEnableAllocationMethodLoudness);
294
295 capabilities.set(kMinimumBitpool, kDefaultMinimumBitpool);
296 capabilities.set(kMaximumBitpool, kDefaultMaximumBitpool);
297
298 /* --- Setup Sampling Frequencies --- */
299
300 auto& sampling_frequency = a2dp_info.samplingFrequencyHz;
301
302 for (auto v : {16000, 32000, 44100, 48000})
303 if (capabilities.get(GetSamplingFrequencyBit(int32_t(v))))
304 sampling_frequency.push_back(v);
305
306 /* --- Setup Channel Modes --- */
307
308 auto& channel_modes = a2dp_info.channelMode;
309
310 for (auto v : {ChannelMode::MONO, ChannelMode::DUALMONO, ChannelMode::STEREO})
311 if (capabilities.get(GetChannelModeBit(v))) channel_modes.push_back(v);
312
313 /* --- Setup Bitdepth --- */
314
315 a2dp_info.bitdepth.push_back(kBitdepth);
316 }
317
ParseConfiguration(const std::vector<uint8_t> & configuration,CodecParameters * codec_parameters,SbcParameters * sbc_parameters) const318 A2dpStatus A2dpOffloadCodecSbc::ParseConfiguration(
319 const std::vector<uint8_t>& configuration,
320 CodecParameters* codec_parameters, SbcParameters* sbc_parameters) const {
321 auto& a2dp_info = info.transport.get<CodecInfo::Transport::Tag::a2dp>();
322
323 if (configuration.size() != a2dp_info.capabilities.size())
324 return A2dpStatus::BAD_LENGTH;
325
326 auto config = A2dpBits(configuration);
327 auto lcaps = A2dpBits(a2dp_info.capabilities);
328
329 /* --- Check Sampling Frequency --- */
330
331 int sampling_frequency = config.find_active_bit(kSamplingFrequency);
332 if (sampling_frequency < 0) return A2dpStatus::INVALID_SAMPLING_FREQUENCY;
333 if (!lcaps.get(sampling_frequency))
334 return A2dpStatus::NOT_SUPPORTED_SAMPLING_FREQUENCY;
335
336 /* --- Check Channel Mode --- */
337
338 int channel_mode = config.find_active_bit(kChannelMode);
339 if (channel_mode < 0) return A2dpStatus::INVALID_CHANNEL_MODE;
340 if (!lcaps.get(channel_mode)) return A2dpStatus::NOT_SUPPORTED_CHANNEL_MODE;
341
342 /* --- Check Block Length --- */
343
344 int block_length = config.find_active_bit(kBlockLength);
345 if (block_length < 0) return A2dpStatus::INVALID_BLOCK_LENGTH;
346
347 /* --- Check Subbands --- */
348
349 int subbands = config.find_active_bit(kSubbands);
350 if (subbands < 0) return A2dpStatus::INVALID_SUBBANDS;
351 if (!lcaps.get(subbands)) return A2dpStatus::NOT_SUPPORTED_SUBBANDS;
352
353 /* --- Check Allocation Method --- */
354
355 int allocation_method = config.find_active_bit(kAllocationMethod);
356 if (allocation_method < 0) return A2dpStatus::INVALID_ALLOCATION_METHOD;
357 if (!lcaps.get(allocation_method))
358 return A2dpStatus::NOT_SUPPORTED_ALLOCATION_METHOD;
359
360 /* --- Check Bitpool --- */
361
362 uint8_t min_bitpool = config.get(kMinimumBitpool);
363 if (min_bitpool < 2 || min_bitpool > 250)
364 return A2dpStatus::INVALID_MINIMUM_BITPOOL_VALUE;
365 if (min_bitpool < lcaps.get(kMinimumBitpool))
366 return A2dpStatus::NOT_SUPPORTED_MINIMUM_BITPOOL_VALUE;
367
368 uint8_t max_bitpool = config.get(kMaximumBitpool);
369 if (max_bitpool < 2 || max_bitpool > 250)
370 return A2dpStatus::INVALID_MAXIMUM_BITPOOL_VALUE;
371 if (max_bitpool > lcaps.get(kMaximumBitpool))
372 return A2dpStatus::NOT_SUPPORTED_MAXIMUM_BITPOOL_VALUE;
373
374 /* --- Return --- */
375
376 codec_parameters->channelMode = GetChannelModeEnum(channel_mode);
377 codec_parameters->samplingFrequencyHz =
378 GetSamplingFrequencyValue(sampling_frequency);
379 codec_parameters->bitdepth = kBitdepth;
380
381 codec_parameters->minBitrate = GetBitrate(config, min_bitpool);
382 codec_parameters->maxBitrate = GetBitrate(config, max_bitpool);
383
384 if (sbc_parameters) {
385 sbc_parameters->block_length = GetBlockLengthValue(block_length);
386 sbc_parameters->subbands = GetSubbandsValue(subbands);
387 sbc_parameters->allocation_method =
388 GetAllocationMethodEnum(allocation_method);
389 sbc_parameters->min_bitpool = min_bitpool;
390 sbc_parameters->max_bitpool = max_bitpool;
391 }
392
393 return A2dpStatus::OK;
394 }
395
BuildConfiguration(const std::vector<uint8_t> & remote_capabilities,const std::optional<CodecParameters> & hint,std::vector<uint8_t> * configuration) const396 bool A2dpOffloadCodecSbc::BuildConfiguration(
397 const std::vector<uint8_t>& remote_capabilities,
398 const std::optional<CodecParameters>& hint,
399 std::vector<uint8_t>* configuration) const {
400 auto& a2dp_info = info.transport.get<CodecInfo::Transport::Tag::a2dp>();
401
402 if (remote_capabilities.size() != a2dp_info.capabilities.size()) return false;
403
404 auto lcaps = A2dpBits(a2dp_info.capabilities);
405 auto rcaps = A2dpBits(remote_capabilities);
406
407 configuration->resize(a2dp_info.capabilities.size());
408 std::fill(begin(*configuration), end(*configuration), 0);
409 auto config = A2dpBits(*configuration);
410
411 /* --- Select Sampling Frequency --- */
412
413 auto sf_hint = hint ? GetSamplingFrequencyBit(hint->samplingFrequencyHz) : -1;
414
415 if (sf_hint >= 0 && lcaps.get(sf_hint) && rcaps.get(sf_hint))
416 config.set(sf_hint);
417 else if (lcaps.get(kSamplingFrequency44100) &&
418 rcaps.get(kSamplingFrequency44100))
419 config.set(kSamplingFrequency44100);
420 else if (lcaps.get(kSamplingFrequency48000) &&
421 rcaps.get(kSamplingFrequency48000))
422 config.set(kSamplingFrequency48000);
423 else
424 return false;
425
426 /* --- Select Channel Mode --- */
427
428 auto cm_hint = hint ? GetChannelModeBit(hint->channelMode) : -1;
429
430 if (cm_hint >= 0 && lcaps.get(cm_hint) && rcaps.get(cm_hint))
431 config.set(cm_hint);
432 else if (lcaps.get(kChannelModeJointStereo) &&
433 rcaps.get(kChannelModeJointStereo))
434 config.set(kChannelModeJointStereo);
435 else if (lcaps.get(kChannelModeStereo) && rcaps.get(kChannelModeStereo))
436 config.set(kChannelModeStereo);
437 else if (lcaps.get(kChannelModeDualChannel) &&
438 rcaps.get(kChannelModeDualChannel))
439 config.set(kChannelModeDualChannel);
440 else if (lcaps.get(kChannelModeMono) && rcaps.get(kChannelModeMono))
441 config.set(kChannelModeMono);
442 else
443 return false;
444
445 /* --- Select Block Length --- */
446
447 if (lcaps.get(kBlockLength16) && rcaps.get(kBlockLength16))
448 config.set(kBlockLength16);
449 else if (lcaps.get(kBlockLength12) && rcaps.get(kBlockLength12))
450 config.set(kBlockLength12);
451 else if (lcaps.get(kBlockLength8) && rcaps.get(kBlockLength8))
452 config.set(kBlockLength8);
453 else if (lcaps.get(kBlockLength4) && rcaps.get(kBlockLength4))
454 config.set(kBlockLength4);
455 else
456 return false;
457
458 /* --- Select Subbands --- */
459
460 if (lcaps.get(kSubbands8) && rcaps.get(kSubbands8))
461 config.set(kSubbands8);
462 else if (lcaps.get(kSubbands4) && rcaps.get(kSubbands4))
463 config.set(kSubbands4);
464 else
465 return false;
466
467 /* --- Select Allocation method --- */
468
469 if (lcaps.get(kAllocationMethodLoudness) &&
470 rcaps.get(kAllocationMethodLoudness))
471 config.set(kAllocationMethodLoudness);
472 else if (lcaps.get(kAllocationMethodSnr) && rcaps.get(kAllocationMethodSnr))
473 config.set(kAllocationMethodSnr);
474 else
475 return false;
476
477 /* --- Select Bitpool --- */
478
479 uint8_t min_bitpool = rcaps.get(kMinimumBitpool);
480 uint8_t max_bitpool = rcaps.get(kMaximumBitpool);
481
482 if (min_bitpool < 2 || min_bitpool > 250 || max_bitpool < 2 ||
483 max_bitpool > 250 || min_bitpool > max_bitpool) {
484 min_bitpool = 2;
485 max_bitpool = 250;
486 }
487
488 min_bitpool = std::max(min_bitpool, uint8_t(lcaps.get(kMinimumBitpool)));
489 max_bitpool = std::max(max_bitpool, uint8_t(lcaps.get(kMaximumBitpool)));
490
491 if (hint) {
492 min_bitpool =
493 std::max(min_bitpool, GetBitpool(*configuration, hint->minBitrate));
494 if (hint->maxBitrate && hint->maxBitrate >= hint->minBitrate)
495 max_bitpool =
496 std::min(max_bitpool, GetBitpool(*configuration, hint->maxBitrate));
497 }
498
499 config.set(kMinimumBitpool, min_bitpool);
500 config.set(kMaximumBitpool, max_bitpool);
501
502 return true;
503 }
504
505 } // namespace aidl::android::hardware::bluetooth::audio
506