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

Commit 6b7f1e4c authored by Jakub Pawlowski's avatar Jakub Pawlowski Committed by Gerrit Code Review
Browse files

Merge "LC3 encoder integration"

parents 1f229fba 02d57e6f
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