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

Commit ed31cc10 authored by Jakub Pawlowski's avatar Jakub Pawlowski
Browse files

Accept audio from audio server in data_interval_us chunks

Currently, we request audio server to pass audio data in 2ms intervals.
With LE Audio this makes not much sense, data is encoded in 7.5 or 10ms
interval.
With this patch applied, we request audio server to provide us with data
only once every interval.

Looks like waking/sleeping, locking/unlocking and additional buffer moves
were actually quite expensive. Before this patch, CPU usage by
bluetooth process is around 86% on Pixel 6 PRO when playing music with
screen off. Audio is often breaking and sttering.
With this patch applied, the CPU usage in same scenario goes down to
around 46%, and the audio stuttering is significantly reduced.

Test: manual, verify audio quality in hearing test.
Bug: 150670922
Change-Id: I9687a4ab813f389597d674b2bc1f0f16d709f1c7
parent 7fc3d1cb
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -319,6 +319,27 @@ bool BluetoothAudioPortOut::LoadAudioConfig(audio_config_t* audio_cfg) const {
  return true;
}

bool BluetoothAudioPortOut::GetPreferredDataIntervalUs(
    size_t* interval_us) const {
  if (!in_use()) {
    return false;
  }

  const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration&
      hal_audio_cfg =
          BluetoothAudioSessionControl_2_2::GetAudioConfig(session_type_);
  if (hal_audio_cfg.getDiscriminator() !=
      ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration::
          hidl_discriminator::pcmConfig) {
    return false;
  }

  const ::android::hardware::bluetooth::audio::V2_1::PcmParameters& pcm_cfg =
      hal_audio_cfg.pcmConfig();
  *interval_us = pcm_cfg.dataIntervalUs;
  return true;
}

bool BluetoothAudioPortIn::LoadAudioConfig(audio_config_t* audio_cfg) const {
  if (!in_use()) {
    LOG(ERROR) << __func__ << ": BluetoothAudioPortIn is not in use";
+1 −0
Original line number Diff line number Diff line
@@ -119,6 +119,7 @@ class BluetoothAudioPortOut : public BluetoothAudioPort {
  // The audio data path to the Bluetooth stack (Software encoding)
  size_t WriteData(const void* buffer, size_t bytes) const;
  bool LoadAudioConfig(audio_config_t* audio_cfg) const;
  bool GetPreferredDataIntervalUs(size_t* interval_us) const;
};

class BluetoothAudioPortIn : public BluetoothAudioPort {
+15 −5
Original line number Diff line number Diff line
@@ -678,9 +678,8 @@ static void out_update_source_metadata(
  out->bluetooth_output_.UpdateMetadata(source_metadata);
}

static size_t samples_per_ticks(size_t milliseconds, uint32_t sample_rate,
                                size_t channel_count) {
  return milliseconds * sample_rate * channel_count / 1000;
static size_t frame_count(size_t microseconds, uint32_t sample_rate) {
  return (microseconds * sample_rate) / 1000000;
}

int adev_open_output_stream(struct audio_hw_device* dev,
@@ -734,8 +733,19 @@ int adev_open_output_stream(struct audio_hw_device* dev,
  out->channel_mask_ = config->channel_mask;
  out->format_ = config->format;
  // frame is number of samples per channel

  size_t preferred_data_interval_us = kBluetoothDefaultOutputBufferMs * 1000;
  if (out->bluetooth_output_.GetPreferredDataIntervalUs(
          &preferred_data_interval_us) &&
      preferred_data_interval_us != 0) {
    out->preferred_data_interval_us = preferred_data_interval_us;
  } else {
    out->preferred_data_interval_us = kBluetoothDefaultOutputBufferMs * 1000;
  }

  out->frames_count_ =
      samples_per_ticks(kBluetoothDefaultOutputBufferMs, out->sample_rate_, 1);
      frame_count(out->preferred_data_interval_us, out->sample_rate_);

  out->frames_rendered_ = 0;
  out->frames_presented_ = 0;

@@ -1188,7 +1198,7 @@ int adev_open_input_stream(struct audio_hw_device* dev,
  in->format_ = config->format;
  // frame is number of samples per channel
  in->frames_count_ =
      samples_per_ticks(kBluetoothDefaultInputBufferMs, in->sample_rate_, 1);
      frame_count(kBluetoothDefaultInputBufferMs, in->sample_rate_);
  in->frames_presented_ = 0;

  *stream_in = &in->stream_in_;
+1 −0
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ struct BluetoothStreamOut {
  uint32_t sample_rate_;
  audio_channel_mask_t channel_mask_;
  audio_format_t format_;
  size_t preferred_data_interval_us;
  // frame is the number of samples per channel
  // frames count per tick
  size_t frames_count_;