tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

cubeb_opensl.cpp (62711B)


      1 /*
      2 * Copyright © 2012 Mozilla Foundation
      3 *
      4 * This program is made available under an ISC-style license.  See the
      5 * accompanying file LICENSE for details.
      6 */
      7 #undef NDEBUG
      8 #include <SLES/OpenSLES.h>
      9 #include <dlfcn.h>
     10 #include <errno.h>
     11 #include <math.h>
     12 #include <memory>
     13 #include <pthread.h>
     14 #include <stdlib.h>
     15 #include <time.h>
     16 #include <vector>
     17 #if defined(__ANDROID__)
     18 #include "android/sles_definitions.h"
     19 #include <SLES/OpenSLES_Android.h>
     20 #include <android/api-level.h>
     21 #include <android/log.h>
     22 #include <dlfcn.h>
     23 #include <sys/system_properties.h>
     24 #endif
     25 #include "android/cubeb-output-latency.h"
     26 #include "cubeb-internal.h"
     27 #include "cubeb/cubeb.h"
     28 #include "cubeb_android.h"
     29 #include "cubeb_array_queue.h"
     30 #include "cubeb_resampler.h"
     31 
     32 #define ANDROID_VERSION_GINGERBREAD_MR1 10
     33 #define ANDROID_VERSION_JELLY_BEAN 18
     34 #define ANDROID_VERSION_LOLLIPOP 21
     35 #define ANDROID_VERSION_MARSHMALLOW 23
     36 #define ANDROID_VERSION_N_MR1 25
     37 
     38 #define DEFAULT_SAMPLE_RATE 48000
     39 #define DEFAULT_NUM_OF_FRAMES 480
     40 
     41 extern cubeb_ops const opensl_ops;
     42 
     43 struct cubeb {
     44  struct cubeb_ops const * ops;
     45  void * lib;
     46  SLInterfaceID SL_IID_BUFFERQUEUE;
     47  SLInterfaceID SL_IID_PLAY;
     48 #if defined(__ANDROID__)
     49  SLInterfaceID SL_IID_ANDROIDCONFIGURATION;
     50  SLInterfaceID SL_IID_ANDROIDSIMPLEBUFFERQUEUE;
     51 #endif
     52  SLInterfaceID SL_IID_VOLUME;
     53  SLInterfaceID SL_IID_RECORD;
     54  SLObjectItf engObj;
     55  SLEngineItf eng;
     56  SLObjectItf outmixObj;
     57  output_latency_function * p_output_latency_function;
     58 };
     59 
     60 #define NELEMS(A) (sizeof(A) / sizeof(A)[0])
     61 #define NBUFS 2
     62 
     63 struct cubeb_stream {
     64  /* Note: Must match cubeb_stream layout in cubeb.c. */
     65  cubeb * context;
     66  void * user_ptr;
     67  /**/
     68  pthread_mutex_t mutex;
     69  SLObjectItf playerObj;
     70  SLPlayItf play;
     71  SLBufferQueueItf bufq;
     72  SLVolumeItf volume;
     73  void ** queuebuf;
     74  uint32_t queuebuf_capacity;
     75  uint32_t queuebuf_idx;
     76  long queuebuf_len;
     77  long bytespersec;
     78  uint32_t framesize;
     79  /* Total number of played frames.
     80   * Synchronized by stream::mutex lock. */
     81  long written;
     82  /* Flag indicating draining. Synchronized
     83   * by stream::mutex lock. */
     84  int draining;
     85  /* Flags to determine in/out.*/
     86  uint32_t input_enabled;
     87  uint32_t output_enabled;
     88  /* Recorder abstract object. */
     89  SLObjectItf recorderObj;
     90  /* Recorder Itf for input capture. */
     91  SLRecordItf recorderItf;
     92  /* Buffer queue for input capture. */
     93  SLAndroidSimpleBufferQueueItf recorderBufferQueueItf;
     94  /* Store input buffers. */
     95  void ** input_buffer_array;
     96  /* The capacity of the array.
     97   * On capture only can be small (4).
     98   * On full duplex is calculated to
     99   * store 1 sec of data buffers. */
    100  uint32_t input_array_capacity;
    101  /* Current filled index of input buffer array.
    102   * It is initiated to -1 indicating buffering
    103   * have not started yet. */
    104  int input_buffer_index;
    105  /* Length of input buffer.*/
    106  uint32_t input_buffer_length;
    107  /* Input frame size */
    108  uint32_t input_frame_size;
    109  /* Device sampling rate. If user rate is not
    110   * accepted an compatible rate is set. If it is
    111   * accepted this is equal to params.rate. */
    112  uint32_t input_device_rate;
    113  /* Exchange input buffers between input
    114   * and full duplex threads. */
    115  array_queue * input_queue;
    116  /* Silent input buffer used on full duplex. */
    117  void * input_silent_buffer;
    118  /* Number of input frames from the start of the stream*/
    119  uint32_t input_total_frames;
    120  /* Flag to stop the execution of user callback and
    121   * close all working threads. Synchronized by
    122   * stream::mutex lock. */
    123  uint32_t shutdown;
    124  /* Store user callback. */
    125  cubeb_data_callback data_callback;
    126  /* Store state callback. */
    127  cubeb_state_callback state_callback;
    128 
    129  cubeb_resampler * resampler;
    130  unsigned int user_output_rate;
    131  unsigned int output_configured_rate;
    132  unsigned int buffer_size_frames;
    133  // Audio output latency used in cubeb_stream_get_position().
    134  unsigned int output_latency_ms;
    135  int64_t lastPosition;
    136  int64_t lastPositionTimeStamp;
    137  int64_t lastCompensativePosition;
    138  int voice_input;
    139  int voice_output;
    140  std::unique_ptr<cubeb_stream_params> input_params;
    141  std::unique_ptr<cubeb_stream_params> output_params;
    142  // A non-empty buffer means that f32 -> int16 conversion need to happen
    143  std::vector<float> conversion_buffer_output;
    144  std::vector<float> conversion_buffer_input;
    145 };
    146 
    147 /* Forward declaration. */
    148 static int
    149 opensl_stop_player(cubeb_stream * stm);
    150 static int
    151 opensl_stop_recorder(cubeb_stream * stm);
    152 
    153 static int
    154 opensl_get_draining(cubeb_stream * stm)
    155 {
    156 #ifdef DEBUG
    157  int r = pthread_mutex_trylock(&stm->mutex);
    158  XASSERT((r == EDEADLK || r == EBUSY) &&
    159          "get_draining: mutex should be locked but it's not.");
    160 #endif
    161  return stm->draining;
    162 }
    163 
    164 static void
    165 opensl_set_draining(cubeb_stream * stm, int value)
    166 {
    167 #ifdef DEBUG
    168  int r = pthread_mutex_trylock(&stm->mutex);
    169  LOG("set draining try r = %d", r);
    170  XASSERT((r == EDEADLK || r == EBUSY) &&
    171          "set_draining: mutex should be locked but it's not.");
    172 #endif
    173  XASSERT(value == 0 || value == 1);
    174  stm->draining = value;
    175 }
    176 
    177 static void
    178 opensl_notify_drained(cubeb_stream * stm)
    179 {
    180  XASSERT(stm);
    181  int r = pthread_mutex_lock(&stm->mutex);
    182  XASSERT(r == 0);
    183  int draining = opensl_get_draining(stm);
    184  r = pthread_mutex_unlock(&stm->mutex);
    185  XASSERT(r == 0);
    186  if (draining) {
    187    stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_DRAINED);
    188    if (stm->play) {
    189      LOG("stop player in play_callback");
    190      r = opensl_stop_player(stm);
    191      XASSERT(r == CUBEB_OK);
    192    }
    193    if (stm->recorderItf) {
    194      r = opensl_stop_recorder(stm);
    195      XASSERT(r == CUBEB_OK);
    196    }
    197  }
    198 }
    199 
    200 static uint32_t
    201 opensl_get_shutdown(cubeb_stream * stm)
    202 {
    203 #ifdef DEBUG
    204  int r = pthread_mutex_trylock(&stm->mutex);
    205  XASSERT((r == EDEADLK || r == EBUSY) &&
    206          "get_shutdown: mutex should be locked but it's not.");
    207 #endif
    208  return stm->shutdown;
    209 }
    210 
    211 static void
    212 opensl_set_shutdown(cubeb_stream * stm, uint32_t value)
    213 {
    214 #ifdef DEBUG
    215  int r = pthread_mutex_trylock(&stm->mutex);
    216  LOG("set shutdown try r = %d", r);
    217  XASSERT((r == EDEADLK || r == EBUSY) &&
    218          "set_shutdown: mutex should be locked but it's not.");
    219 #endif
    220  XASSERT(value == 0 || value == 1);
    221  stm->shutdown = value;
    222 }
    223 
    224 static void
    225 play_callback(SLPlayItf caller, void * user_ptr, SLuint32 event)
    226 {
    227  cubeb_stream * stm = static_cast<cubeb_stream *>(user_ptr);
    228  XASSERT(stm);
    229  switch (event) {
    230  case SL_PLAYEVENT_HEADATMARKER:
    231    opensl_notify_drained(stm);
    232    break;
    233  default:
    234    break;
    235  }
    236 }
    237 
    238 static void
    239 recorder_marker_callback(SLRecordItf caller, void * pContext, SLuint32 event)
    240 {
    241  cubeb_stream * stm = static_cast<cubeb_stream *>(pContext);
    242  XASSERT(stm);
    243 
    244  if (event == SL_RECORDEVENT_HEADATMARKER) {
    245    int r = pthread_mutex_lock(&stm->mutex);
    246    XASSERT(r == 0);
    247    int draining = opensl_get_draining(stm);
    248    r = pthread_mutex_unlock(&stm->mutex);
    249    XASSERT(r == 0);
    250    if (draining) {
    251      stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_DRAINED);
    252      if (stm->recorderItf) {
    253        r = opensl_stop_recorder(stm);
    254        XASSERT(r == CUBEB_OK);
    255      }
    256      if (stm->play) {
    257        r = opensl_stop_player(stm);
    258        XASSERT(r == CUBEB_OK);
    259      }
    260    }
    261  }
    262 }
    263 
    264 // Returns a buffer suitable to write output data to.
    265 void *
    266 get_output_buffer(cubeb_stream * stm, void * output_buffer,
    267                  uint32_t sample_count)
    268 {
    269  if (stm->conversion_buffer_output.empty()) {
    270    return output_buffer;
    271  }
    272  if (stm->conversion_buffer_output.size() < sample_count) {
    273    stm->conversion_buffer_output.resize(sample_count);
    274  }
    275  return stm->conversion_buffer_output.data();
    276 }
    277 
    278 void *
    279 release_output_buffer(cubeb_stream * stm, void * original_output_buffer,
    280                      uint32_t sample_count)
    281 {
    282  if (stm->conversion_buffer_output.empty()) {
    283    return original_output_buffer;
    284  }
    285  int16_t * int16_buf = reinterpret_cast<int16_t *>(original_output_buffer);
    286  for (uint32_t i = 0; i < sample_count; i++) {
    287    float v = stm->conversion_buffer_output[i] * 32768.0f;
    288    float clamped = std::max(-32768.0f, std::min(32767.0f, v));
    289    int16_buf[i] = static_cast<int16_t>(clamped);
    290  }
    291  return original_output_buffer;
    292 }
    293 
    294 static void
    295 bufferqueue_callback(SLBufferQueueItf caller, void * user_ptr)
    296 {
    297  cubeb_stream * stm = static_cast<cubeb_stream *>(user_ptr);
    298  XASSERT(stm);
    299  SLBufferQueueState state;
    300  SLresult res;
    301  long written = 0;
    302 
    303  res = (*stm->bufq)->GetState(stm->bufq, &state);
    304  XASSERT(res == SL_RESULT_SUCCESS);
    305 
    306  if (state.count > 1) {
    307    return;
    308  }
    309 
    310  void * buf = stm->queuebuf[stm->queuebuf_idx];
    311  void * buf_original_ptr = buf;
    312  uint32_t sample_count =
    313      stm->output_params->channels * stm->queuebuf_len / stm->framesize;
    314  written = 0;
    315  int r = pthread_mutex_lock(&stm->mutex);
    316  XASSERT(r == 0);
    317  int draining = opensl_get_draining(stm);
    318  uint32_t shutdown = opensl_get_shutdown(stm);
    319  r = pthread_mutex_unlock(&stm->mutex);
    320  XASSERT(r == 0);
    321  if (!draining && !shutdown) {
    322 
    323    buf = get_output_buffer(stm, buf, sample_count);
    324 
    325    written = cubeb_resampler_fill(stm->resampler, nullptr, nullptr, buf,
    326                                   stm->queuebuf_len / stm->framesize);
    327 
    328    buf = release_output_buffer(stm, buf_original_ptr, sample_count);
    329 
    330    ALOGV("bufferqueue_callback: resampler fill returned %ld frames", written);
    331    if (written < 0 ||
    332        written * stm->framesize > static_cast<uint32_t>(stm->queuebuf_len)) {
    333      ALOGV("bufferqueue_callback: error, shutting down");
    334      r = pthread_mutex_lock(&stm->mutex);
    335      XASSERT(r == 0);
    336      opensl_set_shutdown(stm, 1);
    337      r = pthread_mutex_unlock(&stm->mutex);
    338      XASSERT(r == 0);
    339      opensl_stop_player(stm);
    340      stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_ERROR);
    341      return;
    342    }
    343  }
    344 
    345  // Keep sending silent data even in draining mode to prevent the audio
    346  // back-end from being stopped automatically by OpenSL/ES.
    347  XASSERT(static_cast<uint32_t>(stm->queuebuf_len) >= written * stm->framesize);
    348  memset(reinterpret_cast<uint8_t *>(buf) + written * stm->framesize, 0,
    349         stm->queuebuf_len - written * stm->framesize);
    350  res = (*stm->bufq)->Enqueue(stm->bufq, buf, stm->queuebuf_len);
    351  XASSERT(res == SL_RESULT_SUCCESS);
    352  stm->queuebuf_idx = (stm->queuebuf_idx + 1) % stm->queuebuf_capacity;
    353 
    354  if (written > 0) {
    355    pthread_mutex_lock(&stm->mutex);
    356    stm->written += written;
    357    pthread_mutex_unlock(&stm->mutex);
    358  }
    359 
    360  if (!draining &&
    361      written * stm->framesize < static_cast<uint32_t>(stm->queuebuf_len)) {
    362    LOG("bufferqueue_callback draining");
    363    r = pthread_mutex_lock(&stm->mutex);
    364    XASSERT(r == 0);
    365    int64_t written_duration =
    366        INT64_C(1000) * stm->written * stm->framesize / stm->bytespersec;
    367    opensl_set_draining(stm, 1);
    368    r = pthread_mutex_unlock(&stm->mutex);
    369    XASSERT(r == 0);
    370 
    371    if (written_duration == 0) {
    372      // since we didn't write any sample, it's not possible to reach the marker
    373      // time and trigger the callback. We should initiative notify drained.
    374      opensl_notify_drained(stm);
    375    } else {
    376      // Use SL_PLAYEVENT_HEADATMARKER event from slPlayCallback of SLPlayItf
    377      // to make sure all the data has been processed.
    378      (*stm->play)
    379          ->SetMarkerPosition(stm->play, (SLmillisecond)written_duration);
    380    }
    381    return;
    382  }
    383 }
    384 
    385 static int
    386 opensl_enqueue_recorder(cubeb_stream * stm, void ** last_filled_buffer)
    387 {
    388  XASSERT(stm);
    389 
    390  int current_index = stm->input_buffer_index;
    391  void * last_buffer = nullptr;
    392 
    393  if (current_index < 0) {
    394    // This is the first enqueue
    395    current_index = 0;
    396  } else {
    397    // The current index hold the last filled buffer get it before advance
    398    // index.
    399    last_buffer = stm->input_buffer_array[current_index];
    400    // Advance to get next available buffer
    401    current_index =
    402        static_cast<int>((current_index + 1) % stm->input_array_capacity);
    403  }
    404  // enqueue next empty buffer to be filled by the recorder
    405  SLresult res = (*stm->recorderBufferQueueItf)
    406                     ->Enqueue(stm->recorderBufferQueueItf,
    407                               stm->input_buffer_array[current_index],
    408                               stm->input_buffer_length);
    409  if (res != SL_RESULT_SUCCESS) {
    410    LOG("Enqueue recorder failed. Error code: %u", res);
    411    return CUBEB_ERROR;
    412  }
    413  // All good, update buffer and index.
    414  stm->input_buffer_index = current_index;
    415  if (last_filled_buffer) {
    416    *last_filled_buffer = last_buffer;
    417  }
    418  return CUBEB_OK;
    419 }
    420 
    421 // If necessary, convert and returns an input buffer.
    422 // Otherwise, just returns the pointer that has been passed in.
    423 void *
    424 convert_input_buffer_if_needed(cubeb_stream * stm, void * input_buffer,
    425                               uint32_t sample_count)
    426 {
    427  // Perform conversion if needed
    428  if (stm->conversion_buffer_input.empty()) {
    429    return input_buffer;
    430  }
    431  if (stm->conversion_buffer_input.size() < sample_count) {
    432    stm->conversion_buffer_input.resize(sample_count);
    433  }
    434  int16_t * int16_buf = reinterpret_cast<int16_t *>(input_buffer);
    435  for (uint32_t i = 0; i < sample_count; i++) {
    436    stm->conversion_buffer_input[i] =
    437        static_cast<float>(int16_buf[i]) / 32768.f;
    438  }
    439  return stm->conversion_buffer_input.data();
    440 }
    441 
    442 // input data callback
    443 void
    444 recorder_callback(SLAndroidSimpleBufferQueueItf bq, void * context)
    445 {
    446  XASSERT(context);
    447  cubeb_stream * stm = static_cast<cubeb_stream *>(context);
    448  XASSERT(stm->recorderBufferQueueItf);
    449 
    450  int r = pthread_mutex_lock(&stm->mutex);
    451  XASSERT(r == 0);
    452  uint32_t shutdown = opensl_get_shutdown(stm);
    453  int draining = opensl_get_draining(stm);
    454  r = pthread_mutex_unlock(&stm->mutex);
    455  XASSERT(r == 0);
    456 
    457  if (shutdown || draining) {
    458    // According to the OpenSL ES 1.1 Specification, 8.14 SLBufferQueueItf
    459    // page 184, on transition to the SL_RECORDSTATE_STOPPED state,
    460    // the application should continue to enqueue buffers onto the queue
    461    // to retrieve the residual recorded data in the system.
    462    r = opensl_enqueue_recorder(stm, nullptr);
    463    XASSERT(r == CUBEB_OK);
    464    return;
    465  }
    466 
    467  // Enqueue next available buffer and get the last filled buffer.
    468  void * input_buffer = nullptr;
    469  r = opensl_enqueue_recorder(stm, &input_buffer);
    470  XASSERT(r == CUBEB_OK);
    471  XASSERT(input_buffer);
    472 
    473  long input_frame_count = stm->input_buffer_length / stm->input_frame_size;
    474  uint32_t sample_count = input_frame_count * stm->input_params->channels;
    475 
    476  input_buffer =
    477      convert_input_buffer_if_needed(stm, input_buffer, sample_count);
    478 
    479  // Fill resampler with last input
    480  long got = cubeb_resampler_fill(stm->resampler, input_buffer,
    481                                  &input_frame_count, nullptr, 0);
    482  // Error case
    483  if (got < 0 || got > input_frame_count) {
    484    r = pthread_mutex_lock(&stm->mutex);
    485    XASSERT(r == 0);
    486    opensl_set_shutdown(stm, 1);
    487    r = pthread_mutex_unlock(&stm->mutex);
    488    XASSERT(r == 0);
    489    r = opensl_stop_recorder(stm);
    490    XASSERT(r == CUBEB_OK);
    491    stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_ERROR);
    492  }
    493 
    494  // Advance total stream frames
    495  stm->input_total_frames += got;
    496 
    497  if (got < input_frame_count) {
    498    r = pthread_mutex_lock(&stm->mutex);
    499    XASSERT(r == 0);
    500    opensl_set_draining(stm, 1);
    501    r = pthread_mutex_unlock(&stm->mutex);
    502    XASSERT(r == 0);
    503    int64_t duration =
    504        INT64_C(1000) * stm->input_total_frames / stm->input_device_rate;
    505    (*stm->recorderItf)
    506        ->SetMarkerPosition(stm->recorderItf, (SLmillisecond)duration);
    507    return;
    508  }
    509 }
    510 
    511 void
    512 recorder_fullduplex_callback(SLAndroidSimpleBufferQueueItf bq, void * context)
    513 {
    514  XASSERT(context);
    515  cubeb_stream * stm = static_cast<cubeb_stream *>(context);
    516  XASSERT(stm->recorderBufferQueueItf);
    517 
    518  int r = pthread_mutex_lock(&stm->mutex);
    519  XASSERT(r == 0);
    520  int draining = opensl_get_draining(stm);
    521  uint32_t shutdown = opensl_get_shutdown(stm);
    522  r = pthread_mutex_unlock(&stm->mutex);
    523  XASSERT(r == 0);
    524 
    525  if (shutdown || draining) {
    526    /* On draining and shutdown the recorder should have been stoped from
    527     *  the one set the flags. Accordint to the doc, on transition to
    528     *  the SL_RECORDSTATE_STOPPED state, the application should
    529     *  continue to enqueue buffers onto the queue to retrieve the residual
    530     *  recorded data in the system. */
    531    LOG("Input shutdown %d or drain %d", shutdown, draining);
    532    int r = opensl_enqueue_recorder(stm, nullptr);
    533    XASSERT(r == CUBEB_OK);
    534    return;
    535  }
    536 
    537  // Enqueue next available buffer and get the last filled buffer.
    538  void * input_buffer = nullptr;
    539  r = opensl_enqueue_recorder(stm, &input_buffer);
    540  XASSERT(r == CUBEB_OK);
    541  XASSERT(input_buffer);
    542 
    543  XASSERT(stm->input_queue);
    544  r = array_queue_push(stm->input_queue, input_buffer);
    545  if (r == -1) {
    546    LOG("Input queue is full, drop input ...");
    547    return;
    548  }
    549 
    550  LOG("Input pushed in the queue, input array %zu",
    551      array_queue_get_size(stm->input_queue));
    552 }
    553 
    554 static void
    555 player_fullduplex_callback(SLBufferQueueItf caller, void * user_ptr)
    556 {
    557  cubeb_stream * stm = static_cast<cubeb_stream *>(user_ptr);
    558  XASSERT(stm);
    559  SLresult res;
    560 
    561  int r = pthread_mutex_lock(&stm->mutex);
    562  XASSERT(r == 0);
    563  int draining = opensl_get_draining(stm);
    564  uint32_t shutdown = opensl_get_shutdown(stm);
    565  r = pthread_mutex_unlock(&stm->mutex);
    566  XASSERT(r == 0);
    567 
    568  // Get output
    569  void * output_buffer = nullptr;
    570  r = pthread_mutex_lock(&stm->mutex);
    571  XASSERT(r == 0);
    572  output_buffer = stm->queuebuf[stm->queuebuf_idx];
    573  void * output_buffer_original_ptr = output_buffer;
    574  // Advance the output buffer queue index
    575  stm->queuebuf_idx = (stm->queuebuf_idx + 1) % stm->queuebuf_capacity;
    576  r = pthread_mutex_unlock(&stm->mutex);
    577  XASSERT(r == 0);
    578 
    579  if (shutdown || draining) {
    580    LOG("Shutdown/draining, send silent");
    581    // Set silent on buffer
    582    memset(output_buffer, 0, stm->queuebuf_len);
    583 
    584    // Enqueue data in player buffer queue
    585    res = (*stm->bufq)->Enqueue(stm->bufq, output_buffer, stm->queuebuf_len);
    586    XASSERT(res == SL_RESULT_SUCCESS);
    587    return;
    588  }
    589 
    590  // Get input.
    591  void * input_buffer = array_queue_pop(stm->input_queue);
    592  long input_frame_count = stm->input_buffer_length / stm->input_frame_size;
    593  long sample_count = input_frame_count * stm->input_params->channels;
    594  long frames_needed = stm->queuebuf_len / stm->framesize;
    595  uint32_t output_sample_count =
    596      stm->output_params->channels * stm->queuebuf_len / stm->framesize;
    597 
    598  if (!input_buffer) {
    599    LOG("Input hole set silent input buffer");
    600    input_buffer = stm->input_silent_buffer;
    601  }
    602 
    603  input_buffer =
    604      convert_input_buffer_if_needed(stm, input_buffer, sample_count);
    605 
    606  output_buffer = get_output_buffer(stm, output_buffer, output_sample_count);
    607 
    608  long written = 0;
    609  // Trigger user callback through resampler
    610  written =
    611      cubeb_resampler_fill(stm->resampler, input_buffer, &input_frame_count,
    612                           output_buffer, frames_needed);
    613 
    614  output_buffer =
    615      release_output_buffer(stm, output_buffer_original_ptr, sample_count);
    616 
    617  LOG("Fill: written %ld, frames_needed %ld, input array size %zu", written,
    618      frames_needed, array_queue_get_size(stm->input_queue));
    619 
    620  if (written < 0 || written > frames_needed) {
    621    // Error case
    622    r = pthread_mutex_lock(&stm->mutex);
    623    XASSERT(r == 0);
    624    opensl_set_shutdown(stm, 1);
    625    r = pthread_mutex_unlock(&stm->mutex);
    626    XASSERT(r == 0);
    627    opensl_stop_player(stm);
    628    opensl_stop_recorder(stm);
    629    stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_ERROR);
    630    memset(output_buffer, 0, stm->queuebuf_len);
    631 
    632    // Enqueue data in player buffer queue
    633    res = (*stm->bufq)->Enqueue(stm->bufq, output_buffer, stm->queuebuf_len);
    634    XASSERT(res == SL_RESULT_SUCCESS);
    635    return;
    636  }
    637 
    638  // Advance total out written  frames counter
    639  r = pthread_mutex_lock(&stm->mutex);
    640  XASSERT(r == 0);
    641  stm->written += written;
    642  r = pthread_mutex_unlock(&stm->mutex);
    643  XASSERT(r == 0);
    644 
    645  if (written < frames_needed) {
    646    r = pthread_mutex_lock(&stm->mutex);
    647    XASSERT(r == 0);
    648    int64_t written_duration =
    649        INT64_C(1000) * stm->written * stm->framesize / stm->bytespersec;
    650    opensl_set_draining(stm, 1);
    651    r = pthread_mutex_unlock(&stm->mutex);
    652    XASSERT(r == 0);
    653 
    654    // Use SL_PLAYEVENT_HEADATMARKER event from slPlayCallback of SLPlayItf
    655    // to make sure all the data has been processed.
    656    (*stm->play)->SetMarkerPosition(stm->play, (SLmillisecond)written_duration);
    657  }
    658 
    659  // Keep sending silent data even in draining mode to prevent the audio
    660  // back-end from being stopped automatically by OpenSL/ES.
    661  memset((uint8_t *)output_buffer + written * stm->framesize, 0,
    662         stm->queuebuf_len - written * stm->framesize);
    663 
    664  // Enqueue data in player buffer queue
    665  res = (*stm->bufq)->Enqueue(stm->bufq, output_buffer, stm->queuebuf_len);
    666  XASSERT(res == SL_RESULT_SUCCESS);
    667 }
    668 
    669 static void
    670 opensl_destroy(cubeb * ctx);
    671 
    672 #if defined(__ANDROID__)
    673 #if (__ANDROID_API__ >= ANDROID_VERSION_LOLLIPOP)
    674 using system_property_get = int(const char *, char *);
    675 
    676 static int
    677 wrap_system_property_get(const char * name, char * value)
    678 {
    679  void * libc = dlopen("libc.so", RTLD_LAZY);
    680  if (!libc) {
    681    LOG("Failed to open libc.so");
    682    return -1;
    683  }
    684  system_property_get * func =
    685      (system_property_get *)dlsym(libc, "__system_property_get");
    686  int ret = -1;
    687  if (func) {
    688    ret = func(name, value);
    689  }
    690  dlclose(libc);
    691  return ret;
    692 }
    693 #endif
    694 
    695 static int
    696 get_android_version(void)
    697 {
    698  char version_string[PROP_VALUE_MAX];
    699 
    700  memset(version_string, 0, PROP_VALUE_MAX);
    701 
    702 #if (__ANDROID_API__ >= ANDROID_VERSION_LOLLIPOP)
    703  int len = wrap_system_property_get("ro.build.version.sdk", version_string);
    704 #else
    705  int len = __system_property_get("ro.build.version.sdk", version_string);
    706 #endif
    707  if (len <= 0) {
    708    LOG("Failed to get Android version!\n");
    709    return len;
    710  }
    711 
    712  int version = (int)strtol(version_string, nullptr, 10);
    713  LOG("Android version %d", version);
    714  return version;
    715 }
    716 #endif
    717 
    718 extern "C" {
    719 int
    720 opensl_init(cubeb ** context, char const * context_name)
    721 {
    722  cubeb * ctx;
    723 
    724 #if defined(__ANDROID__)
    725  int android_version = get_android_version();
    726  if (android_version > 0 &&
    727      android_version <= ANDROID_VERSION_GINGERBREAD_MR1) {
    728    // Don't even attempt to run on Gingerbread and lower
    729    LOG("Error: Android version too old, exiting.");
    730    return CUBEB_ERROR;
    731  }
    732 #endif
    733 
    734  *context = nullptr;
    735 
    736  ctx = static_cast<cubeb *>(calloc(1, sizeof(*ctx)));
    737  XASSERT(ctx);
    738 
    739  ctx->ops = &opensl_ops;
    740 
    741  ctx->lib = dlopen("libOpenSLES.so", RTLD_LAZY);
    742  if (!ctx->lib) {
    743    LOG("Error: Couldn't find libOpenSLES.so, exiting");
    744    free(ctx);
    745    return CUBEB_ERROR;
    746  }
    747 
    748  typedef SLresult (*slCreateEngine_t)(
    749      SLObjectItf *, SLuint32, const SLEngineOption *, SLuint32,
    750      const SLInterfaceID *, const SLboolean *);
    751  slCreateEngine_t f_slCreateEngine =
    752      (slCreateEngine_t)dlsym(ctx->lib, "slCreateEngine");
    753  SLInterfaceID SL_IID_ENGINE =
    754      *(SLInterfaceID *)dlsym(ctx->lib, "SL_IID_ENGINE");
    755  SLInterfaceID SL_IID_OUTPUTMIX =
    756      *(SLInterfaceID *)dlsym(ctx->lib, "SL_IID_OUTPUTMIX");
    757  ctx->SL_IID_VOLUME = *(SLInterfaceID *)dlsym(ctx->lib, "SL_IID_VOLUME");
    758  ctx->SL_IID_BUFFERQUEUE =
    759      *(SLInterfaceID *)dlsym(ctx->lib, "SL_IID_BUFFERQUEUE");
    760 #if defined(__ANDROID__)
    761  ctx->SL_IID_ANDROIDCONFIGURATION =
    762      *(SLInterfaceID *)dlsym(ctx->lib, "SL_IID_ANDROIDCONFIGURATION");
    763  ctx->SL_IID_ANDROIDSIMPLEBUFFERQUEUE =
    764      *(SLInterfaceID *)dlsym(ctx->lib, "SL_IID_ANDROIDSIMPLEBUFFERQUEUE");
    765 #endif
    766  ctx->SL_IID_PLAY = *(SLInterfaceID *)dlsym(ctx->lib, "SL_IID_PLAY");
    767  ctx->SL_IID_RECORD = *(SLInterfaceID *)dlsym(ctx->lib, "SL_IID_RECORD");
    768 
    769  if (!f_slCreateEngine || !SL_IID_ENGINE || !SL_IID_OUTPUTMIX ||
    770      !ctx->SL_IID_BUFFERQUEUE ||
    771 #if defined(__ANDROID__)
    772      !ctx->SL_IID_ANDROIDCONFIGURATION ||
    773      !ctx->SL_IID_ANDROIDSIMPLEBUFFERQUEUE ||
    774 #endif
    775      !ctx->SL_IID_PLAY || !ctx->SL_IID_RECORD) {
    776    LOG("Error: didn't find required symbols, exiting.");
    777    opensl_destroy(ctx);
    778    return CUBEB_ERROR;
    779  }
    780 
    781  const SLEngineOption opt[] = {{SL_ENGINEOPTION_THREADSAFE, SL_BOOLEAN_TRUE}};
    782 
    783  SLresult res;
    784  res = f_slCreateEngine(&ctx->engObj, 1, opt, 0, nullptr, nullptr);
    785 
    786  if (res != SL_RESULT_SUCCESS) {
    787    LOG("Error: slCreateEngine failure, exiting.");
    788    opensl_destroy(ctx);
    789    return CUBEB_ERROR;
    790  }
    791 
    792  res = (*ctx->engObj)->Realize(ctx->engObj, SL_BOOLEAN_FALSE);
    793  if (res != SL_RESULT_SUCCESS) {
    794    LOG("Error: engine realization failure, exiting.");
    795    opensl_destroy(ctx);
    796    return CUBEB_ERROR;
    797  }
    798 
    799  res = (*ctx->engObj)->GetInterface(ctx->engObj, SL_IID_ENGINE, &ctx->eng);
    800  if (res != SL_RESULT_SUCCESS) {
    801    LOG("Error: GetInterface(..., SL_IID_ENGINE, ...), exiting.");
    802    opensl_destroy(ctx);
    803    return CUBEB_ERROR;
    804  }
    805 
    806  const SLInterfaceID idsom[] = {SL_IID_OUTPUTMIX};
    807  const SLboolean reqom[] = {SL_BOOLEAN_TRUE};
    808  res =
    809      (*ctx->eng)->CreateOutputMix(ctx->eng, &ctx->outmixObj, 1, idsom, reqom);
    810  if (res != SL_RESULT_SUCCESS) {
    811    LOG("Error: CreateOutputMix failure, exiting.");
    812    opensl_destroy(ctx);
    813    return CUBEB_ERROR;
    814  }
    815 
    816  res = (*ctx->outmixObj)->Realize(ctx->outmixObj, SL_BOOLEAN_FALSE);
    817  if (res != SL_RESULT_SUCCESS) {
    818    LOG("Error: Output mix object failure, exiting.");
    819    opensl_destroy(ctx);
    820    return CUBEB_ERROR;
    821  }
    822 
    823  ctx->p_output_latency_function =
    824      cubeb_output_latency_load_method(android_version);
    825  if (!cubeb_output_latency_method_is_loaded(ctx->p_output_latency_function)) {
    826    LOG("Warning: output latency is not available, cubeb_stream_get_position() "
    827        "is not supported");
    828  }
    829 
    830  *context = ctx;
    831 
    832  LOG("Cubeb init (%p) success", ctx);
    833  return CUBEB_OK;
    834 }
    835 }
    836 
    837 static char const *
    838 opensl_get_backend_id(cubeb * ctx)
    839 {
    840  return "opensl";
    841 }
    842 
    843 static int
    844 opensl_get_max_channel_count(cubeb * ctx, uint32_t * max_channels)
    845 {
    846  XASSERT(ctx && max_channels);
    847  /* The android mixer handles up to two channels, see
    848    http://androidxref.com/4.2.2_r1/xref/frameworks/av/services/audioflinger/AudioFlinger.h#67
    849  */
    850  *max_channels = 2;
    851 
    852  return CUBEB_OK;
    853 }
    854 
    855 static void
    856 opensl_destroy(cubeb * ctx)
    857 {
    858  if (ctx->outmixObj) {
    859    (*ctx->outmixObj)->Destroy(ctx->outmixObj);
    860  }
    861  if (ctx->engObj) {
    862    (*ctx->engObj)->Destroy(ctx->engObj);
    863  }
    864  dlclose(ctx->lib);
    865  if (ctx->p_output_latency_function) {
    866    cubeb_output_latency_unload_method(ctx->p_output_latency_function);
    867  }
    868  free(ctx);
    869 }
    870 
    871 static void
    872 opensl_stream_destroy(cubeb_stream * stm);
    873 
    874 #if defined(__ANDROID__) && (__ANDROID_API__ >= ANDROID_VERSION_LOLLIPOP)
    875 static int
    876 opensl_set_format_ext(SLAndroidDataFormat_PCM_EX * format,
    877                      cubeb_stream_params * params)
    878 {
    879  XASSERT(format);
    880  XASSERT(params);
    881 
    882  format->formatType = SL_ANDROID_DATAFORMAT_PCM_EX;
    883  format->numChannels = params->channels;
    884  // sampleRate is in milliHertz
    885  format->sampleRate = params->rate * 1000;
    886  format->channelMask = params->channels == 1
    887                            ? SL_SPEAKER_FRONT_CENTER
    888                            : SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
    889 
    890  switch (params->format) {
    891  case CUBEB_SAMPLE_S16LE:
    892    format->bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;
    893    format->containerSize = SL_PCMSAMPLEFORMAT_FIXED_16;
    894    format->representation = SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT;
    895    format->endianness = SL_BYTEORDER_LITTLEENDIAN;
    896    break;
    897  case CUBEB_SAMPLE_S16BE:
    898    format->bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;
    899    format->containerSize = SL_PCMSAMPLEFORMAT_FIXED_16;
    900    format->representation = SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT;
    901    format->endianness = SL_BYTEORDER_BIGENDIAN;
    902    break;
    903  case CUBEB_SAMPLE_FLOAT32LE:
    904    format->bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_32;
    905    format->containerSize = SL_PCMSAMPLEFORMAT_FIXED_32;
    906    format->representation = SL_ANDROID_PCM_REPRESENTATION_FLOAT;
    907    format->endianness = SL_BYTEORDER_LITTLEENDIAN;
    908    break;
    909  case CUBEB_SAMPLE_FLOAT32BE:
    910    format->bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_32;
    911    format->containerSize = SL_PCMSAMPLEFORMAT_FIXED_32;
    912    format->representation = SL_ANDROID_PCM_REPRESENTATION_FLOAT;
    913    format->endianness = SL_BYTEORDER_BIGENDIAN;
    914    break;
    915  default:
    916    return CUBEB_ERROR_INVALID_FORMAT;
    917  }
    918  return CUBEB_OK;
    919 }
    920 #endif
    921 
    922 static int
    923 opensl_set_format(SLDataFormat_PCM * format, cubeb_stream_params * params)
    924 {
    925  XASSERT(format);
    926  XASSERT(params);
    927 
    928  // If this function is called, this backend has been compiled with an older
    929  // version of Android, that doesn't support floating point audio IO.
    930  // The stream is configured with int16 of the proper endianess, and conversion
    931  // will happen during playback.
    932 
    933  format->formatType = SL_DATAFORMAT_PCM;
    934  format->numChannels = params->channels;
    935  // samplesPerSec is in milliHertz
    936  format->samplesPerSec = params->rate * 1000;
    937  format->bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;
    938  format->containerSize = SL_PCMSAMPLEFORMAT_FIXED_16;
    939  format->channelMask = params->channels == 1
    940                            ? SL_SPEAKER_FRONT_CENTER
    941                            : SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
    942 
    943  switch (params->format) {
    944  case CUBEB_SAMPLE_S16LE:
    945  case CUBEB_SAMPLE_FLOAT32LE:
    946    format->endianness = SL_BYTEORDER_LITTLEENDIAN;
    947    break;
    948  case CUBEB_SAMPLE_S16BE:
    949  case CUBEB_SAMPLE_FLOAT32BE:
    950    format->endianness = SL_BYTEORDER_BIGENDIAN;
    951    break;
    952  default:
    953    XASSERT(false && "unhandled value");
    954  }
    955  return CUBEB_OK;
    956 }
    957 
    958 template <typename Function>
    959 int
    960 initialize_with_format(cubeb_stream * stm, cubeb_stream_params * params,
    961                       Function func)
    962 {
    963  void * format = nullptr;
    964  bool using_floats = false;
    965  uint32_t * format_sample_rate;
    966 #if defined(__ANDROID__) && (__ANDROID_API__ >= ANDROID_VERSION_LOLLIPOP)
    967  SLAndroidDataFormat_PCM_EX pcm_ext_format;
    968  if (get_android_version() >= ANDROID_VERSION_LOLLIPOP) {
    969    if (opensl_set_format_ext(&pcm_ext_format, params) != CUBEB_OK) {
    970      LOG("opensl_set_format_ext: error, exiting");
    971      return CUBEB_ERROR_INVALID_FORMAT;
    972    }
    973    format = &pcm_ext_format;
    974    format_sample_rate = &pcm_ext_format.sampleRate;
    975    using_floats =
    976        pcm_ext_format.representation == SL_ANDROID_PCM_REPRESENTATION_FLOAT;
    977  }
    978 #endif
    979 
    980  SLDataFormat_PCM pcm_format;
    981  if (!format) {
    982    if (opensl_set_format(&pcm_format, params) != CUBEB_OK) {
    983      LOG("opensl_set_format: error, exiting");
    984      return CUBEB_ERROR_INVALID_FORMAT;
    985    }
    986    format = &pcm_format;
    987    format_sample_rate = &pcm_format.samplesPerSec;
    988  }
    989 
    990  return func(format, format_sample_rate, using_floats);
    991 }
    992 
    993 static int
    994 opensl_configure_capture(cubeb_stream * stm, cubeb_stream_params * params)
    995 {
    996  XASSERT(stm);
    997  XASSERT(params);
    998 
    999  /* For now set device rate to params rate. */
   1000  stm->input_device_rate = params->rate;
   1001 
   1002  int rv = initialize_with_format(
   1003      stm, params,
   1004      [=](void * format, uint32_t * format_sample_rate,
   1005          bool using_floats) -> int {
   1006        SLDataLocator_AndroidSimpleBufferQueue lDataLocatorOut;
   1007        lDataLocatorOut.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
   1008        lDataLocatorOut.numBuffers = NBUFS;
   1009 
   1010        SLDataSink dataSink;
   1011        dataSink.pLocator = &lDataLocatorOut;
   1012        dataSink.pFormat = format;
   1013 
   1014        SLDataLocator_IODevice dataLocatorIn;
   1015        dataLocatorIn.locatorType = SL_DATALOCATOR_IODEVICE;
   1016        dataLocatorIn.deviceType = SL_IODEVICE_AUDIOINPUT;
   1017        dataLocatorIn.deviceID = SL_DEFAULTDEVICEID_AUDIOINPUT;
   1018        dataLocatorIn.device = nullptr;
   1019 
   1020        SLDataSource dataSource;
   1021        dataSource.pLocator = &dataLocatorIn;
   1022        dataSource.pFormat = nullptr;
   1023 
   1024        const SLInterfaceID lSoundRecorderIIDs[] = {
   1025            stm->context->SL_IID_RECORD,
   1026            stm->context->SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
   1027            stm->context->SL_IID_ANDROIDCONFIGURATION};
   1028 
   1029        const SLboolean lSoundRecorderReqs[] = {
   1030            SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
   1031        // create the audio recorder abstract object
   1032        SLresult res =
   1033            (*stm->context->eng)
   1034                ->CreateAudioRecorder(stm->context->eng, &stm->recorderObj,
   1035                                      &dataSource, &dataSink,
   1036                                      NELEMS(lSoundRecorderIIDs),
   1037                                      lSoundRecorderIIDs, lSoundRecorderReqs);
   1038        // Sample rate not supported. Try again with default sample rate!
   1039        if (res == SL_RESULT_CONTENT_UNSUPPORTED) {
   1040          if (stm->output_enabled && stm->output_configured_rate != 0) {
   1041            // Set the same with the player. Since there is no
   1042            // api for input device this is a safe choice.
   1043            stm->input_device_rate = stm->output_configured_rate;
   1044          } else {
   1045            // The output preferred rate is used for an input only scenario.
   1046            // The default rate expected to be supported from all android
   1047            // devices.
   1048            stm->input_device_rate = DEFAULT_SAMPLE_RATE;
   1049          }
   1050          *format_sample_rate = stm->input_device_rate * 1000;
   1051          res = (*stm->context->eng)
   1052                    ->CreateAudioRecorder(
   1053                        stm->context->eng, &stm->recorderObj, &dataSource,
   1054                        &dataSink, NELEMS(lSoundRecorderIIDs),
   1055                        lSoundRecorderIIDs, lSoundRecorderReqs);
   1056        }
   1057        if (res != SL_RESULT_SUCCESS) {
   1058          LOG("Failed to create recorder, not trying other input"
   1059              " rate. Error code: %u",
   1060              res);
   1061          return CUBEB_ERROR;
   1062        }
   1063        // It's always possible to use int16 regardless of the Android version.
   1064        // However if compiling for older Android version, it's possible to
   1065        // request f32 audio, but Android only supports int16, in which case a
   1066        // conversion need to happen.
   1067        if ((params->format == CUBEB_SAMPLE_FLOAT32NE ||
   1068             params->format == CUBEB_SAMPLE_FLOAT32BE) &&
   1069            !using_floats) {
   1070          // setup conversion from f32 to int16
   1071          LOG("Input stream configured for using float, but not supported: a "
   1072              "conversion will be performed");
   1073          stm->conversion_buffer_input.resize(1);
   1074        }
   1075        return CUBEB_OK;
   1076      });
   1077 
   1078  if (rv != CUBEB_OK) {
   1079    LOG("Could not initialize recorder.");
   1080    return rv;
   1081  }
   1082 
   1083  SLresult res;
   1084  if (get_android_version() > ANDROID_VERSION_JELLY_BEAN) {
   1085    SLAndroidConfigurationItf recorderConfig;
   1086    res = (*stm->recorderObj)
   1087              ->GetInterface(stm->recorderObj,
   1088                             stm->context->SL_IID_ANDROIDCONFIGURATION,
   1089                             &recorderConfig);
   1090 
   1091    if (res != SL_RESULT_SUCCESS) {
   1092      LOG("Failed to get the android configuration interface for recorder. "
   1093          "Error "
   1094          "code: %u",
   1095          res);
   1096      return CUBEB_ERROR;
   1097    }
   1098 
   1099    // Voice recognition is the lowest latency, according to the docs. Camcorder
   1100    // uses a microphone that is in the same direction as the camera.
   1101    SLint32 streamType = stm->voice_input
   1102                             ? SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION
   1103                             : SL_ANDROID_RECORDING_PRESET_CAMCORDER;
   1104 
   1105    res =
   1106        (*recorderConfig)
   1107            ->SetConfiguration(recorderConfig, SL_ANDROID_KEY_RECORDING_PRESET,
   1108                               &streamType, sizeof(SLint32));
   1109 
   1110    if (res != SL_RESULT_SUCCESS) {
   1111      LOG("Failed to set the android configuration to VOICE for the recorder. "
   1112          "Error code: %u",
   1113          res);
   1114      return CUBEB_ERROR;
   1115    }
   1116  }
   1117  // realize the audio recorder
   1118  res = (*stm->recorderObj)->Realize(stm->recorderObj, SL_BOOLEAN_FALSE);
   1119  if (res != SL_RESULT_SUCCESS) {
   1120    LOG("Failed to realize recorder. Error code: %u", res);
   1121    return CUBEB_ERROR;
   1122  }
   1123  // get the record interface
   1124  res = (*stm->recorderObj)
   1125            ->GetInterface(stm->recorderObj, stm->context->SL_IID_RECORD,
   1126                           &stm->recorderItf);
   1127  if (res != SL_RESULT_SUCCESS) {
   1128    LOG("Failed to get recorder interface. Error code: %u", res);
   1129    return CUBEB_ERROR;
   1130  }
   1131 
   1132  res = (*stm->recorderItf)
   1133            ->RegisterCallback(stm->recorderItf, recorder_marker_callback, stm);
   1134  if (res != SL_RESULT_SUCCESS) {
   1135    LOG("Failed to register recorder marker callback. Error code: %u", res);
   1136    return CUBEB_ERROR;
   1137  }
   1138 
   1139  (*stm->recorderItf)->SetMarkerPosition(stm->recorderItf, (SLmillisecond)0);
   1140 
   1141  res = (*stm->recorderItf)
   1142            ->SetCallbackEventsMask(stm->recorderItf,
   1143                                    (SLuint32)SL_RECORDEVENT_HEADATMARKER);
   1144  if (res != SL_RESULT_SUCCESS) {
   1145    LOG("Failed to set headatmarker event mask. Error code: %u", res);
   1146    return CUBEB_ERROR;
   1147  }
   1148  // get the simple android buffer queue interface
   1149  res = (*stm->recorderObj)
   1150            ->GetInterface(stm->recorderObj,
   1151                           stm->context->SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
   1152                           &stm->recorderBufferQueueItf);
   1153  if (res != SL_RESULT_SUCCESS) {
   1154    LOG("Failed to get recorder (android) buffer queue interface. Error code: "
   1155        "%u",
   1156        res);
   1157    return CUBEB_ERROR;
   1158  }
   1159 
   1160  // register callback on record (input) buffer queue
   1161  slAndroidSimpleBufferQueueCallback rec_callback = recorder_callback;
   1162  if (stm->output_enabled) {
   1163    // Register full duplex callback instead.
   1164    rec_callback = recorder_fullduplex_callback;
   1165  }
   1166  res = (*stm->recorderBufferQueueItf)
   1167            ->RegisterCallback(stm->recorderBufferQueueItf, rec_callback, stm);
   1168  if (res != SL_RESULT_SUCCESS) {
   1169    LOG("Failed to register recorder buffer queue callback. Error code: %u",
   1170        res);
   1171    return CUBEB_ERROR;
   1172  }
   1173 
   1174  // Calculate length of input buffer according to requested latency
   1175  uint32_t sample_size = 0;
   1176  if (params->format == CUBEB_SAMPLE_FLOAT32BE ||
   1177      params->format == CUBEB_SAMPLE_FLOAT32NE) {
   1178    sample_size = sizeof(float);
   1179  } else {
   1180    sample_size = sizeof(int16_t);
   1181  }
   1182  stm->input_frame_size = params->channels * sample_size;
   1183  stm->input_buffer_length = (stm->input_frame_size * stm->buffer_size_frames);
   1184 
   1185  // Calculate the capacity of input array
   1186  stm->input_array_capacity = NBUFS;
   1187  if (stm->output_enabled) {
   1188    // Full duplex, update capacity to hold 1 sec of data
   1189    stm->input_array_capacity =
   1190        1 * stm->input_device_rate / stm->input_buffer_length;
   1191  }
   1192  // Allocate input array
   1193  stm->input_buffer_array =
   1194      (void **)calloc(1, sizeof(void *) * stm->input_array_capacity);
   1195  // Buffering has not started yet.
   1196  stm->input_buffer_index = -1;
   1197  // Prepare input buffers
   1198  for (uint32_t i = 0; i < stm->input_array_capacity; ++i) {
   1199    stm->input_buffer_array[i] = calloc(1, stm->input_buffer_length);
   1200  }
   1201 
   1202  // On full duplex allocate input queue and silent buffer
   1203  if (stm->output_enabled) {
   1204    stm->input_queue = array_queue_create(stm->input_array_capacity);
   1205    XASSERT(stm->input_queue);
   1206    stm->input_silent_buffer = calloc(1, stm->input_buffer_length);
   1207    XASSERT(stm->input_silent_buffer);
   1208  }
   1209 
   1210  // Enqueue buffer to start rolling once recorder started
   1211  rv = opensl_enqueue_recorder(stm, nullptr);
   1212  if (rv != CUBEB_OK) {
   1213    return rv;
   1214  }
   1215 
   1216  LOG("Cubeb stream init recorder success");
   1217 
   1218  return CUBEB_OK;
   1219 }
   1220 
   1221 static int
   1222 opensl_configure_playback(cubeb_stream * stm, cubeb_stream_params * params)
   1223 {
   1224  XASSERT(stm);
   1225  XASSERT(params);
   1226 
   1227  stm->user_output_rate = params->rate;
   1228  stm->lastPosition = -1;
   1229  stm->lastPositionTimeStamp = 0;
   1230  stm->lastCompensativePosition = -1;
   1231 
   1232  int rv = initialize_with_format(
   1233      stm, params,
   1234      [=](void * format, uint32_t * format_sample_rate, bool using_floats) {
   1235        SLDataLocator_BufferQueue loc_bufq;
   1236        loc_bufq.locatorType = SL_DATALOCATOR_BUFFERQUEUE;
   1237        loc_bufq.numBuffers = NBUFS;
   1238        SLDataSource source;
   1239        source.pLocator = &loc_bufq;
   1240        source.pFormat = format;
   1241        SLDataLocator_OutputMix loc_outmix;
   1242        loc_outmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
   1243        loc_outmix.outputMix = stm->context->outmixObj;
   1244 
   1245        SLDataSink sink;
   1246        sink.pLocator = &loc_outmix;
   1247        sink.pFormat = nullptr;
   1248 
   1249 #if defined(__ANDROID__)
   1250        const SLInterfaceID ids[] = {stm->context->SL_IID_BUFFERQUEUE,
   1251                                     stm->context->SL_IID_VOLUME,
   1252                                     stm->context->SL_IID_ANDROIDCONFIGURATION};
   1253        const SLboolean req[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE,
   1254                                 SL_BOOLEAN_TRUE};
   1255 #else
   1256        const SLInterfaceID ids[] = {ctx->SL_IID_BUFFERQUEUE,
   1257                                     ctx->SL_IID_VOLUME};
   1258        const SLboolean req[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
   1259 #endif
   1260        XASSERT(NELEMS(ids) == NELEMS(req));
   1261 
   1262        uint32_t preferred_sampling_rate = stm->user_output_rate;
   1263        SLresult res = SL_RESULT_CONTENT_UNSUPPORTED;
   1264        if (preferred_sampling_rate) {
   1265          res = (*stm->context->eng)
   1266                    ->CreateAudioPlayer(stm->context->eng, &stm->playerObj,
   1267                                        &source, &sink, NELEMS(ids), ids, req);
   1268        }
   1269 
   1270        // Sample rate not supported? Try again with primary sample rate!
   1271        if (res == SL_RESULT_CONTENT_UNSUPPORTED &&
   1272            preferred_sampling_rate != DEFAULT_SAMPLE_RATE) {
   1273          preferred_sampling_rate = DEFAULT_SAMPLE_RATE;
   1274          *format_sample_rate = preferred_sampling_rate * 1000;
   1275          res = (*stm->context->eng)
   1276                    ->CreateAudioPlayer(stm->context->eng, &stm->playerObj,
   1277                                        &source, &sink, NELEMS(ids), ids, req);
   1278        }
   1279 
   1280        if (res != SL_RESULT_SUCCESS) {
   1281          LOG("Failed to create audio player. Error code: %u", res);
   1282          return CUBEB_ERROR;
   1283        }
   1284        stm->output_configured_rate = preferred_sampling_rate;
   1285 
   1286        // It's always possible to use int16 regardless of the Android version.
   1287        // However if compiling for older Android version, it's possible to
   1288        // request f32 audio, but Android only supports int16, in which case a
   1289        // conversion need to happen.
   1290        if ((params->format == CUBEB_SAMPLE_FLOAT32NE ||
   1291             params->format == CUBEB_SAMPLE_FLOAT32BE) &&
   1292            !using_floats) {
   1293          // setup conversion from f32 to int16
   1294          LOG("Input stream configured for using float, but not supported: a "
   1295              "conversion will be performed");
   1296          stm->conversion_buffer_output.resize(1);
   1297        }
   1298 
   1299        if (!using_floats) {
   1300          stm->framesize = params->channels * sizeof(int16_t);
   1301        } else {
   1302          stm->framesize = params->channels * sizeof(float);
   1303        }
   1304        return CUBEB_OK;
   1305      });
   1306 
   1307  if (rv != CUBEB_OK) {
   1308    LOG("Couldn't set format on sink or source");
   1309    return rv;
   1310  }
   1311 
   1312  stm->bytespersec = stm->output_configured_rate * stm->framesize;
   1313  stm->queuebuf_len = stm->framesize * stm->buffer_size_frames;
   1314 
   1315  // Calculate the capacity of input array
   1316  stm->queuebuf_capacity = NBUFS;
   1317  // Allocate input arrays
   1318  stm->queuebuf = (void **)calloc(1, sizeof(void *) * stm->queuebuf_capacity);
   1319  for (uint32_t i = 0; i < stm->queuebuf_capacity; ++i) {
   1320    stm->queuebuf[i] = calloc(1, stm->queuebuf_len);
   1321    XASSERT(stm->queuebuf[i]);
   1322  }
   1323 
   1324  SLAndroidConfigurationItf playerConfig = nullptr;
   1325 
   1326  SLresult res;
   1327  if (get_android_version() >= ANDROID_VERSION_N_MR1) {
   1328    res = (*stm->playerObj)
   1329              ->GetInterface(stm->playerObj,
   1330                             stm->context->SL_IID_ANDROIDCONFIGURATION,
   1331                             &playerConfig);
   1332    if (res != SL_RESULT_SUCCESS) {
   1333      LOG("Failed to get Android configuration interface. Error code: %u", res);
   1334      return CUBEB_ERROR;
   1335    }
   1336 
   1337    SLint32 streamType = SL_ANDROID_STREAM_MEDIA;
   1338    if (stm->voice_output) {
   1339      streamType = SL_ANDROID_STREAM_VOICE;
   1340    }
   1341    res = (*playerConfig)
   1342              ->SetConfiguration(playerConfig, SL_ANDROID_KEY_STREAM_TYPE,
   1343                                 &streamType, sizeof(streamType));
   1344    if (res != SL_RESULT_SUCCESS) {
   1345      LOG("Failed to set Android configuration to %d Error code: %u",
   1346          streamType, res);
   1347    }
   1348 
   1349    SLuint32 performanceMode = SL_ANDROID_PERFORMANCE_LATENCY;
   1350    if (stm->buffer_size_frames > POWERSAVE_LATENCY_FRAMES_THRESHOLD) {
   1351      LOG("Audio stream configured for power saving");
   1352      performanceMode = SL_ANDROID_PERFORMANCE_POWER_SAVING;
   1353    }
   1354 
   1355    res = (*playerConfig)
   1356              ->SetConfiguration(playerConfig, SL_ANDROID_KEY_PERFORMANCE_MODE,
   1357                                 &performanceMode, sizeof(performanceMode));
   1358    if (res != SL_RESULT_SUCCESS) {
   1359      LOG("Failed to set Android performance mode to %d Error code: %u. This "
   1360          "is not fatal.",
   1361          performanceMode, res);
   1362    }
   1363  }
   1364 
   1365  res = (*stm->playerObj)->Realize(stm->playerObj, SL_BOOLEAN_FALSE);
   1366  if (res != SL_RESULT_SUCCESS) {
   1367    LOG("Failed to realize player object. Error code: %u", res);
   1368    return CUBEB_ERROR;
   1369  }
   1370 
   1371  // There are two ways of getting the audio output latency:
   1372  // - a configuration value, only available on some devices (notably devices
   1373  // running FireOS)
   1374  // - A Java method, that we call using JNI.
   1375  //
   1376  // The first method is prefered, if available, because it can account for more
   1377  // latency causes, and is more precise.
   1378 
   1379  // Latency has to be queried after the realization of the interface, when
   1380  // using SL_IID_ANDROIDCONFIGURATION.
   1381  SLuint32 audioLatency = 0;
   1382  SLuint32 paramSize = sizeof(SLuint32);
   1383  // The reported latency is in milliseconds.
   1384  if (playerConfig) {
   1385    res = (*playerConfig)
   1386              ->GetConfiguration(playerConfig,
   1387                                 (const SLchar *)"androidGetAudioLatency",
   1388                                 &paramSize, &audioLatency);
   1389    if (res == SL_RESULT_SUCCESS) {
   1390      LOG("Got playback latency using android configuration extension");
   1391      stm->output_latency_ms = audioLatency;
   1392    }
   1393  }
   1394  // `playerConfig` is available, but the above failed, or `playerConfig` is not
   1395  // available. In both cases, we need to acquire the output latency by an other
   1396  // mean.
   1397  if ((playerConfig && res != SL_RESULT_SUCCESS) || !playerConfig) {
   1398    if (cubeb_output_latency_method_is_loaded(
   1399            stm->context->p_output_latency_function)) {
   1400      LOG("Got playback latency using JNI");
   1401      stm->output_latency_ms =
   1402          cubeb_get_output_latency(stm->context->p_output_latency_function);
   1403    } else {
   1404      LOG("No alternate latency querying method loaded, A/V sync will be off.");
   1405      stm->output_latency_ms = 0;
   1406    }
   1407  }
   1408 
   1409  LOG("Audio output latency: %dms", stm->output_latency_ms);
   1410 
   1411  res =
   1412      (*stm->playerObj)
   1413          ->GetInterface(stm->playerObj, stm->context->SL_IID_PLAY, &stm->play);
   1414  if (res != SL_RESULT_SUCCESS) {
   1415    LOG("Failed to get play interface. Error code: %u", res);
   1416    return CUBEB_ERROR;
   1417  }
   1418 
   1419  res = (*stm->playerObj)
   1420            ->GetInterface(stm->playerObj, stm->context->SL_IID_BUFFERQUEUE,
   1421                           &stm->bufq);
   1422  if (res != SL_RESULT_SUCCESS) {
   1423    LOG("Failed to get bufferqueue interface. Error code: %u", res);
   1424    return CUBEB_ERROR;
   1425  }
   1426 
   1427  res = (*stm->playerObj)
   1428            ->GetInterface(stm->playerObj, stm->context->SL_IID_VOLUME,
   1429                           &stm->volume);
   1430  if (res != SL_RESULT_SUCCESS) {
   1431    LOG("Failed to get volume interface. Error code: %u", res);
   1432    return CUBEB_ERROR;
   1433  }
   1434 
   1435  res = (*stm->play)->RegisterCallback(stm->play, play_callback, stm);
   1436  if (res != SL_RESULT_SUCCESS) {
   1437    LOG("Failed to register play callback. Error code: %u", res);
   1438    return CUBEB_ERROR;
   1439  }
   1440 
   1441  // Work around wilhelm/AudioTrack badness, bug 1221228
   1442  (*stm->play)->SetMarkerPosition(stm->play, (SLmillisecond)0);
   1443 
   1444  res = (*stm->play)
   1445            ->SetCallbackEventsMask(stm->play,
   1446                                    (SLuint32)SL_PLAYEVENT_HEADATMARKER);
   1447  if (res != SL_RESULT_SUCCESS) {
   1448    LOG("Failed to set headatmarker event mask. Error code: %u", res);
   1449    return CUBEB_ERROR;
   1450  }
   1451 
   1452  slBufferQueueCallback player_callback = bufferqueue_callback;
   1453  if (stm->input_enabled) {
   1454    player_callback = player_fullduplex_callback;
   1455  }
   1456  res = (*stm->bufq)->RegisterCallback(stm->bufq, player_callback, stm);
   1457  if (res != SL_RESULT_SUCCESS) {
   1458    LOG("Failed to register bufferqueue callback. Error code: %u", res);
   1459    return CUBEB_ERROR;
   1460  }
   1461 
   1462  {
   1463    // Enqueue a silent frame so once the player becomes playing, the frame
   1464    // will be consumed and kick off the buffer queue callback.
   1465    // Note the duration of a single frame is less than 1ms. We don't bother
   1466    // adjusting the playback position.
   1467    uint8_t * buf =
   1468        reinterpret_cast<uint8_t *>(stm->queuebuf[stm->queuebuf_idx++]);
   1469    memset(buf, 0, stm->framesize);
   1470    res = (*stm->bufq)->Enqueue(stm->bufq, buf, stm->framesize);
   1471    XASSERT(res == SL_RESULT_SUCCESS);
   1472  }
   1473 
   1474  LOG("Cubeb stream init playback success");
   1475  return CUBEB_OK;
   1476 }
   1477 
   1478 static int
   1479 opensl_validate_stream_param(cubeb_stream_params * stream_params)
   1480 {
   1481  if ((stream_params &&
   1482       (stream_params->channels < 1 || stream_params->channels > 32))) {
   1483    return CUBEB_ERROR_INVALID_FORMAT;
   1484  }
   1485  if ((stream_params && (stream_params->prefs & CUBEB_STREAM_PREF_LOOPBACK))) {
   1486    LOG("Loopback is not supported");
   1487    return CUBEB_ERROR_NOT_SUPPORTED;
   1488  }
   1489  return CUBEB_OK;
   1490 }
   1491 
   1492 int
   1493 has_pref_set(cubeb_stream_params * input_params,
   1494             cubeb_stream_params * output_params, cubeb_stream_prefs pref)
   1495 {
   1496  return (input_params && input_params->prefs & pref) ||
   1497         (output_params && output_params->prefs & pref);
   1498 }
   1499 
   1500 static int
   1501 opensl_stream_init(cubeb * ctx, cubeb_stream ** stream,
   1502                   char const * stream_name, cubeb_devid input_device,
   1503                   cubeb_stream_params * input_stream_params,
   1504                   cubeb_devid output_device,
   1505                   cubeb_stream_params * output_stream_params,
   1506                   unsigned int latency_frames,
   1507                   cubeb_data_callback data_callback,
   1508                   cubeb_state_callback state_callback, void * user_ptr)
   1509 {
   1510  cubeb_stream * stm = nullptr;
   1511  cubeb_async_log_reset_threads();
   1512 
   1513  XASSERT(ctx);
   1514  if (input_device || output_device) {
   1515    LOG("Device selection is not supported in Android. The default will be "
   1516        "used");
   1517  }
   1518 
   1519  *stream = nullptr;
   1520 
   1521  int r = opensl_validate_stream_param(output_stream_params);
   1522  if (r != CUBEB_OK) {
   1523    LOG("Output stream params not valid");
   1524    return r;
   1525  }
   1526  r = opensl_validate_stream_param(input_stream_params);
   1527  if (r != CUBEB_OK) {
   1528    LOG("Input stream params not valid");
   1529    return r;
   1530  }
   1531 
   1532  stm = reinterpret_cast<cubeb_stream *>(calloc(1, sizeof(*stm)));
   1533  XASSERT(stm);
   1534 
   1535  if (input_stream_params) {
   1536    stm->input_params =
   1537        std::make_unique<cubeb_stream_params>(*input_stream_params);
   1538  }
   1539  if (output_stream_params) {
   1540    stm->output_params =
   1541        std::make_unique<cubeb_stream_params>(*output_stream_params);
   1542  }
   1543 
   1544  stm->context = ctx;
   1545  stm->data_callback = data_callback;
   1546  stm->state_callback = state_callback;
   1547  stm->user_ptr = user_ptr;
   1548  stm->buffer_size_frames =
   1549      latency_frames ? latency_frames : DEFAULT_NUM_OF_FRAMES;
   1550  stm->input_enabled = (input_stream_params) ? 1 : 0;
   1551  stm->output_enabled = (output_stream_params) ? 1 : 0;
   1552  stm->shutdown = 1;
   1553  stm->voice_input =
   1554      has_pref_set(input_stream_params, nullptr, CUBEB_STREAM_PREF_VOICE);
   1555  stm->voice_output =
   1556      has_pref_set(nullptr, output_stream_params, CUBEB_STREAM_PREF_VOICE);
   1557 
   1558  LOG("cubeb stream prefs: voice_input: %s voice_output: %s",
   1559      stm->voice_input ? "true" : "false",
   1560      stm->voice_output ? "true" : "false");
   1561 
   1562 #ifdef DEBUG
   1563  pthread_mutexattr_t attr;
   1564  pthread_mutexattr_init(&attr);
   1565  pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
   1566  r = pthread_mutex_init(&stm->mutex, &attr);
   1567 #else
   1568  r = pthread_mutex_init(&stm->mutex, nullptr);
   1569 #endif
   1570  XASSERT(r == 0);
   1571 
   1572  if (output_stream_params) {
   1573    LOG("Playback params: Rate %d, channels %d, format %d, latency in frames "
   1574        "%d.",
   1575        output_stream_params->rate, output_stream_params->channels,
   1576        output_stream_params->format, stm->buffer_size_frames);
   1577    r = opensl_configure_playback(stm, output_stream_params);
   1578    if (r != CUBEB_OK) {
   1579      LOG("Error: playback-side configuration error, exiting.");
   1580      opensl_stream_destroy(stm);
   1581      return r;
   1582    }
   1583  }
   1584 
   1585  if (input_stream_params) {
   1586    LOG("Capture params: Rate %d, channels %d, format %d, latency in frames "
   1587        "%d.",
   1588        input_stream_params->rate, input_stream_params->channels,
   1589        input_stream_params->format, stm->buffer_size_frames);
   1590    r = opensl_configure_capture(stm, input_stream_params);
   1591    if (r != CUBEB_OK) {
   1592      LOG("Error: record-side configuration error, exiting.");
   1593      opensl_stream_destroy(stm);
   1594      return r;
   1595    }
   1596  }
   1597 
   1598  /* Configure resampler*/
   1599  uint32_t target_sample_rate;
   1600  if (input_stream_params) {
   1601    target_sample_rate = input_stream_params->rate;
   1602  } else {
   1603    XASSERT(output_stream_params);
   1604    target_sample_rate = output_stream_params->rate;
   1605  }
   1606 
   1607  // Use the actual configured rates for input
   1608  // and output.
   1609  cubeb_stream_params input_params;
   1610  if (input_stream_params) {
   1611    input_params = *input_stream_params;
   1612    input_params.rate = stm->input_device_rate;
   1613  }
   1614  cubeb_stream_params output_params;
   1615  if (output_stream_params) {
   1616    output_params = *output_stream_params;
   1617    output_params.rate = stm->output_configured_rate;
   1618  }
   1619 
   1620  stm->resampler = cubeb_resampler_create(
   1621      stm, input_stream_params ? &input_params : nullptr,
   1622      output_stream_params ? &output_params : nullptr, target_sample_rate,
   1623      data_callback, user_ptr, CUBEB_RESAMPLER_QUALITY_DEFAULT,
   1624      CUBEB_RESAMPLER_RECLOCK_NONE);
   1625  if (!stm->resampler) {
   1626    LOG("Failed to create resampler");
   1627    opensl_stream_destroy(stm);
   1628    return CUBEB_ERROR;
   1629  }
   1630 
   1631  *stream = stm;
   1632  LOG("Cubeb stream (%p) init success", stm);
   1633  return CUBEB_OK;
   1634 }
   1635 
   1636 static int
   1637 opensl_start_player(cubeb_stream * stm)
   1638 {
   1639  XASSERT(stm->playerObj);
   1640  SLuint32 playerState;
   1641  (*stm->playerObj)->GetState(stm->playerObj, &playerState);
   1642  if (playerState == SL_OBJECT_STATE_REALIZED) {
   1643    SLresult res = (*stm->play)->SetPlayState(stm->play, SL_PLAYSTATE_PLAYING);
   1644    if (res != SL_RESULT_SUCCESS) {
   1645      LOG("Failed to start player. Error code: %u", res);
   1646      return CUBEB_ERROR;
   1647    }
   1648  }
   1649  return CUBEB_OK;
   1650 }
   1651 
   1652 static int
   1653 opensl_start_recorder(cubeb_stream * stm)
   1654 {
   1655  XASSERT(stm->recorderObj);
   1656  SLuint32 recorderState;
   1657  (*stm->recorderObj)->GetState(stm->recorderObj, &recorderState);
   1658  if (recorderState == SL_OBJECT_STATE_REALIZED) {
   1659    SLresult res =
   1660        (*stm->recorderItf)
   1661            ->SetRecordState(stm->recorderItf, SL_RECORDSTATE_RECORDING);
   1662    if (res != SL_RESULT_SUCCESS) {
   1663      LOG("Failed to start recorder. Error code: %u", res);
   1664      return CUBEB_ERROR;
   1665    }
   1666  }
   1667  return CUBEB_OK;
   1668 }
   1669 
   1670 static int
   1671 opensl_stream_start(cubeb_stream * stm)
   1672 {
   1673  XASSERT(stm);
   1674 
   1675  int r = pthread_mutex_lock(&stm->mutex);
   1676  XASSERT(r == 0);
   1677  opensl_set_shutdown(stm, 0);
   1678  opensl_set_draining(stm, 0);
   1679  r = pthread_mutex_unlock(&stm->mutex);
   1680  XASSERT(r == 0);
   1681 
   1682  if (stm->playerObj) {
   1683    r = opensl_start_player(stm);
   1684    if (r != CUBEB_OK) {
   1685      return r;
   1686    }
   1687  }
   1688 
   1689  if (stm->recorderObj) {
   1690    int r = opensl_start_recorder(stm);
   1691    if (r != CUBEB_OK) {
   1692      return r;
   1693    }
   1694  }
   1695 
   1696  stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_STARTED);
   1697  LOG("Cubeb stream (%p) started", stm);
   1698  return CUBEB_OK;
   1699 }
   1700 
   1701 static int
   1702 opensl_stop_player(cubeb_stream * stm)
   1703 {
   1704  XASSERT(stm->playerObj);
   1705  XASSERT(stm->shutdown || stm->draining);
   1706 
   1707  SLresult res = (*stm->play)->SetPlayState(stm->play, SL_PLAYSTATE_PAUSED);
   1708  if (res != SL_RESULT_SUCCESS) {
   1709    LOG("Failed to stop player. Error code: %u", res);
   1710    return CUBEB_ERROR;
   1711  }
   1712 
   1713  return CUBEB_OK;
   1714 }
   1715 
   1716 static int
   1717 opensl_stop_recorder(cubeb_stream * stm)
   1718 {
   1719  XASSERT(stm->recorderObj);
   1720  XASSERT(stm->shutdown || stm->draining);
   1721 
   1722  SLresult res = (*stm->recorderItf)
   1723                     ->SetRecordState(stm->recorderItf, SL_RECORDSTATE_PAUSED);
   1724  if (res != SL_RESULT_SUCCESS) {
   1725    LOG("Failed to stop recorder. Error code: %u", res);
   1726    return CUBEB_ERROR;
   1727  }
   1728 
   1729  return CUBEB_OK;
   1730 }
   1731 
   1732 static int
   1733 opensl_stream_stop(cubeb_stream * stm)
   1734 {
   1735  XASSERT(stm);
   1736 
   1737  int r = pthread_mutex_lock(&stm->mutex);
   1738  XASSERT(r == 0);
   1739  opensl_set_shutdown(stm, 1);
   1740  r = pthread_mutex_unlock(&stm->mutex);
   1741  XASSERT(r == 0);
   1742 
   1743  if (stm->playerObj) {
   1744    r = opensl_stop_player(stm);
   1745    if (r != CUBEB_OK) {
   1746      return r;
   1747    }
   1748  }
   1749 
   1750  if (stm->recorderObj) {
   1751    int r = opensl_stop_recorder(stm);
   1752    if (r != CUBEB_OK) {
   1753      return r;
   1754    }
   1755  }
   1756 
   1757  stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_STOPPED);
   1758  LOG("Cubeb stream (%p) stopped", stm);
   1759  return CUBEB_OK;
   1760 }
   1761 
   1762 static int
   1763 opensl_destroy_recorder(cubeb_stream * stm)
   1764 {
   1765  XASSERT(stm);
   1766  XASSERT(stm->recorderObj);
   1767 
   1768  if (stm->recorderBufferQueueItf) {
   1769    SLresult res =
   1770        (*stm->recorderBufferQueueItf)->Clear(stm->recorderBufferQueueItf);
   1771    if (res != SL_RESULT_SUCCESS) {
   1772      LOG("Failed to clear recorder buffer queue. Error code: %u", res);
   1773      return CUBEB_ERROR;
   1774    }
   1775    stm->recorderBufferQueueItf = nullptr;
   1776    for (uint32_t i = 0; i < stm->input_array_capacity; ++i) {
   1777      free(stm->input_buffer_array[i]);
   1778    }
   1779  }
   1780 
   1781  (*stm->recorderObj)->Destroy(stm->recorderObj);
   1782  stm->recorderObj = nullptr;
   1783  stm->recorderItf = nullptr;
   1784 
   1785  if (stm->input_queue) {
   1786    array_queue_destroy(stm->input_queue);
   1787  }
   1788  free(stm->input_silent_buffer);
   1789 
   1790  return CUBEB_OK;
   1791 }
   1792 
   1793 static void
   1794 opensl_stream_destroy(cubeb_stream * stm)
   1795 {
   1796  XASSERT(stm->draining || stm->shutdown);
   1797 
   1798  // If we're still draining at stream destroy time, pause the streams now so we
   1799  // can destroy them safely.
   1800  if (stm->draining) {
   1801    opensl_stream_stop(stm);
   1802  }
   1803  // Sleep for 10ms to give active streams time to pause so that no further
   1804  // buffer callbacks occur.  Inspired by the same workaround (sleepBeforeClose)
   1805  // in liboboe.
   1806  usleep(10 * 1000);
   1807 
   1808  if (stm->playerObj) {
   1809    (*stm->playerObj)->Destroy(stm->playerObj);
   1810    stm->playerObj = nullptr;
   1811    stm->play = nullptr;
   1812    stm->bufq = nullptr;
   1813    for (uint32_t i = 0; i < stm->queuebuf_capacity; ++i) {
   1814      free(stm->queuebuf[i]);
   1815    }
   1816  }
   1817 
   1818  if (stm->recorderObj) {
   1819    int r = opensl_destroy_recorder(stm);
   1820    XASSERT(r == CUBEB_OK);
   1821  }
   1822 
   1823  if (stm->resampler) {
   1824    cubeb_resampler_destroy(stm->resampler);
   1825  }
   1826 
   1827  pthread_mutex_destroy(&stm->mutex);
   1828 
   1829  LOG("Cubeb stream (%p) destroyed", stm);
   1830  free(stm);
   1831 }
   1832 
   1833 static int
   1834 opensl_stream_get_position(cubeb_stream * stm, uint64_t * position)
   1835 {
   1836  SLmillisecond msec;
   1837  uint32_t compensation_msec = 0;
   1838  SLresult res;
   1839 
   1840  res = (*stm->play)->GetPosition(stm->play, &msec);
   1841  if (res != SL_RESULT_SUCCESS) {
   1842    return CUBEB_ERROR;
   1843  }
   1844 
   1845  timespec t{};
   1846  clock_gettime(CLOCK_MONOTONIC, &t);
   1847  if (stm->lastPosition == msec) {
   1848    compensation_msec =
   1849        (t.tv_sec * 1000000000LL + t.tv_nsec - stm->lastPositionTimeStamp) /
   1850        1000000;
   1851  } else {
   1852    stm->lastPositionTimeStamp = t.tv_sec * 1000000000LL + t.tv_nsec;
   1853    stm->lastPosition = msec;
   1854  }
   1855 
   1856  uint64_t samplerate = stm->user_output_rate;
   1857  uint32_t output_latency = stm->output_latency_ms;
   1858 
   1859  XASSERT(stm->written >= 0);
   1860  XASSERT(stm->user_output_rate > 0);
   1861  XASSERT(stm->output_configured_rate > 0);
   1862  pthread_mutex_lock(&stm->mutex);
   1863  int64_t maximum_position = stm->written * (int64_t)stm->user_output_rate /
   1864                             stm->output_configured_rate;
   1865  pthread_mutex_unlock(&stm->mutex);
   1866  XASSERT(maximum_position >= 0);
   1867 
   1868  if (msec > output_latency) {
   1869    int64_t unadjusted_position;
   1870    if (stm->lastCompensativePosition > msec + compensation_msec) {
   1871      // Over compensation, use lastCompensativePosition.
   1872      unadjusted_position =
   1873          samplerate * (stm->lastCompensativePosition - output_latency) / 1000;
   1874    } else {
   1875      unadjusted_position =
   1876          samplerate * (msec - output_latency + compensation_msec) / 1000;
   1877      stm->lastCompensativePosition = msec + compensation_msec;
   1878    }
   1879    *position = unadjusted_position < maximum_position ? unadjusted_position
   1880                                                       : maximum_position;
   1881  } else {
   1882    *position = 0;
   1883  }
   1884  return CUBEB_OK;
   1885 }
   1886 
   1887 static int
   1888 opensl_stream_get_latency(cubeb_stream * stm, uint32_t * latency)
   1889 {
   1890  XASSERT(stm);
   1891  XASSERT(latency);
   1892 
   1893  uint32_t stream_latency_frames =
   1894      stm->user_output_rate * stm->output_latency_ms / 1000;
   1895 
   1896  *latency = static_cast<int>(stream_latency_frames +
   1897                              cubeb_resampler_latency(stm->resampler));
   1898 
   1899  return CUBEB_OK;
   1900 }
   1901 
   1902 int
   1903 opensl_stream_set_volume(cubeb_stream * stm, float volume)
   1904 {
   1905  SLresult res;
   1906  SLmillibel max_level, millibels;
   1907  float unclamped_millibels;
   1908 
   1909  res = (*stm->volume)->GetMaxVolumeLevel(stm->volume, &max_level);
   1910 
   1911  if (res != SL_RESULT_SUCCESS) {
   1912    return CUBEB_ERROR;
   1913  }
   1914 
   1915  /* millibels are 100*dB, so the conversion from the volume's linear amplitude
   1916   * is 100 * 20 * log(volume). However we clamp the resulting value before
   1917   * passing it to lroundf() in order to prevent it from silently returning an
   1918   * erroneous value when the unclamped value exceeds the size of a long. */
   1919  unclamped_millibels = 100.0f * 20.0f * log10f(fmaxf(volume, 0.0f));
   1920  unclamped_millibels = fmaxf(unclamped_millibels, SL_MILLIBEL_MIN);
   1921  unclamped_millibels = fminf(unclamped_millibels, max_level);
   1922 
   1923  millibels = static_cast<SLmillibel>(lroundf(unclamped_millibels));
   1924 
   1925  res = (*stm->volume)->SetVolumeLevel(stm->volume, millibels);
   1926 
   1927  if (res != SL_RESULT_SUCCESS) {
   1928    return CUBEB_ERROR;
   1929  }
   1930  return CUBEB_OK;
   1931 }
   1932 
   1933 struct cubeb_ops const opensl_ops = {
   1934    .init = opensl_init,
   1935    .get_backend_id = opensl_get_backend_id,
   1936    .get_max_channel_count = opensl_get_max_channel_count,
   1937    .get_min_latency = nullptr,
   1938    .get_preferred_sample_rate = nullptr,
   1939    .get_supported_input_processing_params = nullptr,
   1940    .enumerate_devices = nullptr,
   1941    .device_collection_destroy = nullptr,
   1942    .destroy = opensl_destroy,
   1943    .stream_init = opensl_stream_init,
   1944    .stream_destroy = opensl_stream_destroy,
   1945    .stream_start = opensl_stream_start,
   1946    .stream_stop = opensl_stream_stop,
   1947    .stream_get_position = opensl_stream_get_position,
   1948    .stream_get_latency = opensl_stream_get_latency,
   1949    .stream_get_input_latency = nullptr,
   1950    .stream_set_volume = opensl_stream_set_volume,
   1951    .stream_set_name = nullptr,
   1952    .stream_get_current_device = nullptr,
   1953    .stream_set_input_mute = nullptr,
   1954    .stream_set_input_processing_params = nullptr,
   1955    .stream_device_destroy = nullptr,
   1956    .stream_register_device_changed_callback = nullptr,
   1957    .register_device_collection_changed = nullptr};