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

Commit 5413a91f authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "LeAudio: Configuration provider dependency inversion - Part 1" into main

parents d391a6da 4307070f
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