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

Commit 4307070f authored by Jakub Tyszkowski's avatar Jakub Tyszkowski
Browse files

LeAudio: Configuration provider dependency inversion - Part 1

Part1: Move broadcast configurations to Codec Manager

Codec manager should be the only entry point for the BAP code, which in
turn should not care for the codec location and from where the
configurations are provided.

This is part of the refactors preparing the code base for the multi-codec
support.

Bug: 308428860
Bug: 295972694
Test: atest --host bluetooth_le_audio_test bluetooth_le_audio_client_test bluetooth_test_broadcaster bluetooth_test_broadcaster_state_machine bluetooth_le_audio_codec_manager_test
Flag: EXEMPT; refactor for the multicodec support - verified with unit tests and manual testing
Change-Id: Ibfe28cba5419d92af41ede4117a1f7d72dbbc8c4
parent 921bacb2
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -99,6 +99,7 @@ cc_library_static {
        "hh/bta_hh_utils.cc",
        "le_audio/audio_hal_client/audio_sink_hal_client.cc",
        "le_audio/audio_hal_client/audio_source_hal_client.cc",
        "le_audio/broadcaster/broadcast_configuration_provider.cc",
        "le_audio/broadcaster/broadcaster.cc",
        "le_audio/broadcaster/broadcaster_types.cc",
        "le_audio/broadcaster/state_machine.cc",
@@ -775,6 +776,7 @@ cc_test {
        ":TestMockBtaLeAudioHalVerifier",
        ":TestMockLegacyHciInterface",
        ":TestStubOsi",
        "le_audio/broadcaster/broadcast_configuration_provider.cc",
        "le_audio/codec_manager.cc",
        "le_audio/codec_manager_test.cc",
        "le_audio/le_audio_set_configuration_provider_json.cc",
@@ -856,6 +858,8 @@ cc_test {
        "le_audio/audio_hal_client/audio_hal_client_test.cc",
        "le_audio/audio_hal_client/audio_sink_hal_client.cc",
        "le_audio/audio_hal_client/audio_source_hal_client.cc",
        "le_audio/broadcaster/broadcast_configuration_provider.cc",
        "le_audio/broadcaster/broadcaster_types.cc",
        "le_audio/client_parser.cc",
        "le_audio/client_parser_test.cc",
        "le_audio/content_control_id_keeper.cc",
@@ -950,6 +954,8 @@ cc_test {
        ":TestStubOsi",
        "gatt/database.cc",
        "gatt/database_builder.cc",
        "le_audio/broadcaster/broadcast_configuration_provider.cc",
        "le_audio/broadcaster/broadcaster_types.cc",
        "le_audio/client.cc",
        "le_audio/client_parser.cc",
        "le_audio/content_control_id_keeper.cc",
@@ -1061,6 +1067,7 @@ cc_test {
        ":TestCommonStackConfig",
        ":TestMockMainShim",
        ":TestMockStackBtmIso",
        "le_audio/broadcaster/broadcast_configuration_provider.cc",
        "le_audio/broadcaster/broadcaster_types.cc",
        "le_audio/broadcaster/state_machine.cc",
        "le_audio/broadcaster/state_machine_test.cc",
+1 −0
Original line number Diff line number Diff line
@@ -91,6 +91,7 @@ static_library("bta") {
    "jv/bta_jv_cfg.cc",
    "le_audio/audio_hal_client/audio_sink_hal_client.cc",
    "le_audio/audio_hal_client/audio_source_hal_client.cc",
    "le_audio/broadcaster/broadcast_configuration_provider.cc",
    "le_audio/broadcaster/broadcaster.cc",
    "le_audio/broadcaster/broadcaster_types.cc",
    "le_audio/broadcaster/state_machine.cc",
+67 −0
Original line number Diff line number Diff line
/*
 * Copyright 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "broadcast_configuration_provider.h"

#include "internal_include/stack_config.h"

namespace bluetooth::le_audio {
namespace broadcaster {
/* Software codec configuration provider */
BroadcastConfiguration GetBroadcastConfig(
    const std::vector<std::pair<types::LeAudioContextType, uint8_t>>&
        subgroup_quality) {
  // Select the SW codec parameters based on the first subgroup audio context
  // Note that the HW offloader may support more quality subgroups.
  // TODO: Unify the quality selection logic with GetBroadcastOffloadConfig()
  auto context = types::AudioContexts(subgroup_quality.at(0).first);

  const std::string* options =
      stack_config_get_interface()->get_pts_broadcast_audio_config_options();
  if (options) {
    if (!options->compare("lc3_stereo_48_1_2")) return lc3_stereo_48_1_2;
    if (!options->compare("lc3_stereo_48_2_2")) return lc3_stereo_48_2_2;
    if (!options->compare("lc3_stereo_48_3_2")) return lc3_stereo_48_3_2;
    if (!options->compare("lc3_stereo_48_4_2")) return lc3_stereo_48_4_2;
  }

  // High quality, Low Latency
  if (context.test_any(types::LeAudioContextType::GAME |
                       types::LeAudioContextType::LIVE))
    return lc3_stereo_24_2_1;

  // Standard quality, Low Latency
  if (context.test(types::LeAudioContextType::INSTRUCTIONAL))
    return lc3_mono_16_2_1;

  // Standard quality, High Reliability
  if (context.test_any(types::LeAudioContextType::SOUNDEFFECTS |
                       types::LeAudioContextType::UNSPECIFIED))
    return lc3_stereo_16_2_2;

  if (context.test_any(types::LeAudioContextType::ALERTS |
                       types::LeAudioContextType::NOTIFICATIONS |
                       types::LeAudioContextType::EMERGENCYALARM))
    return lc3_mono_16_2_2;

  // High quality, High Reliability
  if (context.test(types::LeAudioContextType::MEDIA)) return lc3_stereo_24_2_2;

  // Defaults: Standard quality, High Reliability
  return lc3_mono_16_2_2;
}
}  // namespace broadcaster
}  // namespace bluetooth::le_audio
 No newline at end of file
+296 −0
Original line number Diff line number Diff line
/*
 * Copyright 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#pragma once

#include "bta/le_audio/broadcaster/broadcaster_types.h"
#include "bta/le_audio/le_audio_types.h"

namespace bluetooth::le_audio {
namespace broadcaster {

constexpr types::LeAudioCodecId kLeAudioCodecIdLc3 = {
    .coding_format = types::kLeAudioCodingFormatLC3,
    .vendor_company_id = types::kLeAudioVendorCompanyIdUndefined,
    .vendor_codec_id = types::kLeAudioVendorCodecIdUndefined};

// Quality subgroup configurations
static const BroadcastSubgroupCodecConfig lc3_mono_16_2 =
    BroadcastSubgroupCodecConfig(
        kLeAudioCodecIdLc3,
        {BroadcastSubgroupBisCodecConfig{
            // num_bis
            1,
            // codec_specific
            types::LeAudioLtvMap({
                LTV_ENTRY_SAMPLING_FREQUENCY(
                    codec_spec_conf::kLeAudioSamplingFreq16000Hz),
                LTV_ENTRY_FRAME_DURATION(
                    codec_spec_conf::kLeAudioCodecFrameDur10000us),
                LTV_ENTRY_OCTETS_PER_CODEC_FRAME(40),
            }),
            // .channel_count_per_iso_stream = 1,
        }},
        // bits_per_sample
        16);

static const BroadcastSubgroupCodecConfig lc3_stereo_16_2 =
    BroadcastSubgroupCodecConfig(
        kLeAudioCodecIdLc3,
        {BroadcastSubgroupBisCodecConfig{
            // num_bis
            2,
            // codec_specific
            types::LeAudioLtvMap({
                LTV_ENTRY_SAMPLING_FREQUENCY(
                    codec_spec_conf::kLeAudioSamplingFreq16000Hz),
                LTV_ENTRY_FRAME_DURATION(
                    codec_spec_conf::kLeAudioCodecFrameDur10000us),
                LTV_ENTRY_OCTETS_PER_CODEC_FRAME(40),
            }),
            // .channel_count_per_iso_stream = 1,
        }},
        // bits_per_sample
        16);

static const BroadcastSubgroupCodecConfig lc3_stereo_24_2 =
    BroadcastSubgroupCodecConfig(
        kLeAudioCodecIdLc3,
        {BroadcastSubgroupBisCodecConfig{
            // num_bis
            2,
            // codec_specific
            types::LeAudioLtvMap({
                LTV_ENTRY_SAMPLING_FREQUENCY(
                    codec_spec_conf::kLeAudioSamplingFreq24000Hz),
                LTV_ENTRY_FRAME_DURATION(
                    codec_spec_conf::kLeAudioCodecFrameDur10000us),
                LTV_ENTRY_OCTETS_PER_CODEC_FRAME(60),
            }),
            // .channel_count_per_iso_stream = 1,
        }},
        // bits_per_sample
        16);

static const BroadcastSubgroupCodecConfig lc3_stereo_48_1 =
    BroadcastSubgroupCodecConfig(
        kLeAudioCodecIdLc3,
        {BroadcastSubgroupBisCodecConfig{
            // num_bis
            2,
            // codec_specific
            types::LeAudioLtvMap({
                LTV_ENTRY_SAMPLING_FREQUENCY(
                    codec_spec_conf::kLeAudioSamplingFreq48000Hz),
                LTV_ENTRY_FRAME_DURATION(
                    codec_spec_conf::kLeAudioCodecFrameDur7500us),
                LTV_ENTRY_OCTETS_PER_CODEC_FRAME(75),
            }),
            // .channel_count_per_iso_stream = 1,
        }},
        // bits_per_sample
        16);

static const BroadcastSubgroupCodecConfig lc3_stereo_48_2 =
    BroadcastSubgroupCodecConfig(
        kLeAudioCodecIdLc3,
        {BroadcastSubgroupBisCodecConfig{
            // num_bis
            2,
            // codec_specific
            types::LeAudioLtvMap({
                LTV_ENTRY_SAMPLING_FREQUENCY(
                    codec_spec_conf::kLeAudioSamplingFreq48000Hz),
                LTV_ENTRY_FRAME_DURATION(
                    codec_spec_conf::kLeAudioCodecFrameDur10000us),
                LTV_ENTRY_OCTETS_PER_CODEC_FRAME(100),
            }),
            // .channel_count_per_iso_stream = 1,
        }},
        // bits_per_sample
        16);

static const BroadcastSubgroupCodecConfig lc3_stereo_48_3 =
    BroadcastSubgroupCodecConfig(
        kLeAudioCodecIdLc3,
        {BroadcastSubgroupBisCodecConfig{
            // num_bis
            2,
            // codec_specific
            types::LeAudioLtvMap({
                LTV_ENTRY_SAMPLING_FREQUENCY(
                    codec_spec_conf::kLeAudioSamplingFreq48000Hz),
                LTV_ENTRY_FRAME_DURATION(
                    codec_spec_conf::kLeAudioCodecFrameDur7500us),
                LTV_ENTRY_OCTETS_PER_CODEC_FRAME(90),
            }),
            // .channel_count_per_iso_stream = 1,
        }},
        // bits_per_sample
        16);

static const BroadcastSubgroupCodecConfig lc3_stereo_48_4 =
    BroadcastSubgroupCodecConfig(
        kLeAudioCodecIdLc3,
        {BroadcastSubgroupBisCodecConfig{
            // num_bis
            2,
            // codec_specific
            types::LeAudioLtvMap({
                LTV_ENTRY_SAMPLING_FREQUENCY(
                    codec_spec_conf::kLeAudioSamplingFreq48000Hz),
                LTV_ENTRY_FRAME_DURATION(
                    codec_spec_conf::kLeAudioCodecFrameDur10000us),
                LTV_ENTRY_OCTETS_PER_CODEC_FRAME(120),
            }),
            // .channel_count_per_iso_stream = 1,
        }},
        // bits_per_sample
        16);

static const types::DataPathConfiguration lc3_data_path = {
    .dataPathId = bluetooth::hci::iso_manager::kIsoDataPathHci,
    .dataPathConfig = {},
    .isoDataPathConfig =
        {
            .codecId = kLeAudioCodecIdLc3,
            .isTransparent = true,
            .controllerDelayUs = 0x00000000,  // irrlevant for transparent mode
            .configuration = {},
        },
};

static const BroadcastQosConfig qos_config_2_10 = BroadcastQosConfig(2, 10);
static const BroadcastQosConfig qos_config_4_45 = BroadcastQosConfig(4, 45);
static const BroadcastQosConfig qos_config_4_50 = BroadcastQosConfig(4, 50);
static const BroadcastQosConfig qos_config_4_60 = BroadcastQosConfig(4, 60);
static const BroadcastQosConfig qos_config_4_65 = BroadcastQosConfig(4, 65);

// Standard single subgroup configurations
static const BroadcastConfiguration lc3_mono_16_2_1 = {
    // subgroup list, qos configuration, data path configuration
    .subgroups = {lc3_mono_16_2},
    .qos = qos_config_2_10,
    .data_path = lc3_data_path,
    .sduIntervalUs = 10000,
    .maxSduOctets = 40,
    .phy = 0x02,   // PHY_LE_2M
    .packing = 0,  // Sequential
    .framing = 0,  // Unframed
};

static const BroadcastConfiguration lc3_mono_16_2_2 = {
    // subgroup list, qos configuration, data path configuration
    .subgroups = {lc3_mono_16_2},
    .qos = qos_config_4_60,
    .data_path = lc3_data_path,
    .sduIntervalUs = 10000,
    .maxSduOctets = 40,
    .phy = 0x02,   // PHY_LE_2M
    .packing = 0,  // Sequential
    .framing = 0,  // Unframed
};

static const BroadcastConfiguration lc3_stereo_16_2_2 = {
    // subgroup list, qos configuration, data path configuration
    .subgroups = {lc3_stereo_16_2},
    .qos = qos_config_4_60,
    .data_path = lc3_data_path,
    .sduIntervalUs = 10000,
    .maxSduOctets = 80,
    .phy = 0x02,   // PHY_LE_2M
    .packing = 0,  // Sequential
    .framing = 0,  // Unframed
};

static const BroadcastConfiguration lc3_stereo_24_2_1 = {
    // subgroup list, qos configuration, data path configuration
    .subgroups = {lc3_stereo_24_2},
    .qos = qos_config_2_10,
    .data_path = lc3_data_path,
    .sduIntervalUs = 10000,
    .maxSduOctets = 120,
    .phy = 0x02,   // PHY_LE_2M
    .packing = 0,  // Sequential
    .framing = 0,  // Unframed
};

static const BroadcastConfiguration lc3_stereo_24_2_2 = {
    // subgroup list, qos configuration, data path configuration
    .subgroups = {lc3_stereo_24_2},
    .qos = qos_config_4_60,
    .data_path = lc3_data_path,
    .sduIntervalUs = 10000,
    .maxSduOctets = 120,
    .phy = 0x02,   // PHY_LE_2M
    .packing = 0,  // Sequential
    .framing = 0,  // Unframed
};

static const BroadcastConfiguration lc3_stereo_48_1_2 = {
    // subgroup list, qos configuration, data path configuration
    .subgroups = {lc3_stereo_48_1},
    .qos = qos_config_4_50,
    .data_path = lc3_data_path,
    .sduIntervalUs = 10000,
    .maxSduOctets = 150,
    .phy = 0x02,   // PHY_LE_2M
    .packing = 0,  // Sequential
    .framing = 0   // Unframed,
};

static const BroadcastConfiguration lc3_stereo_48_2_2 = {
    // subgroup list, qos configuration, data path configuration
    .subgroups = {lc3_stereo_48_2},
    .qos = qos_config_4_65,
    .data_path = lc3_data_path,
    .sduIntervalUs = 10000,
    .maxSduOctets = 200,
    .phy = 0x02,   // PHY_LE_2M
    .packing = 0,  // Sequential
    .framing = 0   // Unframed,
};

static const BroadcastConfiguration lc3_stereo_48_3_2 = {
    // subgroup list, qos configuration, data path configuration
    .subgroups = {lc3_stereo_48_3},
    .qos = qos_config_4_50,
    .data_path = lc3_data_path,
    .sduIntervalUs = 10000,
    .maxSduOctets = 180,
    .phy = 0x02,   // PHY_LE_2M
    .packing = 0,  // Sequential
    .framing = 0   // Unframed,
};

static const BroadcastConfiguration lc3_stereo_48_4_2 = {
    // subgroup list, qos configuration, data path configuration
    .subgroups = {lc3_stereo_48_4},
    .qos = qos_config_4_65,
    .data_path = lc3_data_path,
    .sduIntervalUs = 10000,
    .maxSduOctets = 240,
    .phy = 0x02,   // PHY_LE_2M
    .packing = 0,  // Sequential
    .framing = 0   // Unframed,
};

// Takes a list of subgroup requirements (audio context, quality index)
BroadcastConfiguration GetBroadcastConfig(
    const std::vector<std::pair<types::LeAudioContextType, uint8_t>>&
        subgroup_quality);

}  // namespace broadcaster
}  // namespace bluetooth::le_audio
+150 −92

File changed.

Preview size limit exceeded, changes collapsed.

Loading