1 /****************************************************************************** 2 * 3 * Copyright 2018 The Android Open Source Project 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19 #include "audio_hearing_aid_hw/include/audio_hearing_aid_hw.h" 20 #include "bta_hearing_aid_api.h" 21 #include "osi/include/alarm.h" 22 #include "uipc.h" 23 24 #include <base/files/file_util.h> 25 #include <include/hardware/bt_av.h> 26 27 using base::FilePath; 28 extern const char* audio_ha_hw_dump_ctrl_event(tHEARING_AID_CTRL_CMD event); 29 30 namespace { 31 int bit_rate = 16; 32 int sample_rate = 16000; 33 int data_interval_ms = 10 /* msec */; 34 int num_channels = 2; 35 alarm_t* audio_timer = nullptr; 36 37 HearingAidAudioReceiver* localAudioReceiver; 38 std::unique_ptr<tUIPC_STATE> uipc_hearing_aid; 39 40 struct AudioHalStats { 41 size_t media_read_total_underflow_bytes; 42 size_t media_read_total_underflow_count; 43 uint64_t media_read_last_underflow_us; 44 45 AudioHalStats() { Reset(); } 46 47 void Reset() { 48 media_read_total_underflow_bytes = 0; 49 media_read_total_underflow_count = 0; 50 media_read_last_underflow_us = 0; 51 } 52 }; 53 54 AudioHalStats stats; 55 56 void send_audio_data(void*) { 57 uint32_t bytes_per_tick = 58 (num_channels * sample_rate * data_interval_ms * (bit_rate / 8)) / 1000; 59 60 uint16_t event; 61 uint8_t p_buf[bytes_per_tick]; 62 63 uint32_t bytes_read = UIPC_Read(*uipc_hearing_aid, UIPC_CH_ID_AV_AUDIO, 64 &event, p_buf, bytes_per_tick); 65 66 VLOG(2) << "bytes_read: " << bytes_read; 67 if (bytes_read < bytes_per_tick) { 68 stats.media_read_total_underflow_bytes += bytes_per_tick - bytes_read; 69 stats.media_read_total_underflow_count++; 70 stats.media_read_last_underflow_us = time_get_os_boottime_us(); 71 } 72 73 std::vector<uint8_t> data(p_buf, p_buf + bytes_read); 74 75 localAudioReceiver->OnAudioDataReady(data); 76 } 77 78 void hearing_aid_send_ack(tHEARING_AID_CTRL_ACK status) { 79 uint8_t ack = status; 80 DVLOG(2) << "Hearing Aid audio ctrl ack: " << status; 81 UIPC_Send(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0, &ack, sizeof(ack)); 82 } 83 84 void hearing_aid_data_cb(tUIPC_CH_ID, tUIPC_EVENT event) { 85 DVLOG(2) << "Hearing Aid audio data event: " << event; 86 switch (event) { 87 case UIPC_OPEN_EVT: 88 /* 89 * Read directly from media task from here on (keep callback for 90 * connection events. 91 */ 92 UIPC_Ioctl(*uipc_hearing_aid, UIPC_CH_ID_AV_AUDIO, 93 UIPC_REG_REMOVE_ACTIVE_READSET, NULL); 94 UIPC_Ioctl(*uipc_hearing_aid, UIPC_CH_ID_AV_AUDIO, UIPC_SET_READ_POLL_TMO, 95 reinterpret_cast<void*>(0)); 96 97 audio_timer = alarm_new_periodic("hearing_aid_data_timer"); 98 alarm_set_on_mloop(audio_timer, data_interval_ms, send_audio_data, 99 nullptr); 100 break; 101 case UIPC_CLOSE_EVT: 102 hearing_aid_send_ack(HEARING_AID_CTRL_ACK_SUCCESS); 103 if (audio_timer) { 104 alarm_cancel(audio_timer); 105 } 106 break; 107 default: 108 LOG(ERROR) << "Hearing Aid audio data event not recognized:" << event; 109 } 110 } 111 112 void hearing_aid_recv_ctrl_data() { 113 tHEARING_AID_CTRL_CMD cmd = HEARING_AID_CTRL_CMD_NONE; 114 int n; 115 116 uint8_t read_cmd = 0; /* The read command size is one octet */ 117 n = UIPC_Read(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, NULL, &read_cmd, 1); 118 cmd = static_cast<tHEARING_AID_CTRL_CMD>(read_cmd); 119 120 /* detach on ctrl channel means audioflinger process was terminated */ 121 if (n == 0) { 122 LOG(WARNING) << __func__ << "CTRL CH DETACHED"; 123 UIPC_Close(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL); 124 return; 125 } 126 127 VLOG(2) << __func__ << " " << audio_ha_hw_dump_ctrl_event(cmd); 128 // a2dp_cmd_pending = cmd; 129 130 switch (cmd) { 131 case HEARING_AID_CTRL_CMD_CHECK_READY: 132 hearing_aid_send_ack(HEARING_AID_CTRL_ACK_SUCCESS); 133 break; 134 135 case HEARING_AID_CTRL_CMD_START: 136 if (localAudioReceiver) localAudioReceiver->OnAudioResume(); 137 // timer is restarted in UIPC_Open 138 UIPC_Open(*uipc_hearing_aid, UIPC_CH_ID_AV_AUDIO, hearing_aid_data_cb, 139 HEARING_AID_DATA_PATH); 140 hearing_aid_send_ack(HEARING_AID_CTRL_ACK_SUCCESS); 141 break; 142 143 case HEARING_AID_CTRL_CMD_STOP: 144 hearing_aid_send_ack(HEARING_AID_CTRL_ACK_SUCCESS); 145 break; 146 147 case HEARING_AID_CTRL_CMD_SUSPEND: 148 if (audio_timer) alarm_cancel(audio_timer); 149 if (localAudioReceiver) localAudioReceiver->OnAudioSuspend(); 150 hearing_aid_send_ack(HEARING_AID_CTRL_ACK_SUCCESS); 151 break; 152 153 case HEARING_AID_CTRL_GET_OUTPUT_AUDIO_CONFIG: { 154 btav_a2dp_codec_config_t codec_config; 155 btav_a2dp_codec_config_t codec_capability; 156 if (sample_rate == 16000) { 157 codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_16000; 158 codec_capability.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_16000; 159 } else if (sample_rate == 24000) { 160 codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_24000; 161 codec_capability.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_24000; 162 } else { 163 LOG(FATAL) << "unsupported sample rate: " << sample_rate; 164 } 165 166 codec_config.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16; 167 codec_capability.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16; 168 169 codec_config.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO; 170 codec_capability.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO; 171 172 hearing_aid_send_ack(HEARING_AID_CTRL_ACK_SUCCESS); 173 // Send the current codec config 174 UIPC_Send(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0, 175 reinterpret_cast<const uint8_t*>(&codec_config.sample_rate), 176 sizeof(btav_a2dp_codec_sample_rate_t)); 177 UIPC_Send(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0, 178 reinterpret_cast<const uint8_t*>(&codec_config.bits_per_sample), 179 sizeof(btav_a2dp_codec_bits_per_sample_t)); 180 UIPC_Send(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0, 181 reinterpret_cast<const uint8_t*>(&codec_config.channel_mode), 182 sizeof(btav_a2dp_codec_channel_mode_t)); 183 // Send the current codec capability 184 UIPC_Send(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0, 185 reinterpret_cast<const uint8_t*>(&codec_capability.sample_rate), 186 sizeof(btav_a2dp_codec_sample_rate_t)); 187 UIPC_Send( 188 *uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0, 189 reinterpret_cast<const uint8_t*>(&codec_capability.bits_per_sample), 190 sizeof(btav_a2dp_codec_bits_per_sample_t)); 191 UIPC_Send( 192 *uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0, 193 reinterpret_cast<const uint8_t*>(&codec_capability.channel_mode), 194 sizeof(btav_a2dp_codec_channel_mode_t)); 195 break; 196 } 197 198 case HEARING_AID_CTRL_SET_OUTPUT_AUDIO_CONFIG: { 199 // TODO: we only support one config for now! 200 btav_a2dp_codec_config_t codec_config; 201 codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_NONE; 202 codec_config.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE; 203 codec_config.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_NONE; 204 205 hearing_aid_send_ack(HEARING_AID_CTRL_ACK_SUCCESS); 206 // Send the current codec config 207 if (UIPC_Read(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0, 208 reinterpret_cast<uint8_t*>(&codec_config.sample_rate), 209 sizeof(btav_a2dp_codec_sample_rate_t)) != 210 sizeof(btav_a2dp_codec_sample_rate_t)) { 211 LOG(ERROR) << __func__ << "Error reading sample rate from audio HAL"; 212 break; 213 } 214 if (UIPC_Read(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0, 215 reinterpret_cast<uint8_t*>(&codec_config.bits_per_sample), 216 sizeof(btav_a2dp_codec_bits_per_sample_t)) != 217 sizeof(btav_a2dp_codec_bits_per_sample_t)) { 218 LOG(ERROR) << __func__ 219 << "Error reading bits per sample from audio HAL"; 220 221 break; 222 } 223 if (UIPC_Read(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0, 224 reinterpret_cast<uint8_t*>(&codec_config.channel_mode), 225 sizeof(btav_a2dp_codec_channel_mode_t)) != 226 sizeof(btav_a2dp_codec_channel_mode_t)) { 227 LOG(ERROR) << __func__ << "Error reading channel mode from audio HAL"; 228 229 break; 230 } 231 LOG(INFO) << __func__ << " HEARING_AID_CTRL_SET_OUTPUT_AUDIO_CONFIG: " 232 << "sample_rate=" << codec_config.sample_rate 233 << "bits_per_sample=" << codec_config.bits_per_sample 234 << "channel_mode=" << codec_config.channel_mode; 235 break; 236 } 237 238 default: 239 LOG(ERROR) << __func__ << "UNSUPPORTED CMD: " << cmd; 240 hearing_aid_send_ack(HEARING_AID_CTRL_ACK_FAILURE); 241 break; 242 } 243 VLOG(2) << __func__ << " a2dp-ctrl-cmd : " << audio_ha_hw_dump_ctrl_event(cmd) 244 << " DONE"; 245 } 246 247 void hearing_aid_ctrl_cb(tUIPC_CH_ID, tUIPC_EVENT event) { 248 VLOG(2) << "Hearing Aid audio ctrl event: " << event; 249 switch (event) { 250 case UIPC_OPEN_EVT: 251 break; 252 case UIPC_CLOSE_EVT: 253 UIPC_Open(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, hearing_aid_ctrl_cb, 254 HEARING_AID_CTRL_PATH); 255 break; 256 case UIPC_RX_DATA_READY_EVT: 257 hearing_aid_recv_ctrl_data(); 258 break; 259 default: 260 LOG(ERROR) << "Hearing Aid audio ctrl unrecognized event: " << event; 261 } 262 } 263 } // namespace 264 265 void HearingAidAudioSource::Start(const CodecConfiguration& codecConfiguration, 266 HearingAidAudioReceiver* audioReceiver) { 267 localAudioReceiver = audioReceiver; 268 VLOG(2) << "Hearing Aid UIPC Open"; 269 stats.Reset(); 270 } 271 272 void HearingAidAudioSource::Stop() { 273 if (audio_timer) { 274 alarm_cancel(audio_timer); 275 } 276 } 277 278 void HearingAidAudioSource::Initialize() { 279 uipc_hearing_aid = UIPC_Init(); 280 UIPC_Open(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, hearing_aid_ctrl_cb, 281 HEARING_AID_CTRL_PATH); 282 } 283 284 void HearingAidAudioSource::CleanUp() { 285 UIPC_Close(*uipc_hearing_aid, UIPC_CH_ID_ALL); 286 } 287 288 void HearingAidAudioSource::DebugDump(int fd) { 289 uint64_t now_us = time_get_os_boottime_us(); 290 std::stringstream stream; 291 stream << " Hearing Aid Audio HAL:" 292 << "\n Counts (underflow) : " 293 << stats.media_read_total_underflow_count 294 << "\n Bytes (underflow) : " 295 << stats.media_read_total_underflow_bytes 296 << "\n Last update time ago in ms (underflow) : " 297 << (stats.media_read_last_underflow_us > 0 298 ? (unsigned long long)(now_us - 299 stats.media_read_last_underflow_us) / 300 1000 301 : 0) 302 << std::endl; 303 dprintf(fd, "%s", stream.str().c_str()); 304 } 305