Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c68d8df5 authored by shihchienc's avatar shihchienc
Browse files

leaudio: add transition betwen config and capability

We already have some transition functions from capability to config.
Adding more supported transition functions to help us when transition
between config and capability such as sampling frequency, frame
duration, and channel count.

Bug: 259191520
Flag: Exempt, no functional change. Regression tested with unittests
Test: atest bluetooth_le_audio_test bluetooth_le_audio_client_test
Change-Id: Iee8b54add8dfce154faf9bcc4c7e463bd2008fc6
parent 0ed8ea93
Loading
Loading
Loading
Loading
+33 −1
Original line number Diff line number Diff line
@@ -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.
 */
+105 −0
Original line number Diff line number Diff line
@@ -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