1 /* RetroArch - A frontend for libretro.
2 * Copyright (C) 2010-2014 - Hans-Kristian Arntzen
3 * Copyright (C) 2011-2017 - Daniel De Matteis
4 *
5 * RetroArch is free software: you can redistribute it and/or modify it under the terms
6 * of the GNU General Public License as published by the Free Software Found-
7 * ation, either version 3 of the License, or (at your option) any later version.
8 *
9 * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
10 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11 * PURPOSE. See the GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along with RetroArch.
14 * If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include <SLES/OpenSLES.h>
18 #ifdef ANDROID
19 #include <SLES/OpenSLES_Android.h>
20 #endif
21
22 #include <rthreads/rthreads.h>
23
24 #include "../../retroarch.h"
25
26 /* Helper macros, COM-style. */
27 #define SLObjectItf_Realize(a, ...) ((*(a))->Realize(a, __VA_ARGS__))
28 #define SLObjectItf_GetInterface(a, ...) ((*(a))->GetInterface(a, __VA_ARGS__))
29 #define SLObjectItf_Destroy(a) ((*(a))->Destroy((a)))
30
31 #define SLEngineItf_CreateOutputMix(a, ...) ((*(a))->CreateOutputMix(a, __VA_ARGS__))
32 #define SLEngineItf_CreateAudioPlayer(a, ...) ((*(a))->CreateAudioPlayer(a, __VA_ARGS__))
33
34 #define SLPlayItf_SetPlayState(a, ...) ((*(a))->SetPlayState(a, __VA_ARGS__))
35
36 typedef struct sl
37 {
38 uint8_t **buffer;
39 uint8_t *buffer_chunk;
40
41 SLObjectItf engine_object;
42 SLEngineItf engine;
43
44 SLObjectItf output_mix;
45 SLObjectItf buffer_queue_object;
46 SLAndroidSimpleBufferQueueItf buffer_queue;
47 SLPlayItf player;
48
49 slock_t *lock;
50 scond_t *cond;
51 unsigned buf_size;
52 unsigned buf_count;
53 unsigned buffer_index;
54 unsigned buffer_ptr;
55 volatile unsigned buffered_blocks;
56 bool nonblock;
57 bool is_paused;
58 } sl_t;
59
opensl_callback(SLAndroidSimpleBufferQueueItf bq,void * ctx)60 static void opensl_callback(SLAndroidSimpleBufferQueueItf bq, void *ctx)
61 {
62 sl_t *sl = (sl_t*)ctx;
63 __sync_fetch_and_sub(&sl->buffered_blocks, 1);
64 scond_signal(sl->cond);
65 }
66
67 #define GOTO_IF_FAIL(x) do { \
68 if ((res = (x)) != SL_RESULT_SUCCESS) \
69 goto error; \
70 } while (0)
71
sl_free(void * data)72 static void sl_free(void *data)
73 {
74 sl_t *sl = (sl_t*)data;
75 if (!sl)
76 return;
77
78 if (sl->player)
79 SLPlayItf_SetPlayState(sl->player, SL_PLAYSTATE_STOPPED);
80
81 if (sl->buffer_queue_object)
82 SLObjectItf_Destroy(sl->buffer_queue_object);
83
84 if (sl->output_mix)
85 SLObjectItf_Destroy(sl->output_mix);
86
87 if (sl->engine_object)
88 SLObjectItf_Destroy(sl->engine_object);
89
90 if (sl->lock)
91 slock_free(sl->lock);
92 if (sl->cond)
93 scond_free(sl->cond);
94
95 free(sl->buffer);
96 free(sl->buffer_chunk);
97 free(sl);
98 }
99
sl_init(const char * device,unsigned rate,unsigned latency,unsigned block_frames,unsigned * new_rate)100 static void *sl_init(const char *device, unsigned rate, unsigned latency,
101 unsigned block_frames,
102 unsigned *new_rate)
103 {
104 unsigned i;
105 SLDataFormat_PCM fmt_pcm = {0};
106 SLDataSource audio_src = {0};
107 SLDataSink audio_sink = {0};
108 SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {0};
109 SLDataLocator_OutputMix loc_outmix = {0};
110 SLresult res = 0;
111 SLInterfaceID id = SL_IID_ANDROIDSIMPLEBUFFERQUEUE;
112 SLboolean req = SL_BOOLEAN_TRUE;
113 sl_t *sl = (sl_t*)calloc(1, sizeof(sl_t));
114
115 (void)device;
116 if (!sl)
117 goto error;
118
119 RARCH_LOG("[OpenSL]: Requested audio latency: %u ms.", latency);
120
121 GOTO_IF_FAIL(slCreateEngine(&sl->engine_object, 0, NULL, 0, NULL, NULL));
122 GOTO_IF_FAIL(SLObjectItf_Realize(sl->engine_object, SL_BOOLEAN_FALSE));
123 GOTO_IF_FAIL(SLObjectItf_GetInterface(sl->engine_object, SL_IID_ENGINE, &sl->engine));
124
125 GOTO_IF_FAIL(SLEngineItf_CreateOutputMix(sl->engine, &sl->output_mix, 0, NULL, NULL));
126 GOTO_IF_FAIL(SLObjectItf_Realize(sl->output_mix, SL_BOOLEAN_FALSE));
127
128 if (block_frames)
129 sl->buf_size = block_frames * 4;
130 else
131 sl->buf_size = next_pow2(32 * latency);
132
133 sl->buf_count = (latency * 4 * rate + 500) / 1000;
134 sl->buf_count = (sl->buf_count + sl->buf_size / 2) / sl->buf_size;
135
136 if (sl->buf_count < 2)
137 sl->buf_count = 2;
138
139 sl->buffer = (uint8_t**)calloc(sizeof(uint8_t*), sl->buf_count);
140 if (!sl->buffer)
141 goto error;
142
143 sl->buffer_chunk = (uint8_t*)calloc(sl->buf_count, sl->buf_size);
144 if (!sl->buffer_chunk)
145 goto error;
146
147 for (i = 0; i < sl->buf_count; i++)
148 sl->buffer[i] = sl->buffer_chunk + i * sl->buf_size;
149
150 RARCH_LOG("[OpenSL]: Setting audio latency: Block size = %u, Blocks = %u, Total = %u ...\n",
151 sl->buf_size, sl->buf_count, sl->buf_size * sl->buf_count);
152
153 fmt_pcm.formatType = SL_DATAFORMAT_PCM;
154 fmt_pcm.numChannels = 2;
155 fmt_pcm.samplesPerSec = rate * 1000; /* Samplerate is in milli-Hz. */
156 fmt_pcm.bitsPerSample = 16;
157 fmt_pcm.containerSize = 16;
158 fmt_pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
159 fmt_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN; /* Android only. */
160
161 audio_src.pLocator = &loc_bufq;
162 audio_src.pFormat = &fmt_pcm;
163
164 loc_bufq.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
165 loc_bufq.numBuffers = sl->buf_count;
166
167 loc_outmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
168 loc_outmix.outputMix = sl->output_mix;
169
170 audio_sink.pLocator = &loc_outmix;
171
172 GOTO_IF_FAIL(SLEngineItf_CreateAudioPlayer(sl->engine, &sl->buffer_queue_object,
173 &audio_src, &audio_sink,
174 1, &id, &req));
175 GOTO_IF_FAIL(SLObjectItf_Realize(sl->buffer_queue_object, SL_BOOLEAN_FALSE));
176
177 GOTO_IF_FAIL(SLObjectItf_GetInterface(sl->buffer_queue_object, SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
178 &sl->buffer_queue));
179
180 sl->cond = scond_new();
181 sl->lock = slock_new();
182
183 (*sl->buffer_queue)->RegisterCallback(sl->buffer_queue, opensl_callback, sl);
184
185 /* Enqueue a bit to get stuff rolling. */
186 sl->buffered_blocks = sl->buf_count;
187 sl->buffer_index = 0;
188
189 for (i = 0; i < sl->buf_count; i++)
190 (*sl->buffer_queue)->Enqueue(sl->buffer_queue, sl->buffer[i], sl->buf_size);
191
192 GOTO_IF_FAIL(SLObjectItf_GetInterface(sl->buffer_queue_object, SL_IID_PLAY, &sl->player));
193 GOTO_IF_FAIL(SLPlayItf_SetPlayState(sl->player, SL_PLAYSTATE_PLAYING));
194
195 return sl;
196
197 error:
198 RARCH_ERR("[OpenSL]: Couldn't initialize OpenSL ES driver, error code: [%d].\n", (int)res);
199 sl_free(sl);
200 return NULL;
201 }
202
sl_stop(void * data)203 static bool sl_stop(void *data)
204 {
205 sl_t *sl = (sl_t*)data;
206 sl->is_paused = (SLPlayItf_SetPlayState(sl->player, SL_PLAYSTATE_STOPPED)
207 == SL_RESULT_SUCCESS) ? true : false;
208
209 return sl->is_paused ? true : false;
210 }
211
sl_alive(void * data)212 static bool sl_alive(void *data)
213 {
214 sl_t *sl = (sl_t*)data;
215 if (!sl)
216 return false;
217 return !sl->is_paused;
218 }
219
sl_set_nonblock_state(void * data,bool state)220 static void sl_set_nonblock_state(void *data, bool state)
221 {
222 sl_t *sl = (sl_t*)data;
223 if (sl)
224 sl->nonblock = state;
225 }
226
sl_start(void * data,bool is_shutdown)227 static bool sl_start(void *data, bool is_shutdown)
228 {
229 sl_t *sl = (sl_t*)data;
230 sl->is_paused = (SLPlayItf_SetPlayState(sl->player, SL_PLAYSTATE_PLAYING)
231 == SL_RESULT_SUCCESS) ? false : true;
232 return sl->is_paused ? false : true;
233 }
234
sl_write(void * data,const void * buf_,size_t size)235 static ssize_t sl_write(void *data, const void *buf_, size_t size)
236 {
237 sl_t *sl = (sl_t*)data;
238 size_t written = 0;
239 const uint8_t *buf = (const uint8_t*)buf_;
240
241 while (size)
242 {
243 size_t avail_write;
244
245 if (sl->nonblock)
246 {
247 if (sl->buffered_blocks == sl->buf_count)
248 break;
249 }
250 else
251 {
252 slock_lock(sl->lock);
253 while (sl->buffered_blocks == sl->buf_count)
254 scond_wait(sl->cond, sl->lock);
255 slock_unlock(sl->lock);
256 }
257
258 avail_write = MIN(sl->buf_size - sl->buffer_ptr, size);
259
260 if (avail_write)
261 {
262 memcpy(sl->buffer[sl->buffer_index] + sl->buffer_ptr, buf, avail_write);
263 sl->buffer_ptr += avail_write;
264 buf += avail_write;
265 size -= avail_write;
266 written += avail_write;
267 }
268
269 if (sl->buffer_ptr >= sl->buf_size)
270 {
271 SLresult res = (*sl->buffer_queue)->Enqueue(sl->buffer_queue, sl->buffer[sl->buffer_index], sl->buf_size);
272 sl->buffer_index = (sl->buffer_index + 1) % sl->buf_count;
273 __sync_fetch_and_add(&sl->buffered_blocks, 1);
274 sl->buffer_ptr = 0;
275
276 if (res != SL_RESULT_SUCCESS)
277 {
278 RARCH_ERR("[OpenSL]: Failed to write! (Error: 0x%x)\n", (unsigned)res);
279 return -1;
280 }
281 }
282 }
283
284 return written;
285 }
286
sl_write_avail(void * data)287 static size_t sl_write_avail(void *data)
288 {
289 sl_t *sl = (sl_t*)data;
290 size_t avail = (sl->buf_count - (int)sl->buffered_blocks - 1) * sl->buf_size + (sl->buf_size - (int)sl->buffer_ptr);
291 return avail;
292 }
293
sl_buffer_size(void * data)294 static size_t sl_buffer_size(void *data)
295 {
296 sl_t *sl = (sl_t*)data;
297 return sl->buf_size * sl->buf_count;
298 }
299
sl_use_float(void * data)300 static bool sl_use_float(void *data)
301 {
302 (void)data;
303 return false;
304 }
305
306 audio_driver_t audio_opensl = {
307 sl_init,
308 sl_write,
309 sl_stop,
310 sl_start,
311 sl_alive,
312 sl_set_nonblock_state,
313 sl_free,
314 sl_use_float,
315 "opensl",
316 NULL,
317 NULL,
318 sl_write_avail,
319 sl_buffer_size,
320 };
321