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