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

Commit 1ab703d2 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "audio: Introduce read PCM from FMQ session functionality"

parents 06ea5f15 ac6927f0
Loading
Loading
Loading
Loading
+36 −0
Original line number Original line Diff line number Diff line
@@ -43,7 +43,10 @@ AudioConfiguration BluetoothAudioSession::invalidSoftwareAudioConfiguration =
AudioConfiguration BluetoothAudioSession::invalidOffloadAudioConfiguration = {};
AudioConfiguration BluetoothAudioSession::invalidOffloadAudioConfiguration = {};


static constexpr int kFmqSendTimeoutMs = 1000;  // 1000 ms timeout for sending
static constexpr int kFmqSendTimeoutMs = 1000;  // 1000 ms timeout for sending
static constexpr int kFmqReceiveTimeoutMs =
    1000;                                       // 1000 ms timeout for receiving
static constexpr int kWritePollMs = 1;          // polled non-blocking interval
static constexpr int kWritePollMs = 1;          // polled non-blocking interval
static constexpr int kReadPollMs = 1;           // polled non-blocking interval


static inline timespec timespec_convert_from_hal(const TimeSpec& TS) {
static inline timespec timespec_convert_from_hal(const TimeSpec& TS) {
  return {.tv_sec = static_cast<long>(TS.tvSec),
  return {.tv_sec = static_cast<long>(TS.tvSec),
@@ -402,6 +405,39 @@ size_t BluetoothAudioSession::OutWritePcmData(const void* buffer,
  return totalWritten;
  return totalWritten;
}
}


// The control function reads stream from FMQ
size_t BluetoothAudioSession::InReadPcmData(void* buffer, size_t bytes) {
  if (buffer == nullptr || !bytes) return 0;
  size_t totalRead = 0;
  int ms_timeout = kFmqReceiveTimeoutMs;
  do {
    std::unique_lock<std::recursive_mutex> lock(mutex_);
    if (!IsSessionReady()) break;
    size_t availableToRead = mDataMQ->availableToRead();
    if (availableToRead) {
      if (availableToRead > (bytes - totalRead)) {
        availableToRead = bytes - totalRead;
      }
      if (!mDataMQ->read(static_cast<uint8_t*>(buffer) + totalRead,
                         availableToRead)) {
        ALOGE("FMQ datapath reading %zu/%zu failed", totalRead, bytes);
        return totalRead;
      }
      totalRead += availableToRead;
    } else if (ms_timeout >= kReadPollMs) {
      lock.unlock();
      usleep(kReadPollMs * 1000);
      ms_timeout -= kReadPollMs;
      continue;
    } else {
      ALOGD("in data %zu/%zu overflow %d ms", totalRead, bytes,
            (kFmqReceiveTimeoutMs - ms_timeout));
      return totalRead;
    }
  } while (totalRead < bytes);
  return totalRead;
}

std::unique_ptr<BluetoothAudioSessionInstance>
std::unique_ptr<BluetoothAudioSessionInstance>
    BluetoothAudioSessionInstance::instance_ptr =
    BluetoothAudioSessionInstance::instance_ptr =
        std::unique_ptr<BluetoothAudioSessionInstance>(
        std::unique_ptr<BluetoothAudioSessionInstance>(
+2 −0
Original line number Original line Diff line number Diff line
@@ -153,6 +153,8 @@ class BluetoothAudioSession {


  // The control function writes stream to FMQ
  // The control function writes stream to FMQ
  size_t OutWritePcmData(const void* buffer, size_t bytes);
  size_t OutWritePcmData(const void* buffer, size_t bytes);
  // The control function read stream from FMQ
  size_t InReadPcmData(void* buffer, size_t bytes);


  static constexpr PcmParameters kInvalidPcmParameters = {
  static constexpr PcmParameters kInvalidPcmParameters = {
      .sampleRate = SampleRate::RATE_UNKNOWN,
      .sampleRate = SampleRate::RATE_UNKNOWN,
+11 −0
Original line number Original line Diff line number Diff line
@@ -141,6 +141,17 @@ class BluetoothAudioSessionControl_2_1 {
    }
    }
    return 0;
    return 0;
  }
  }

  // The control API reads stream from FMQ
  static size_t InReadPcmData(const SessionType_2_1& session_type, void* buffer,
                              size_t bytes) {
    std::shared_ptr<BluetoothAudioSession_2_1> session_ptr =
        BluetoothAudioSessionInstance_2_1::GetSessionInstance(session_type);
    if (session_ptr != nullptr) {
      return session_ptr->GetAudioSession()->InReadPcmData(buffer, bytes);
    }
    return 0;
  }
};
};


}  // namespace audio
}  // namespace audio