diff options
| -rw-r--r-- | flags/leaudio.aconfig | 7 | ||||
| -rw-r--r-- | system/bta/le_audio/le_audio_types.h | 34 | ||||
| -rw-r--r-- | system/bta/le_audio/le_audio_types_test.cc | 105 |
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 |