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

Commit 765350a5 authored by Jakub Pawłowski's avatar Jakub Pawłowski Committed by Gerrit Code Review
Browse files

Merge changes I3d455f0f,If91239d1

* changes:
  Use new LC3 encoder API
  Merge LC3 fixes and improvements
parents 62582e25 7b4e2c73
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -542,7 +542,7 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {

        encoders_mem_.emplace_back(malloc(encoder_bytes), &std::free);
        encoders_.emplace_back(
            lc3_setup_encoder(dt_us, sr_hz, encoders_mem_.back().get()));
            lc3_setup_encoder(dt_us, sr_hz, 0, encoders_mem_.back().get()));
      }
    }

+36 −43
Original line number Diff line number Diff line
@@ -1820,8 +1820,8 @@ class LeAudioClientImpl : public LeAudioClient {
    uint16_t num_of_frames_per_ch;

    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);
    int af_hz = audio_framework_source_config.sample_rate;
    num_of_frames_per_ch = lc3_frame_samples(dt_us, af_hz);

    chan_mono.reserve(num_of_frames_per_ch);
    for (int i = 0; i < pitch * num_of_frames_per_ch; i += pitch) {
@@ -1847,8 +1847,8 @@ class LeAudioClientImpl : public LeAudioClient {
    uint16_t number_of_required_samples_per_channel;

    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);
    int af_hz = audio_framework_source_config.sample_rate;
    number_of_required_samples_per_channel = lc3_frame_samples(dt_us, af_hz);

    for (auto [cis_handle, audio_location] : stream_conf->sink_streams) {
      if (audio_location & le_audio::codec_spec_conf::kLeAudioLocationAnyLeft)
@@ -1870,22 +1870,16 @@ class LeAudioClientImpl : public LeAudioClient {

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

    int af_hz = audio_framework_source_config.sample_rate;
    LOG_ASSERT(af_hz >= sr_hz) << __func__ << " sample freq issue";

    int pitch = af_hz / sr_hz;

    LOG(INFO) << __func__ << " pitch " << pitch
              << " data size: " << (int)data.size()
    LOG(INFO) << __func__ << " data size: " << (int)data.size()
              << " byte count: " << byte_count << " mono: " << mono;
    if (!mono) {
      lc3_encode(lc3_encoder_left, (const int16_t*)data.data(), 2 * pitch,
      lc3_encode(lc3_encoder_left, (const int16_t*)data.data(), 2,
                 chan_left_enc.size(), chan_left_enc.data());
      lc3_encode(lc3_encoder_right, ((const int16_t*)data.data()) + 1,
                 2 * pitch, chan_right_enc.size(), chan_right_enc.data());
      lc3_encode(lc3_encoder_right, ((const int16_t*)data.data()) + 1, 2,
                 chan_right_enc.size(), chan_right_enc.data());
    } else {
      std::vector<int16_t> chan_mono;
      get_mono_stream(data, chan_mono, pitch);
      get_mono_stream(data, chan_mono);

      if (left_cis_handle) {
        lc3_encode(lc3_encoder_left, (const int16_t*)chan_mono.data(), 1,
@@ -1919,8 +1913,8 @@ class LeAudioClientImpl : public LeAudioClient {
    uint16_t number_of_required_samples_per_channel;

    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);
    int af_hz = audio_framework_source_config.sample_rate;
    number_of_required_samples_per_channel = lc3_frame_samples(dt_us, af_hz);

    if ((int)data.size() < (2 /* bytes per sample */ * num_channels *
                            number_of_required_samples_per_channel)) {
@@ -1929,24 +1923,22 @@ class LeAudioClientImpl : public LeAudioClient {
    }
    std::vector<uint8_t> chan_encoded(num_channels * byte_count, 0);

    int af_hz = audio_framework_source_config.sample_rate;
    LOG_ASSERT(af_hz >= sr_hz) << __func__ << " sample freq issue";

    int pitch = af_hz / sr_hz;

    if (num_channels == 1) {
      /* Since we always get two channels from framework, lets make it mono here
       */
      std::vector<int16_t> chan_mono;
      get_mono_stream(data, chan_mono, pitch);
      get_mono_stream(data, chan_mono);

      lc3_encode(lc3_encoder_left, (const int16_t*)chan_mono.data(), 1,
                 byte_count, chan_encoded.data());
      auto err = lc3_encode(lc3_encoder_left, (const int16_t*)chan_mono.data(),
                            1, byte_count, chan_encoded.data());

      if (err < 0) {
        LOG(ERROR) << " error while encoding, error code: " << +err;
      }
    } else {
      lc3_encode(lc3_encoder_left, (const int16_t*)data.data(), 2 * pitch,
                 byte_count, chan_encoded.data());
      lc3_encode(lc3_encoder_right, (const int16_t*)data.data() + 1, 2 * pitch,
      lc3_encode(lc3_encoder_left, (const int16_t*)data.data(), 2, byte_count,
                 chan_encoded.data());
      lc3_encode(lc3_encoder_right, (const int16_t*)data.data() + 1, 2,
                 byte_count, chan_encoded.data() + byte_count);
    }

@@ -2088,23 +2080,19 @@ class LeAudioClientImpl : public LeAudioClient {
    }

    int dt_us = current_sink_codec_config.data_interval_us;
    int sr_hz = current_sink_codec_config.sample_rate;
    int af_hz = audio_framework_sink_config.sample_rate;
    LOG_ASSERT(af_hz >= sr_hz) << __func__ << " sample freq issue";

    int pitch = af_hz / sr_hz;

    int pcm_size;
    if (dt_us == 10000) {
      if (sr_hz == 44100)
      if (af_hz == 44100)
        pcm_size = 480;
      else
        pcm_size = sr_hz / 100;
        pcm_size = af_hz / 100;
    } else if (dt_us == 7500) {
      if (sr_hz == 44100)
      if (af_hz == 44100)
        pcm_size = 360;
      else
        pcm_size = (sr_hz * 3) / 400;
        pcm_size = (af_hz * 3) / 400;
    } else {
      LOG(ERROR) << "BAD dt_us: " << dt_us;
      return;
@@ -2112,8 +2100,8 @@ class LeAudioClientImpl : public LeAudioClient {

    std::vector<int16_t> pcm_data_decoded(pcm_size, 0);

    auto err =
        lc3_decode(lc3_decoder, data, size, pcm_data_decoded.data(), pitch);
    auto err = lc3_decode(lc3_decoder, data, size, pcm_data_decoded.data(),
                          1 /* pitch */);

    /* TODO: How handle failing decoding ? */
    if (err < 0) {
@@ -2159,14 +2147,17 @@ class LeAudioClientImpl : public LeAudioClient {
      }
      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);
      int af_hz = audio_framework_source_config.sample_rate;
      unsigned enc_size = lc3_encoder_size(dt_us, af_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_left =
          lc3_setup_encoder(dt_us, sr_hz, af_hz, lc3_encoder_left_mem);
      lc3_encoder_right =
          lc3_setup_encoder(dt_us, sr_hz, lc3_encoder_right_mem);
          lc3_setup_encoder(dt_us, sr_hz, af_hz, lc3_encoder_right_mem);

    } else if (CodecManager::GetInstance()->GetCodecLocation() ==
               le_audio::types::CodecLocation::ADSP) {
      CodecManager::GetInstance()->UpdateActiveSourceAudioConfig(
@@ -2245,9 +2236,11 @@ class LeAudioClientImpl : public LeAudioClient {

      int dt_us = current_sink_codec_config.data_interval_us;
      int sr_hz = current_sink_codec_config.sample_rate;
      unsigned dec_size = lc3_decoder_size(dt_us, sr_hz);
      int af_hz = audio_framework_sink_config.sample_rate;
      unsigned dec_size = lc3_decoder_size(dt_us, af_hz);
      lc3_decoder_mem = malloc(dec_size);
      lc3_decoder = lc3_setup_decoder(dt_us, sr_hz, lc3_decoder_mem);

      lc3_decoder = lc3_setup_decoder(dt_us, sr_hz, af_hz, lc3_decoder_mem);
    } else if (CodecManager::GetInstance()->GetCodecLocation() ==
               le_audio::types::CodecLocation::ADSP) {
      CodecManager::GetInstance()->UpdateActiveSinkAudioConfig(*stream_conf,
+2 −1
Original line number Diff line number Diff line
@@ -37,7 +37,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {

  void* lc3_encoder_mem = nullptr;
  lc3_encoder_mem = malloc(enc_size);
  lc3_encoder_t  lc3_encoder = lc3_setup_encoder(dt_us, sr_hz, lc3_encoder_mem);
  lc3_encoder_t lc3_encoder =
      lc3_setup_encoder(dt_us, sr_hz, 0, lc3_encoder_mem);

  std::vector<uint8_t> output(output_byte_count);
  lc3_encode(lc3_encoder, (const int16_t*)input_frames.data(), 1,
+24 −2
Original line number Diff line number Diff line
@@ -205,6 +205,9 @@ int lc3_delay_samples(int dt_us, int sr_hz);
 * dt_us           Frame duration in us, 7500 or 10000
 * sr_hz           Samplerate in Hz, 8000, 16000, 24000, 32000 or 48000
 * return          Size of then encoder in bytes, 0 on bad parameters
 *
 * The `sr_hz` parameter is the samplerate of the PCM input stream,
 * and will match `sr_pcm_hz` of `lc3_setup_encoder()`.
 */
unsigned lc3_encoder_size(int dt_us, int sr_hz);

@@ -212,10 +215,18 @@ unsigned lc3_encoder_size(int dt_us, int sr_hz);
 * Setup encoder
 * dt_us           Frame duration in us, 7500 or 10000
 * sr_hz           Samplerate in Hz, 8000, 16000, 24000, 32000 or 48000
 * sr_pcm_hz       Input samplerate, downsampling option of input, or 0
 * mem             Encoder memory space, aligned to pointer type
 * return          Encoder as an handle, NULL on bad parameters
 *
 * The `sr_pcm_hz` parameter is a downsampling option of PCM input,
 * the value `0` fallback to the samplerate of the encoded stream `sr_hz`.
 * When used, `sr_pcm_hz` is intended to be higher or equal to the encoder
 * samplerate `sr_hz`. The size of the context needed, given by
 * `lc3_encoder_size()` will be set accordingly to `sr_pcm_hz`.
 */
lc3_encoder_t lc3_setup_encoder(int dt_us, int sr_hz, void *mem);
lc3_encoder_t lc3_setup_encoder(
    int dt_us, int sr_hz, int sr_pcm_hz, void *mem);

/**
 * Encode a frame
@@ -233,6 +244,9 @@ int lc3_encode(lc3_encoder_t encoder,
 * dt_us           Frame duration in us, 7500 or 10000
 * sr_hz           Samplerate in Hz, 8000, 16000, 24000, 32000 or 48000
 * return          Size of then decoder in bytes, 0 on bad parameters
 *
 * The `sr_hz` parameter is the samplerate of the PCM output stream,
 * and will match `sr_pcm_hz` of `lc3_setup_decoder()`.
 */
unsigned lc3_decoder_size(int dt_us, int sr_hz);

@@ -240,10 +254,18 @@ unsigned lc3_decoder_size(int dt_us, int sr_hz);
 * Setup decoder
 * dt_us           Frame duration in us, 7500 or 10000
 * sr_hz           Samplerate in Hz, 8000, 16000, 24000, 32000 or 48000
 * sr_pcm_hz       Output samplerate, upsampling option of output (or 0)
 * mem             Decoder memory space, aligned to pointer type
 * return          Decoder as an handle, NULL on bad parameters
 *
 * The `sr_pcm_hz` parameter is an upsampling option of PCM output,
 * the value `0` fallback to the samplerate of the decoded stream `sr_hz`.
 * When used, `sr_pcm_hz` is intended to be higher or equal to the decoder
 * samplerate `sr_hz`. The size of the context needed, given by
 * `lc3_decoder_size()` will be set accordingly to `sr_pcm_hz`.
 */
lc3_decoder_t lc3_setup_decoder(int dt_us, int sr_hz, void *mem);
lc3_decoder_t lc3_setup_decoder(
    int dt_us, int sr_hz, int sr_pcm_hz, void *mem);

/**
 * Decode a frame
+2 −2
Original line number Diff line number Diff line
@@ -97,7 +97,7 @@ typedef struct lc3_spec_analysis {

struct lc3_encoder {
    enum lc3_dt dt;
    enum lc3_srate sr;
    enum lc3_srate sr, sr_pcm;

    lc3_attdet_analysis_t attdet;
    lc3_ltpf_analysis_t ltpf;
@@ -134,7 +134,7 @@ typedef struct lc3_plc_state {

struct lc3_decoder {
    enum lc3_dt dt;
    enum lc3_srate sr;
    enum lc3_srate sr, sr_pcm;

    lc3_ltpf_synthesis_t ltpf;
    lc3_plc_state_t plc;
Loading