hearing_aid_software_encoding.cc 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. /*
  2. * Copyright 2019 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #define LOG_TAG "BTAudioClientHearingAid"
  17. #include "hearing_aid_software_encoding.h"
  18. #include "client_interface.h"
  19. #include "audio_hearing_aid_hw/include/audio_hearing_aid_hw.h"
  20. #include "osi/include/log.h"
  21. #include "osi/include/properties.h"
  22. namespace {
  23. using ::android::hardware::bluetooth::audio::V2_0::CodecType;
  24. using ::bluetooth::audio::AudioConfiguration;
  25. using ::bluetooth::audio::BitsPerSample;
  26. using ::bluetooth::audio::BluetoothAudioCtrlAck;
  27. using ::bluetooth::audio::ChannelMode;
  28. using ::bluetooth::audio::PcmParameters;
  29. using ::bluetooth::audio::SampleRate;
  30. using ::bluetooth::audio::SessionType;
  31. using ::bluetooth::audio::hearing_aid::StreamCallbacks;
  32. // Transport implementation for Hearing Aids
  33. class HearingAidTransport
  34. : public bluetooth::audio::IBluetoothTransportInstance {
  35. public:
  36. HearingAidTransport(StreamCallbacks stream_cb)
  37. : IBluetoothTransportInstance(
  38. SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH, {}),
  39. stream_cb_(std::move(stream_cb)),
  40. remote_delay_report_ms_(0),
  41. total_bytes_read_(0),
  42. data_position_({}){};
  43. BluetoothAudioCtrlAck StartRequest() override {
  44. LOG(INFO) << __func__;
  45. if (stream_cb_.on_resume_(true)) {
  46. return BluetoothAudioCtrlAck::SUCCESS_FINISHED;
  47. }
  48. return BluetoothAudioCtrlAck::FAILURE;
  49. }
  50. BluetoothAudioCtrlAck SuspendRequest() override {
  51. LOG(INFO) << __func__;
  52. if (stream_cb_.on_suspend_()) {
  53. uint8_t p_buf[AUDIO_STREAM_OUTPUT_BUFFER_SZ * 2];
  54. ::bluetooth::audio::hearing_aid::read(p_buf, sizeof(p_buf));
  55. return BluetoothAudioCtrlAck::SUCCESS_FINISHED;
  56. } else {
  57. return BluetoothAudioCtrlAck::FAILURE;
  58. }
  59. }
  60. void StopRequest() override {
  61. LOG(INFO) << __func__;
  62. if (stream_cb_.on_suspend_()) {
  63. // flush
  64. uint8_t p_buf[AUDIO_STREAM_OUTPUT_BUFFER_SZ * 2];
  65. ::bluetooth::audio::hearing_aid::read(p_buf, sizeof(p_buf));
  66. }
  67. }
  68. bool GetPresentationPosition(uint64_t* remote_delay_report_ns,
  69. uint64_t* total_bytes_read,
  70. timespec* data_position) override {
  71. VLOG(2) << __func__ << ": data=" << total_bytes_read_
  72. << " byte(s), timestamp=" << data_position_.tv_sec << "."
  73. << data_position_.tv_nsec
  74. << "s, delay report=" << remote_delay_report_ms_ << " msec.";
  75. if (remote_delay_report_ns != nullptr) {
  76. *remote_delay_report_ns = remote_delay_report_ms_ * 1000000u;
  77. }
  78. if (total_bytes_read != nullptr) *total_bytes_read = total_bytes_read_;
  79. if (data_position != nullptr) *data_position = data_position_;
  80. return true;
  81. }
  82. void MetadataChanged(const source_metadata_t& source_metadata) override {
  83. auto track_count = source_metadata.track_count;
  84. auto tracks = source_metadata.tracks;
  85. LOG(INFO) << __func__ << ": " << track_count << " track(s) received";
  86. while (track_count) {
  87. VLOG(1) << __func__ << ": usage=" << tracks->usage
  88. << ", content_type=" << tracks->content_type
  89. << ", gain=" << tracks->gain;
  90. --track_count;
  91. ++tracks;
  92. }
  93. }
  94. void ResetPresentationPosition() override {
  95. VLOG(2) << __func__ << ": called.";
  96. remote_delay_report_ms_ = 0;
  97. total_bytes_read_ = 0;
  98. data_position_ = {};
  99. }
  100. void LogBytesRead(size_t bytes_read) override {
  101. if (bytes_read) {
  102. total_bytes_read_ += bytes_read;
  103. clock_gettime(CLOCK_MONOTONIC, &data_position_);
  104. }
  105. }
  106. void SetRemoteDelay(uint16_t delay_report_ms) {
  107. LOG(INFO) << __func__ << ": delay_report=" << delay_report_ms << " msec";
  108. remote_delay_report_ms_ = delay_report_ms;
  109. }
  110. private:
  111. StreamCallbacks stream_cb_;
  112. uint16_t remote_delay_report_ms_;
  113. uint64_t total_bytes_read_;
  114. timespec data_position_;
  115. };
  116. bool HearingAidGetSelectedHalPcmConfig(PcmParameters* hal_pcm_config) {
  117. if (hal_pcm_config == nullptr) return false;
  118. // TODO: we only support one config for now!
  119. hal_pcm_config->sampleRate = SampleRate::RATE_16000;
  120. hal_pcm_config->bitsPerSample = BitsPerSample::BITS_16;
  121. hal_pcm_config->channelMode = ChannelMode::STEREO;
  122. return true;
  123. }
  124. // Sink instance of Hearing Aids to provide call-in APIs for Bluetooth Audio Hal
  125. HearingAidTransport* hearing_aid_sink = nullptr;
  126. // Common interface to call-out into Bluetooth Audio Hal
  127. bluetooth::audio::BluetoothAudioClientInterface*
  128. hearing_aid_hal_clientinterface = nullptr;
  129. bool btaudio_hearing_aid_disabled = false;
  130. bool is_configured = false;
  131. // Save the value if the remote reports its delay before hearing_aid_sink is
  132. // initialized
  133. uint16_t remote_delay_ms = 0;
  134. bool is_hal_2_0_force_disabled() {
  135. if (!is_configured) {
  136. btaudio_hearing_aid_disabled = osi_property_get_bool(BLUETOOTH_AUDIO_HAL_PROP_DISABLED, false);
  137. is_configured = true;
  138. }
  139. return btaudio_hearing_aid_disabled;
  140. }
  141. } // namespace
  142. namespace bluetooth {
  143. namespace audio {
  144. namespace hearing_aid {
  145. bool is_hal_2_0_enabled() { return hearing_aid_hal_clientinterface != nullptr; }
  146. bool init(StreamCallbacks stream_cb,
  147. bluetooth::common::MessageLoopThread* message_loop) {
  148. LOG(INFO) << __func__;
  149. if (is_hal_2_0_force_disabled()) {
  150. LOG(ERROR) << __func__ << ": BluetoothAudio HAL is disabled";
  151. return false;
  152. }
  153. hearing_aid_sink = new HearingAidTransport(std::move(stream_cb));
  154. hearing_aid_hal_clientinterface =
  155. new bluetooth::audio::BluetoothAudioClientInterface(hearing_aid_sink,
  156. message_loop);
  157. if (!hearing_aid_hal_clientinterface->IsValid()) {
  158. LOG(WARNING) << __func__ << ": BluetoothAudio HAL for Hearing Aid is invalid?!";
  159. delete hearing_aid_hal_clientinterface;
  160. hearing_aid_hal_clientinterface = nullptr;
  161. delete hearing_aid_sink;
  162. hearing_aid_sink = nullptr;
  163. return false;
  164. }
  165. if (remote_delay_ms != 0) {
  166. LOG(INFO) << __func__ << ": restore DELAY " << remote_delay_ms << " ms";
  167. hearing_aid_sink->SetRemoteDelay(remote_delay_ms);
  168. remote_delay_ms = 0;
  169. }
  170. return true;
  171. }
  172. void cleanup() {
  173. LOG(INFO) << __func__;
  174. if (!is_hal_2_0_enabled()) return;
  175. end_session();
  176. delete hearing_aid_hal_clientinterface;
  177. hearing_aid_hal_clientinterface = nullptr;
  178. delete hearing_aid_sink;
  179. hearing_aid_sink = nullptr;
  180. remote_delay_ms = 0;
  181. }
  182. void start_session() {
  183. LOG(INFO) << __func__;
  184. if (!is_hal_2_0_enabled()) return;
  185. AudioConfiguration audio_config;
  186. PcmParameters pcm_config{};
  187. if (!HearingAidGetSelectedHalPcmConfig(&pcm_config)) {
  188. LOG(ERROR) << __func__ << ": cannot get PCM config";
  189. return;
  190. }
  191. audio_config.pcmConfig(pcm_config);
  192. if (!hearing_aid_hal_clientinterface->UpdateAudioConfig(audio_config)) {
  193. LOG(ERROR) << __func__ << ": cannot update audio config to HAL";
  194. return;
  195. }
  196. hearing_aid_hal_clientinterface->StartSession();
  197. }
  198. void end_session() {
  199. LOG(INFO) << __func__;
  200. if (!is_hal_2_0_enabled()) return;
  201. hearing_aid_hal_clientinterface->EndSession();
  202. }
  203. size_t read(uint8_t* p_buf, uint32_t len) {
  204. if (!is_hal_2_0_enabled()) return 0;
  205. return hearing_aid_hal_clientinterface->ReadAudioData(p_buf, len);
  206. }
  207. // Update Hearing Aids delay report to BluetoothAudio HAL
  208. void set_remote_delay(uint16_t delay_report_ms) {
  209. if (!is_hal_2_0_enabled()) {
  210. LOG(INFO) << __func__ << ": not ready for DelayReport " << delay_report_ms
  211. << " ms";
  212. remote_delay_ms = delay_report_ms;
  213. return;
  214. }
  215. LOG(INFO) << __func__ << ": delay_report_ms=" << delay_report_ms << " ms";
  216. hearing_aid_sink->SetRemoteDelay(delay_report_ms);
  217. }
  218. } // namespace hearing_aid
  219. } // namespace audio
  220. } // namespace bluetooth