Home | History | Annotate | Download | only in hearing_aid
      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