summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--flags/leaudio.aconfig7
-rw-r--r--system/bta/le_audio/le_audio_types.h34
-rw-r--r--system/bta/le_audio/le_audio_types_test.cc105
3 files changed, 145 insertions, 1 deletions
diff --git a/flags/leaudio.aconfig b/flags/leaudio.aconfig
index 3d9d835179..639d5fcef2 100644
--- a/flags/leaudio.aconfig
+++ b/flags/leaudio.aconfig
@@ -384,3 +384,10 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "leaudio_set_codec_config_preference"
+ namespace: "bluetooth"
+ description: "New apis to set codec config preference"
+ bug: "353909820"
+}
diff --git a/system/bta/le_audio/le_audio_types.h b/system/bta/le_audio/le_audio_types.h
index 9e9b7ababa..aa6eaa6285 100644
--- a/system/bta/le_audio/le_audio_types.h
+++ b/system/bta/le_audio/le_audio_types.h
@@ -25,6 +25,7 @@
#include <bluetooth/log.h>
#include <stdint.h>
+#include <bit>
#include <bitset>
#include <map>
#include <optional>
@@ -100,6 +101,25 @@ static const bluetooth::Uuid kTelephonyMediaAudioProfileRoleCharacteristicUuid =
} // namespace uuid
namespace codec_spec_conf {
+constexpr uint8_t SingleCapaToConfigHelper(uint16_t single_capability, uint8_t offset = 0) {
+ if (!single_capability || std::popcount(single_capability) > 1) {
+ return 0;
+ }
+ return std::countr_zero(single_capability) + offset;
+}
+
+constexpr uint8_t SingleSamplingFreqCapability2Config(uint16_t single_capability) {
+ return SingleCapaToConfigHelper(single_capability, 1);
+}
+
+constexpr uint8_t SingleFrameDurationCapability2Config(uint16_t single_capability) {
+ return SingleCapaToConfigHelper(single_capability);
+}
+
+constexpr uint8_t SingleChannelCountCapability2Config(uint16_t single_capability) {
+ return SingleCapaToConfigHelper(single_capability, 1);
+}
+
/* LTV Types */
constexpr uint8_t kLeAudioLtvTypeSamplingFreq = 0x01;
constexpr uint8_t kLeAudioLtvTypeFrameDuration = 0x02;
@@ -185,10 +205,22 @@ constexpr uint16_t kLeAudioCodecFrameLen120 = 120;
constexpr uint8_t kInvalidCisId = 0xFF;
namespace codec_spec_caps {
-uint16_t constexpr SamplingFreqConfig2Capability(uint8_t conf) { return 1 << (conf - 1); }
+uint16_t constexpr SamplingFreqConfig2Capability(uint8_t conf) {
+ if (!conf) {
+ return 0;
+ }
+ return 0x01 << (conf - 1);
+}
uint8_t constexpr FrameDurationConfig2Capability(uint8_t conf) { return 0x01 << (conf); }
+uint16_t constexpr ChannelCountConfig2Capability(uint8_t conf) {
+ if (!conf) {
+ return 0;
+ }
+ return 0x01 << (conf - 1);
+}
+
/* LTV Types - same values as in Codec Specific Configurations but 0x03 is
* named differently.
*/
diff --git a/system/bta/le_audio/le_audio_types_test.cc b/system/bta/le_audio/le_audio_types_test.cc
index 93dee03cc3..f46da64e26 100644
--- a/system/bta/le_audio/le_audio_types_test.cc
+++ b/system/bta/le_audio/le_audio_types_test.cc
@@ -717,5 +717,110 @@ TEST(CodecConfigSettingTest, test_vendor_codec_type) {
ASSERT_EQ(vendor_16_2, vendor_codec);
}
+TEST(CodecSpecTest, test_sampling_frequency_transition) {
+ ASSERT_EQ(codec_spec_conf::SingleSamplingFreqCapability2Config(
+ codec_spec_caps::SamplingFreqConfig2Capability(
+ codec_spec_conf::kLeAudioSamplingFreq8000Hz)),
+ codec_spec_conf::kLeAudioSamplingFreq8000Hz);
+ ASSERT_EQ(codec_spec_conf::SingleSamplingFreqCapability2Config(
+ codec_spec_caps::SamplingFreqConfig2Capability(
+ codec_spec_conf::kLeAudioSamplingFreq11025Hz)),
+ codec_spec_conf::kLeAudioSamplingFreq11025Hz);
+ ASSERT_EQ(codec_spec_conf::SingleSamplingFreqCapability2Config(
+ codec_spec_caps::SamplingFreqConfig2Capability(
+ codec_spec_conf::kLeAudioSamplingFreq16000Hz)),
+ codec_spec_conf::kLeAudioSamplingFreq16000Hz);
+ ASSERT_EQ(codec_spec_conf::SingleSamplingFreqCapability2Config(
+ codec_spec_caps::SamplingFreqConfig2Capability(
+ codec_spec_conf::kLeAudioSamplingFreq22050Hz)),
+ codec_spec_conf::kLeAudioSamplingFreq22050Hz);
+ ASSERT_EQ(codec_spec_conf::SingleSamplingFreqCapability2Config(
+ codec_spec_caps::SamplingFreqConfig2Capability(
+ codec_spec_conf::kLeAudioSamplingFreq24000Hz)),
+ codec_spec_conf::kLeAudioSamplingFreq24000Hz);
+ ASSERT_EQ(codec_spec_conf::SingleSamplingFreqCapability2Config(
+ codec_spec_caps::SamplingFreqConfig2Capability(
+ codec_spec_conf::kLeAudioSamplingFreq32000Hz)),
+ codec_spec_conf::kLeAudioSamplingFreq32000Hz);
+ ASSERT_EQ(codec_spec_conf::SingleSamplingFreqCapability2Config(
+ codec_spec_caps::SamplingFreqConfig2Capability(
+ codec_spec_conf::kLeAudioSamplingFreq44100Hz)),
+ codec_spec_conf::kLeAudioSamplingFreq44100Hz);
+ ASSERT_EQ(codec_spec_conf::SingleSamplingFreqCapability2Config(
+ codec_spec_caps::SamplingFreqConfig2Capability(
+ codec_spec_conf::kLeAudioSamplingFreq48000Hz)),
+ codec_spec_conf::kLeAudioSamplingFreq48000Hz);
+ ASSERT_EQ(codec_spec_conf::SingleSamplingFreqCapability2Config(
+ codec_spec_caps::SamplingFreqConfig2Capability(
+ codec_spec_conf::kLeAudioSamplingFreq88200Hz)),
+ codec_spec_conf::kLeAudioSamplingFreq88200Hz);
+ ASSERT_EQ(codec_spec_conf::SingleSamplingFreqCapability2Config(
+ codec_spec_caps::SamplingFreqConfig2Capability(
+ codec_spec_conf::kLeAudioSamplingFreq96000Hz)),
+ codec_spec_conf::kLeAudioSamplingFreq96000Hz);
+ ASSERT_EQ(codec_spec_conf::SingleSamplingFreqCapability2Config(
+ codec_spec_caps::SamplingFreqConfig2Capability(
+ codec_spec_conf::kLeAudioSamplingFreq176400Hz)),
+ codec_spec_conf::kLeAudioSamplingFreq176400Hz);
+ ASSERT_EQ(codec_spec_conf::SingleSamplingFreqCapability2Config(
+ codec_spec_caps::SamplingFreqConfig2Capability(
+ codec_spec_conf::kLeAudioSamplingFreq192000Hz)),
+ codec_spec_conf::kLeAudioSamplingFreq192000Hz);
+ ASSERT_EQ(codec_spec_conf::SingleSamplingFreqCapability2Config(
+ codec_spec_caps::SamplingFreqConfig2Capability(
+ codec_spec_conf::kLeAudioSamplingFreq384000Hz)),
+ codec_spec_conf::kLeAudioSamplingFreq384000Hz);
+}
+
+TEST(CodecSpecTest, test_frame_duration_transition) {
+ ASSERT_EQ(codec_spec_conf::SingleFrameDurationCapability2Config(
+ codec_spec_caps::FrameDurationConfig2Capability(
+ codec_spec_conf::kLeAudioCodecFrameDur7500us)),
+ codec_spec_conf::kLeAudioCodecFrameDur7500us);
+ ASSERT_EQ(codec_spec_conf::SingleFrameDurationCapability2Config(
+ codec_spec_caps::FrameDurationConfig2Capability(
+ codec_spec_conf::kLeAudioCodecFrameDur10000us)),
+ codec_spec_conf::kLeAudioCodecFrameDur10000us);
+}
+
+TEST(CodecSpecTest, test_channel_count_transition) {
+ ASSERT_EQ(codec_spec_caps::ChannelCountConfig2Capability(
+ codec_spec_conf::SingleChannelCountCapability2Config(
+ codec_spec_caps::kLeAudioCodecChannelCountNone)),
+ codec_spec_caps::kLeAudioCodecChannelCountNone);
+ ASSERT_EQ(codec_spec_caps::ChannelCountConfig2Capability(
+ codec_spec_conf::SingleChannelCountCapability2Config(
+ codec_spec_caps::kLeAudioCodecChannelCountSingleChannel)),
+ codec_spec_caps::kLeAudioCodecChannelCountSingleChannel);
+ ASSERT_EQ(codec_spec_caps::ChannelCountConfig2Capability(
+ codec_spec_conf::SingleChannelCountCapability2Config(
+ codec_spec_caps::kLeAudioCodecChannelCountTwoChannel)),
+ codec_spec_caps::kLeAudioCodecChannelCountTwoChannel);
+ ASSERT_EQ(codec_spec_caps::ChannelCountConfig2Capability(
+ codec_spec_conf::SingleChannelCountCapability2Config(
+ codec_spec_caps::kLeAudioCodecChannelCountThreeChannel)),
+ codec_spec_caps::kLeAudioCodecChannelCountThreeChannel);
+ ASSERT_EQ(codec_spec_caps::ChannelCountConfig2Capability(
+ codec_spec_conf::SingleChannelCountCapability2Config(
+ codec_spec_caps::kLeAudioCodecChannelCountFourChannel)),
+ codec_spec_caps::kLeAudioCodecChannelCountFourChannel);
+ ASSERT_EQ(codec_spec_caps::ChannelCountConfig2Capability(
+ codec_spec_conf::SingleChannelCountCapability2Config(
+ codec_spec_caps::kLeAudioCodecChannelCountFiveChannel)),
+ codec_spec_caps::kLeAudioCodecChannelCountFiveChannel);
+ ASSERT_EQ(codec_spec_caps::ChannelCountConfig2Capability(
+ codec_spec_conf::SingleChannelCountCapability2Config(
+ codec_spec_caps::kLeAudioCodecChannelCountSixChannel)),
+ codec_spec_caps::kLeAudioCodecChannelCountSixChannel);
+ ASSERT_EQ(codec_spec_caps::ChannelCountConfig2Capability(
+ codec_spec_conf::SingleChannelCountCapability2Config(
+ codec_spec_caps::kLeAudioCodecChannelCountSevenChannel)),
+ codec_spec_caps::kLeAudioCodecChannelCountSevenChannel);
+ ASSERT_EQ(codec_spec_caps::ChannelCountConfig2Capability(
+ codec_spec_conf::SingleChannelCountCapability2Config(
+ codec_spec_caps::kLeAudioCodecChannelCountEightChannel)),
+ codec_spec_caps::kLeAudioCodecChannelCountEightChannel);
+}
+
} // namespace types
} // namespace bluetooth::le_audio