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

Commit 2a7b97a7 authored by Grzegorz Kołodziejczyk's avatar Grzegorz Kołodziejczyk Committed by Automerger Merge Worker
Browse files

audio: Introduce LE Audio support for client interface and HAL am: 4015a4c4

Original change: https://android-review.googlesource.com/c/platform/system/bt/+/1589742

Change-Id: If100a9ae30f2b344e08d8b73b1c076dc992e67c4
parents 6469d13a 4015a4c4
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -172,6 +172,24 @@ bool BluetoothAudioPort::init_session_type(audio_devices_t device) {
                   << ")";
      session_type_ = SessionType_2_1::HEARING_AID_SOFTWARE_ENCODING_DATAPATH;
      break;
    case AUDIO_DEVICE_OUT_BLE_HEADSET:
      LOG(VERBOSE) << __func__
                   << ": device=AUDIO_DEVICE_OUT_BLE_HEADSET (MEDIA/VOICE) ("
                   << StringPrintf("%#x", device) << ")";
      session_type_ = SessionType_2_1::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH;
      break;
    case AUDIO_DEVICE_OUT_BLE_SPEAKER:
      LOG(VERBOSE) << __func__
                   << ": device=AUDIO_DEVICE_OUT_BLE_SPEAKER (MEDIA) ("
                   << StringPrintf("%#x", device) << ")";
      session_type_ = SessionType_2_1::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH;
      break;
    case AUDIO_DEVICE_IN_BLE_HEADSET:
      LOG(VERBOSE) << __func__
                   << ": device=AUDIO_DEVICE_IN_BLE_HEADSET (VOICE) ("
                   << StringPrintf("%#x", device) << ")";
      session_type_ = SessionType_2_1::LE_AUDIO_SOFTWARE_DECODED_DATAPATH;
      break;
    default:
      LOG(ERROR) << __func__ << ": unknown device=" << StringPrintf("%#x", device);
      return false;
+1 −4
Original line number Diff line number Diff line
@@ -69,11 +69,8 @@ class BluetoothAudioPort {
  // Called by Audio framework / HAL to stop the stream
  void Stop();

  // The audio data path to the Bluetooth stack (Software encoding)
  size_t WriteData(const void* buffer, size_t bytes) const;

  // Called by the Audio framework / HAL to fetch informaiton about audio frames
  // presented to an external sink.
  // presented to an external sink, or frames presented fror an internal sink
  bool GetPresentationPosition(uint64_t* delay_ns, uint64_t* bytes,
                               timespec* timestamp) const;

+1 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ cc_library_static {
                "client_interface.cc",
                "codec_status.cc",
                "hearing_aid_software_encoding.cc",
                "le_audio_software.cc",
            ],
        },
        host: {
+5 −1
Original line number Diff line number Diff line
@@ -525,7 +525,11 @@ bool BluetoothAudioClientInterface::UpdateAudioConfig_2_1(
      (transport_->GetSessionType_2_1() ==
           SessionType_2_1::A2DP_SOFTWARE_ENCODING_DATAPATH ||
       transport_->GetSessionType_2_1() ==
           SessionType_2_1::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
           SessionType_2_1::HEARING_AID_SOFTWARE_ENCODING_DATAPATH ||
       transport_->GetSessionType_2_1() ==
           SessionType_2_1::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH ||
       transport_->GetSessionType_2_1() ==
           SessionType_2_1::LE_AUDIO_SOFTWARE_DECODED_DATAPATH);
  bool is_offload_session = (transport_->GetSessionType_2_1() ==
                             SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH);
  auto audio_config_discriminator = audio_config_2_1.getDiscriminator();
+73 −0
Original line number Diff line number Diff line
@@ -86,6 +86,15 @@ constexpr SampleRatePair kSampleRatePairs[9] = {
    {.hal_sample_rate_ = SampleRate::RATE_24000,
     .btav_sample_rate_ = BTAV_A2DP_CODEC_SAMPLE_RATE_24000}};

constexpr SampleRate_2_1 kSampleRates_2_1[] = {
    SampleRate_2_1::RATE_UNKNOWN, SampleRate_2_1::RATE_8000,
    SampleRate_2_1::RATE_16000,   SampleRate_2_1::RATE_24000,
    SampleRate_2_1::RATE_32000,   SampleRate_2_1::RATE_44100,
    SampleRate_2_1::RATE_48000};

constexpr uint32_t kDataIntervalUs[] = {0 /* Invalid */,
                                        10000 /* Valid 10ms */};

struct BitsPerSamplePair {
  BitsPerSample hal_bits_per_sample_;
  btav_a2dp_codec_bits_per_sample_t btav_bits_per_sample_;
@@ -796,3 +805,67 @@ TEST_F(BluetoothAudioClientInterfaceTest,
    }    // BitsPerSampple
  }      // SampleRate
}

TEST_F(BluetoothAudioClientInterfaceTest,
       StartAndEndLeAudioEncodingSoftwareSession) {
  test_sink_transport_ = new TestSinkTransport(
      SessionType_2_1::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH);
  clientif_sink_ =
      new BluetoothAudioSinkClientInterface(test_sink_transport_, nullptr);
  AudioConfiguration_2_1 audio_config = {};
  PcmParameters_2_1 pcm_config = {};
  for (auto sample_rate : kSampleRates_2_1) {
    pcm_config.sampleRate = sample_rate;
    for (auto bits_per_sample_pair : kBitsPerSamplePairs) {
      pcm_config.bitsPerSample = bits_per_sample_pair.hal_bits_per_sample_;
      for (auto channel_mode_pair : kChannelModePairs) {
        pcm_config.channelMode = channel_mode_pair.hal_channel_mode_;
        for (auto data_interval_us : kDataIntervalUs) {
          pcm_config.dataIntervalUs = data_interval_us;
          audio_config.pcmConfig(pcm_config);
          clientif_sink_->UpdateAudioConfig_2_1(audio_config);
          if (IsSinkSoftwarePcmParameters_2_1_Supported(pcm_config)) {
            ASSERT_EQ(clientif_sink_->StartSession_2_1(),
                      kClientIfReturnSuccess);
          } else {
            ASSERT_NE(clientif_sink_->StartSession_2_1(),
                      kClientIfReturnSuccess);
          }
          ASSERT_EQ(clientif_sink_->EndSession(), kClientIfReturnSuccess);
        }  // dataIntervalUs
      }    // ChannelMode
    }      // BitsPerSampple
  }        // SampleRate
}

TEST_F(BluetoothAudioClientInterfaceTest,
       StartAndEndLeAudioDecodedSoftwareSession) {
  test_source_transport_ = new TestSourceTransport(
      SessionType_2_1::LE_AUDIO_SOFTWARE_DECODED_DATAPATH);
  clientif_source_ =
      new BluetoothAudioSourceClientInterface(test_source_transport_, nullptr);
  AudioConfiguration_2_1 audio_config = {};
  PcmParameters_2_1 pcm_config = {};
  for (auto sample_rate : kSampleRates_2_1) {
    pcm_config.sampleRate = sample_rate;
    for (auto bits_per_sample_pair : kBitsPerSamplePairs) {
      pcm_config.bitsPerSample = bits_per_sample_pair.hal_bits_per_sample_;
      for (auto channel_mode_pair : kChannelModePairs) {
        pcm_config.channelMode = channel_mode_pair.hal_channel_mode_;
        for (auto data_interval_us : kDataIntervalUs) {
          pcm_config.dataIntervalUs = data_interval_us;
          audio_config.pcmConfig(pcm_config);
          clientif_source_->UpdateAudioConfig_2_1(audio_config);
          if (IsSourceSoftwarePcmParameters_2_1_Supported(pcm_config)) {
            ASSERT_EQ(clientif_source_->StartSession_2_1(),
                      kClientIfReturnSuccess);
          } else {
            ASSERT_NE(clientif_source_->StartSession_2_1(),
                      kClientIfReturnSuccess);
          }
          ASSERT_EQ(clientif_source_->EndSession(), kClientIfReturnSuccess);
        }  // dataIntervalUs
      }    // ChannelMode
    }      // BitsPerSampple
  }        // SampleRate
}
Loading