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

Commit 1d1e4fc0 authored by Jakub Pawlowski's avatar Jakub Pawlowski Committed by Automerger Merge Worker
Browse files

Merge "LC3 encoder integration" am: 6b7f1e4c

Original change: https://android-review.googlesource.com/c/platform/packages/modules/Bluetooth/+/1891676

Change-Id: I64f19d75a229e40f0bb2ff16eefadfd96c0f50a6
parents 969695ed 6b7f1e4c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -514,6 +514,7 @@ cc_test {
        "libbt-protos-lite",
        "libosi",
        "liblc3codec",
        "liblc3encoder",
    ],
    sanitize: {
        cfi: true,
+143 −40
Original line number Diff line number Diff line
@@ -33,9 +33,11 @@
#include "devices.h"
#include "embdrv/lc3/Api/Lc3Decoder.hpp"
#include "embdrv/lc3/Api/Lc3Encoder.hpp"
#include "embdrv/lc3_enc/include/lc3.h"
#include "gatt/bta_gattc_int.h"
#include "le_audio_types.h"
#include "osi/include/osi.h"
#include "osi/include/properties.h"
#include "stack/btm/btm_dev.h"
#include "stack/btm/btm_sec.h"
#include "stack/include/btu.h"  // do_in_main_thread
@@ -84,6 +86,8 @@ CigCallbacks* stateMachineHciCallbacks;
LeAudioGroupStateMachine::Callbacks* stateMachineCallbacks;
DeviceGroupsCallbacks* device_group_callbacks;

bool use_new_encoder = true;

/*
 * Coordinatet Set Identification Profile (CSIP) based on CSIP 1.0
 * and Coordinatet Set Identification Service (CSIS) 1.0
@@ -131,6 +135,8 @@ class LeAudioClientImpl : public LeAudioClient {
        audio_source_ready_to_send(false),
        current_source_codec_config({0, 0, 0, 0}),
        current_sink_codec_config({0, 0, 0, 0}),
        lc3_encoder_left_mem(nullptr),
        lc3_encoder_right_mem(nullptr),
        lc3_encoder(nullptr),
        lc3_decoder(nullptr),
        audio_source_instance_(nullptr),
@@ -1738,7 +1744,15 @@ class LeAudioClientImpl : public LeAudioClient {
                                 std::vector<int16_t>& chan_left,
                                 std::vector<int16_t>& chan_right,
                                 bool prepare_mono = false) {
    uint16_t num_of_frames_per_ch = lc3_encoder->lc3Config.NF;
    uint16_t num_of_frames_per_ch;

    if (use_new_encoder) {
      int dt_us = current_source_codec_config.data_interval_us;
      int sr_hz = current_source_codec_config.sample_rate;
      num_of_frames_per_ch = lc3_frame_samples(dt_us, sr_hz);
    } else {
      num_of_frames_per_ch = lc3_encoder->lc3Config.NF;
    }

    chan_left.reserve(num_of_frames_per_ch);
    chan_right.reserve(num_of_frames_per_ch);
@@ -1767,7 +1781,15 @@ class LeAudioClientImpl : public LeAudioClient {
    uint16_t byte_count = stream_conf->sink_octets_per_codec_frame;
    uint16_t left_cis_handle = 0;
    uint16_t right_cis_handle = 0;
    uint16_t number_of_required_samples_per_channel = lc3_encoder->lc3Config.NF;
    uint16_t number_of_required_samples_per_channel;

    if (use_new_encoder) {
      int dt_us = current_source_codec_config.data_interval_us;
      int sr_hz = current_source_codec_config.sample_rate;
      number_of_required_samples_per_channel = lc3_frame_samples(dt_us, sr_hz);
    } else {
      number_of_required_samples_per_channel = lc3_encoder->lc3Config.NF;
    }

    for (auto [cis_handle, audio_location] : stream_conf->sink_streams) {
      if (audio_location & le_audio::codec_spec_conf::kLeAudioLocationAnyLeft)
@@ -1782,21 +1804,42 @@ class LeAudioClientImpl : public LeAudioClient {
      return;
    }

    std::vector<uint8_t> chan_left_enc(byte_count, 0);
    std::vector<uint8_t> chan_right_enc(byte_count, 0);

    bool mono = (left_cis_handle == 0) || (right_cis_handle == 0);

    if (!mono && use_new_encoder) {
      lc3_encode(lc3_encoder_left, (const int16_t*)data.data(), 2,
                 chan_left_enc.data(), chan_left_enc.size());
      lc3_encode(lc3_encoder_right, ((const int16_t*)data.data()) + 1, 2,
                 chan_right_enc.data(), chan_right_enc.size());
    } else {
      std::vector<int16_t> chan_left;
      std::vector<int16_t> chan_right;
      get_left_and_right_stream(data, chan_left, chan_right, mono);

    std::vector<uint8_t> chan_left_enc(byte_count, 0);
    std::vector<uint8_t> chan_right_enc(byte_count, 0);

      uint8_t err = 0;
    if (left_cis_handle)
      if (left_cis_handle) {
        if (use_new_encoder) {
          lc3_encode(lc3_encoder_left, (const int16_t*)chan_left.data(), 1,
                     chan_left_enc.data(), chan_left_enc.size());
        } else {
          err |= lc3_encoder->run((const int16_t*)chan_left.data(),
                                  chan_left_enc.size(), chan_left_enc.data(), 0);
    if (right_cis_handle)
        }
      }

      if (right_cis_handle) {
        if (use_new_encoder) {
          lc3_encode(lc3_encoder_right, (const int16_t*)chan_right.data(), 1,
                     chan_right_enc.data(), chan_right_enc.size());

        } else {
          err |= lc3_encoder->run((const int16_t*)chan_right.data(),
                                  chan_right_enc.size(), chan_right_enc.data(), 1);
        }
      }

      if (err != Lc3Encoder::ERROR_FREE) {
        LOG(ERROR) << " error while encoding; error code: "
@@ -1804,6 +1847,7 @@ class LeAudioClientImpl : public LeAudioClient {
                   << "\t err: " << static_cast<uint8_t>(err);
        return;
      }
    }

    /* Send data to the controller */
    if (left_cis_handle)
@@ -1818,34 +1862,55 @@ class LeAudioClientImpl : public LeAudioClient {
  void PrepareAndSendToSingleDevice(
      const std::vector<uint8_t>& data,
      struct le_audio::stream_configuration* stream_conf) {
    int num_channels = lc3_encoder->lc3Config.Nc;
    int num_channels = current_source_codec_config.num_channels;
    uint16_t byte_count = stream_conf->sink_octets_per_codec_frame;
    auto cis_handle = stream_conf->sink_streams.front().first;
    uint16_t number_of_required_samples_per_channel = lc3_encoder->lc3Config.NF;
    uint16_t number_of_required_samples_per_channel;

    if (use_new_encoder) {
      int dt_us = current_source_codec_config.data_interval_us;
      int sr_hz = current_source_codec_config.sample_rate;
      number_of_required_samples_per_channel = lc3_frame_samples(dt_us, sr_hz);
    } else {
      number_of_required_samples_per_channel = lc3_encoder->lc3Config.NF;
    }

    if ((int)data.size() < (2 /* bytes per sample */ * num_channels *
                            number_of_required_samples_per_channel)) {
      LOG(ERROR) << __func__ << "Missing samples";
      return;
    }

    std::vector<uint8_t> chan_encoded(num_channels * byte_count, 0);
    uint8_t err = 0;
    if (num_channels == 1) {
      if (use_new_encoder) {
        lc3_encode(lc3_encoder_left, (const int16_t*)data.data(), 1,
                   chan_encoded.data(), byte_count);
      } else {
        err = lc3_encoder->run((const int16_t*)data.data(), byte_count,
                               chan_encoded.data(), 0);

      }
    } else {
      std::vector<int16_t> chan_left;
      std::vector<int16_t> chan_right;
      get_left_and_right_stream(data, chan_left, chan_right, false);

      if (use_new_encoder) {
        lc3_encode(lc3_encoder_left, (const int16_t*)chan_left.data(), 1,
                   chan_encoded.data(), byte_count);
      } else {
        err |= lc3_encoder->run((const int16_t*)chan_left.data(), byte_count,
                                chan_encoded.data(), 0);
      }

      if (use_new_encoder) {
        lc3_encode(lc3_encoder_right, (const int16_t*)chan_right.data(), 1,
                   chan_encoded.data() + byte_count, byte_count);
      } else {
        err |= lc3_encoder->run((const int16_t*)chan_right.data(), byte_count,
                                chan_encoded.data() + byte_count, 1);
      }
    }

    if (err != Lc3Encoder::ERROR_FREE) {
      LOG(ERROR) << " error while encoding; error code: "
@@ -2023,6 +2088,26 @@ class LeAudioClientImpl : public LeAudioClient {
      return false;
    }

    if (use_new_encoder) {
      if (lc3_encoder_left_mem) {
        LOG(WARNING)
            << " The encoder instance should have been already released.";
        free(lc3_encoder_left_mem);
        lc3_encoder_left_mem = nullptr;
        free(lc3_encoder_right_mem);
        lc3_encoder_right_mem = nullptr;
      }
      int dt_us = current_source_codec_config.data_interval_us;
      int sr_hz = current_source_codec_config.sample_rate;
      unsigned enc_size = lc3_encoder_size(dt_us, sr_hz);

      lc3_encoder_left_mem = malloc(enc_size);
      lc3_encoder_right_mem = malloc(enc_size);

      lc3_encoder_left = lc3_setup_encoder(dt_us, sr_hz, lc3_encoder_left_mem);
      lc3_encoder_right = lc3_setup_encoder(dt_us, sr_hz, lc3_encoder_right_mem);

    } else {
      if (lc3_encoder) {
        LOG(WARNING)
            << " The encoder instance should have been already released.";
@@ -2035,6 +2120,7 @@ class LeAudioClientImpl : public LeAudioClient {
          current_source_codec_config.sample_rate,
          Lc3ConfigFrameDuration(current_source_codec_config.data_interval_us),
          current_source_codec_config.num_channels));
    }

    uint16_t remote_delay_ms =
        group->GetRemoteDelay(le_audio::types::kLeAudioDirectionSink);
@@ -2116,6 +2202,13 @@ class LeAudioClientImpl : public LeAudioClient {
    audio_sink_ready_to_receive = false;
    audio_source_ready_to_send = false;

    if (lc3_encoder_left_mem) {
      free(lc3_encoder_left_mem);
      lc3_encoder_left_mem = nullptr;
      free(lc3_encoder_right_mem);
      lc3_encoder_right_mem = nullptr;
    }

    if (lc3_encoder) {
      delete lc3_encoder;
      lc3_encoder = nullptr;
@@ -2682,6 +2775,13 @@ class LeAudioClientImpl : public LeAudioClient {

  LeAudioCodecConfiguration current_source_codec_config;
  LeAudioCodecConfiguration current_sink_codec_config;

  void* lc3_encoder_left_mem;
  void* lc3_encoder_right_mem;

  lc3_encoder_t lc3_encoder_left;
  lc3_encoder_t lc3_encoder_right;

  Lc3Encoder* lc3_encoder;
  Lc3Decoder* lc3_decoder;
  std::vector<uint8_t> encoded_data;
@@ -2914,6 +3014,9 @@ void LeAudioClient::Initialize(
      << ", LE Audio Client requires Bluetooth Audio HAL V2.1 at least. Either "
         "disable LE Audio Profile, or update your HAL";

  use_new_encoder = osi_property_get_bool("persist.bluetooth.use_new_lc3", true);
  LOG(INFO) << "use_new_encoder = " << +use_new_encoder;

  IsoManager::GetInstance()->Start();

  audioSinkReceiver = &audioSinkReceiverImpl;
+1 −0
Original line number Diff line number Diff line
@@ -244,6 +244,7 @@ cc_test {
        "libFraunhoferAAC",
        "libg722codec",
        "liblc3codec",
        "liblc3encoder",
        "libbtdevice",
        "libbt-hci",
        "libudrv-uipc",
+48 −0
Original line number Diff line number Diff line
package {
    // See: http://go/android-license-faq
    // A large-scale-change added 'default_applicable_licenses' to import
    // all of the 'license_kinds' from "system_bt_license"
    // to get the below license kinds:
    //   SPDX-license-identifier-Apache-2.0
    default_applicable_licenses: ["system_bt_license"],
}

cc_library_static {
    name: "liblc3encoder",
    host_supported: true,
    apex_available: [

        "//apex_available:platform",
        "com.android.bluetooth.updatable"
    ],
    defaults: ["fluoride_defaults"],
    srcs: [
        "src/*.c",
    ],
    cflags: [
        "-O3",
        "-ffast-math",
        "-Werror",
        "-Wmissing-braces",
        "-Wno-unused-parameter",
        "-Wno-#warnings",
        "-Wuninitialized",
        "-Wno-self-assign",
        "-Wno-implicit-fallthrough",
    ],
    target: {
       android: {
            sanitize: {
                misc_undefined:[
                   "unsigned-integer-overflow",
                   "signed-integer-overflow",
                   "bounds",
                ],
                cfi: true,
            },
       },
    },
    export_include_dirs: [
        "include",
    ],
}
+1 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ rust_binary_host {
        "libFraunhoferAAC",
        "libg722codec",
        "liblc3codec",
        "liblc3encoder",
        "libudrv-uipc",
        "libbluetooth_gd", // Gabeldorsche
        "libbluetooth-dumpsys",
Loading