/
SDL_openslES.c
628 lines (506 loc) · 19.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/*
Simple DirectMedia Layer
Copyright (C) 1997-2019 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_AUDIO_DRIVER_OPENSLES
#include "SDL_audio.h"
#include "../SDL_audio_c.h"
#include "SDL_openslES.h"
29
/* for native audio */
30
31
32
33
34
35
36
#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>
#include <android/log.h>
#define LOG_TAG "SDL_openslES"
37
38
39
40
41
42
#if 0
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
// #define LOGI(...) do {} while (0)
// #define LOGE(...) do {} while (0)
#else
43
44
#define LOGI(...)
#define LOGE(...)
45
#endif
46
47
/* engine interfaces */
48
49
50
static SLObjectItf engineObject = NULL;
static SLEngineItf engineEngine;
51
/* output mix interfaces */
52
static SLObjectItf outputMixObject = NULL;
53
// static SLEnvironmentalReverbItf outputMixEnvironmentalReverb = NULL;
54
55
56
/* aux effect on the output mix, used by the buffer queue player */
/* static const SLEnvironmentalReverbSettings reverbSettings = SL_I3DL2_ENVIRONMENT_PRESET_STONECORRIDOR; */
57
58
/* buffer queue player interfaces */
59
60
61
62
63
64
static SLObjectItf bqPlayerObject = NULL;
static SLPlayItf bqPlayerPlay = NULL;
static SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue = NULL;
/*static SLEffectSendItf bqPlayerEffectSend = NULL; */
static SLMuteSoloItf bqPlayerMuteSolo = NULL;
static SLVolumeItf bqPlayerVolume = NULL;
65
66
#if 0
67
/* recorder interfaces TODO */
68
69
70
71
static SLObjectItf recorderObject = NULL;
static SLRecordItf recorderRecord;
static SLAndroidSimpleBufferQueueItf recorderBufferQueue;
#endif
72
73
/* pointer and size of the next player buffer to enqueue, and number of remaining buffers */
74
75
76
77
78
#if 0
static short *nextBuffer;
static unsigned nextSize;
static int nextCount;
#endif
79
80
// static SDL_AudioDevice* audioDevice = NULL;
81
82
#if 0
83
84
85
86
87
static const char *sldevaudiorecorderstr = "SLES Audio Recorder";
static const char *sldevaudioplayerstr = "SLES Audio Player";
#define SLES_DEV_AUDIO_RECORDER sldevaudiorecorderstr
#define SLES_DEV_AUDIO_PLAYER sldevaudioplayerstr
88
89
static void openslES_DetectDevices( int iscapture )
{
90
LOGI( "openSLES_DetectDevices()" );
91
92
if ( iscapture )
addfn( SLES_DEV_AUDIO_RECORDER );
93
else
94
addfn( SLES_DEV_AUDIO_PLAYER );
95
return;
96
97
98
}
#endif
99
static void openslES_DestroyEngine();
100
101
static int
102
openslES_CreateEngine()
103
{
104
SLresult result;
105
106
LOGI("openSLES_CreateEngine()");
107
108
/* create engine */
109
110
111
112
113
result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
if (SL_RESULT_SUCCESS != result) {
LOGE("slCreateEngine failed");
goto error;
}
114
115
LOGI("slCreateEngine OK");
116
117
/* realize the engine */
118
119
120
121
122
result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
if (SL_RESULT_SUCCESS != result) {
LOGE("RealizeEngine failed");
goto error;
}
123
124
LOGI("RealizeEngine OK");
125
126
/* get the engine interface, which is needed in order to create other objects */
127
128
129
130
131
result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
if (SL_RESULT_SUCCESS != result) {
LOGE("EngineGetInterface failed");
goto error;
}
132
133
LOGI("EngineGetInterface OK");
134
135
136
137
/* create output mix, with environmental reverb specified as a non-required interface */
/* const SLInterfaceID ids[1] = { SL_IID_ENVIRONMENTALREVERB }; */
/* const SLboolean req[1] = { SL_BOOLEAN_FALSE }; */
138
139
140
141
const SLInterfaceID ids[1] = { SL_IID_VOLUME };
const SLboolean req[1] = { SL_BOOLEAN_FALSE };
result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 1, ids, req);
142
143
144
145
146
147
if (SL_RESULT_SUCCESS != result) {
LOGE("CreateOutputMix failed");
goto error;
}
LOGI("CreateOutputMix OK");
148
149
/* realize the output mix */
150
151
152
153
154
155
result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
if (SL_RESULT_SUCCESS != result) {
LOGE("RealizeOutputMix failed");
goto error;
}
return 1;
156
157
158
159
error:
openslES_DestroyEngine();
return 0;
160
161
}
162
163
static void openslES_DestroyPCMPlayer(_THIS);
static void openslES_DestroyPCMRecorder(_THIS);
164
165
static void openslES_DestroyEngine()
166
{
167
LOGI("openslES_DestroyEngine()");
168
169
170
// openslES_DestroyPCMPlayer(this);
// openslES_DestroyPCMRecorder(this);
171
172
/* destroy output mix object, and invalidate all associated interfaces */
173
174
175
if (outputMixObject != NULL) {
(*outputMixObject)->Destroy(outputMixObject);
outputMixObject = NULL;
176
/* outputMixEnvironmentalReverb = NULL; */
177
}
178
179
/* destroy engine object, and invalidate all associated interfaces */
180
181
182
183
184
if (engineObject != NULL) {
(*engineObject)->Destroy(engineObject);
engineObject = NULL;
engineEngine = NULL;
}
185
186
return;
187
188
}
189
/* this callback handler is called every time a buffer finishes playing */
190
191
static void
bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context)
192
{
193
struct SDL_PrivateAudioData *audiodata = (struct SDL_PrivateAudioData *) context;
194
195
static int t = 0;
196
197
/* assert(bq == bqPlayerBufferQueue); */
/* assert(NULL == context); */
198
199
/* for streaming playback, replace this test by logic to find and fill the next buffer */
200
#if 0
201
202
203
204
if (--nextCount > 0 && NULL != nextBuffer && 0 != nextSize)
{
SLresult result;
205
/* enqueue another buffer */
206
result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, nextBuffer, nextSize);
207
208
/* the most likely other result is SL_RESULT_BUFFER_INSUFFICIENT, */
/* which for this code example would indicate a programming error */
209
210
211
assert(SL_RESULT_SUCCESS == result);
(void) result;
}
212
#endif
213
LOGI("SLES: Playback Callmeback %u", t++);
214
SDL_SemPost(audiodata->playsem);
215
return;
216
217
}
218
219
static int
openslES_CreatePCMRecorder(_THIS)
220
{
221
222
/* struct SDL_PrivateAudioData *audiodata = (struct SDL_PrivateAudioData *) this->hidden; */
223
224
LOGE("openslES_CreatePCMRecorder not implimented yet!");
return SDL_SetError("openslES_CreatePCMRecorder not implimented yet!");
225
226
}
227
static void
228
openslES_DestroyPCMRecorder(_THIS)
229
{
230
231
/* struct SDL_PrivateAudioData *audiodata = (struct SDL_PrivateAudioData *) this->hidden; */
232
return;
233
234
}
235
static int
236
openslES_CreatePCMPlayer(_THIS)
237
{
238
239
struct SDL_PrivateAudioData *audiodata = (struct SDL_PrivateAudioData *) this->hidden;
240
SLDataFormat_PCM format_pcm;
241
242
SDL_AudioFormat test_format = 0;
243
244
SLresult result;
int i;
245
246
#if 0
247
248
test_format = SDL_FirstAudioFormat( this->spec.format );
249
250
while (test_format != 0) {
251
252
253
254
255
256
if (SDL_AUDIO_ISSIGNED(test_format) && SDL_AUDIO_ISINT(test_format)) {
break;
}
test_format = SDL_NextAudioFormat();
}
257
258
if ( test_format == 0 ) {
259
/* Didn't find a compatible format : */
260
261
262
LOGI( "No compatible audio format!" );
return SDL_SetError("No compatible audio format!");
}
263
264
this->spec.format = test_format;
265
#endif
266
267
/* Update the fragment size as size in bytes */
268
SDL_CalculateAudioSpec(&this->spec);
269
270
271
272
LOGI("Try to open %u hz %u bit chan %u %s samples %u",
this->spec.freq, SDL_AUDIO_BITSIZE(this->spec.format),
this->spec.channels, (test_format & 0x1000) ? "BE" : "LE", this->spec.samples);
273
274
/* configure audio source */
275
SLDataLocator_AndroidSimpleBufferQueue loc_bufq = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, NUM_BUFFERS };
276
277
278
format_pcm.formatType = SL_DATAFORMAT_PCM;
format_pcm.numChannels = this->spec.channels;
279
format_pcm.samplesPerSec = this->spec.freq * 1000; /* / kilo Hz to milli Hz */
280
281
format_pcm.bitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format);
format_pcm.containerSize = SDL_AUDIO_BITSIZE(this->spec.format);
282
283
284
285
286
287
if (SDL_AUDIO_ISBIGENDIAN(this->spec.format)) {
format_pcm.endianness = SL_BYTEORDER_BIGENDIAN;
} else {
format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
}
288
289
/*
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
#define SL_SPEAKER_FRONT_LEFT ((SLuint32) 0x00000001)
#define SL_SPEAKER_FRONT_RIGHT ((SLuint32) 0x00000002)
#define SL_SPEAKER_FRONT_CENTER ((SLuint32) 0x00000004)
#define SL_SPEAKER_LOW_FREQUENCY ((SLuint32) 0x00000008)
#define SL_SPEAKER_BACK_LEFT ((SLuint32) 0x00000010)
#define SL_SPEAKER_BACK_RIGHT ((SLuint32) 0x00000020)
#define SL_SPEAKER_FRONT_LEFT_OF_CENTER ((SLuint32) 0x00000040)
#define SL_SPEAKER_FRONT_RIGHT_OF_CENTER ((SLuint32) 0x00000080)
#define SL_SPEAKER_BACK_CENTER ((SLuint32) 0x00000100)
#define SL_SPEAKER_SIDE_LEFT ((SLuint32) 0x00000200)
#define SL_SPEAKER_SIDE_RIGHT ((SLuint32) 0x00000400)
#define SL_SPEAKER_TOP_CENTER ((SLuint32) 0x00000800)
#define SL_SPEAKER_TOP_FRONT_LEFT ((SLuint32) 0x00001000)
#define SL_SPEAKER_TOP_FRONT_CENTER ((SLuint32) 0x00002000)
#define SL_SPEAKER_TOP_FRONT_RIGHT ((SLuint32) 0x00004000)
#define SL_SPEAKER_TOP_BACK_LEFT ((SLuint32) 0x00008000)
#define SL_SPEAKER_TOP_BACK_CENTER ((SLuint32) 0x00010000)
#define SL_SPEAKER_TOP_BACK_RIGHT ((SLuint32) 0x00020000)
308
309
*/
310
311
312
313
314
315
316
317
318
319
320
321
322
if (this->spec.channels == 1) {
format_pcm.channelMask = SL_SPEAKER_FRONT_CENTER;
} else if (this->spec.channels == 2) {
format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
} else if (this->spec.channels == 3) {
format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT | SL_SPEAKER_FRONT_CENTER;
} else if (this->spec.channels == 4) {
format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT |
SL_SPEAKER_BACK_LEFT | SL_SPEAKER_BACK_RIGHT;
} else {
format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT |
SL_SPEAKER_BACK_LEFT | SL_SPEAKER_BACK_RIGHT | SL_SPEAKER_FRONT_CENTER;
}
323
324
SLDataSource audioSrc = { &loc_bufq, &format_pcm };
325
326
/* configure audio sink */
327
328
SLDataLocator_OutputMix loc_outmix = { SL_DATALOCATOR_OUTPUTMIX, outputMixObject };
SLDataSink audioSnk = { &loc_outmix, NULL };
329
330
/* create audio player */
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
const SLInterfaceID ids[2] = {
SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
SL_IID_VOLUME
};
const SLboolean req[2] = {
SL_BOOLEAN_TRUE,
SL_BOOLEAN_FALSE,
};
result = (*engineEngine)->CreateAudioPlayer(engineEngine, &bqPlayerObject, &audioSrc, &audioSnk, 2, ids, req);
if (SL_RESULT_SUCCESS != result) {
LOGE("CreateAudioPlayer failed");
goto failed;
}
346
347
/* realize the player */
348
349
350
351
352
result = (*bqPlayerObject)->Realize(bqPlayerObject, SL_BOOLEAN_FALSE);
if (SL_RESULT_SUCCESS != result) {
LOGE("RealizeAudioPlayer failed");
goto failed;
}
353
354
/* get the play interface */
355
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_PLAY, &bqPlayerPlay);
356
357
358
359
if (SL_RESULT_SUCCESS != result) {
LOGE("SL_IID_PLAY interface get failed");
goto failed;
}
360
361
/* get the buffer queue interface */
362
363
364
365
366
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &bqPlayerBufferQueue);
if (SL_RESULT_SUCCESS != result) {
LOGE("SL_IID_BUFFERQUEUE interface get failed");
goto failed;
}
367
368
369
370
/* register callback on the buffer queue */
/* context is '(SDL_PrivateAudioData *)this->hidden' */
result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, this->hidden);
371
372
373
374
if (SL_RESULT_SUCCESS != result) {
LOGE("RegisterCallback failed");
goto failed;
}
375
376
#if 0
377
/* get the effect send interface */
378
379
380
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_EFFECTSEND, &bqPlayerEffectSend);
if (SL_RESULT_SUCCESS != result)
{
381
382
383
384
LOGE("SL_IID_EFFECTSEND interface get failed");
goto failed;
}
385
386
#endif
387
388
#if 0 /* mute/solo is not supported for sources that are known to be mono, as this is */
/* get the mute/solo interface */
389
390
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_MUTESOLO, &bqPlayerMuteSolo);
assert(SL_RESULT_SUCCESS == result);
391
(void) result;
392
393
#endif
394
/* get the volume interface */
395
396
397
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_VOLUME, &bqPlayerVolume);
if (SL_RESULT_SUCCESS != result) {
LOGE("SL_IID_VOLUME interface get failed");
398
/* goto failed; */
399
}
400
401
/* Create the audio buffer semaphore */
402
403
audiodata->playsem = SDL_CreateSemaphore(NUM_BUFFERS - 1);
if (!audiodata->playsem) {
404
405
406
LOGE("cannot create Semaphore!");
goto failed;
}
407
408
/* Create the sound buffers */
409
410
audiodata->mixbuff = (Uint8 *) SDL_malloc(NUM_BUFFERS * this->spec.size);
if (audiodata->mixbuff == NULL) {
411
412
413
LOGE("mixbuffer allocate - out of memory");
goto failed;
}
414
415
for (i = 0; i < NUM_BUFFERS; i++) {
416
audiodata->pmixbuff[i] = audiodata->mixbuff + i * this->spec.size;
417
}
418
419
/* set the player's state to playing */
420
result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING);
421
422
423
424
425
if (SL_RESULT_SUCCESS != result) {
LOGE("Play set state failed");
goto failed;
}
426
427
return 0;
428
failed:
429
430
openslES_DestroyPCMPlayer(this);
431
432
return SDL_SetError("Open device failed!");
433
434
}
435
static void
436
openslES_DestroyPCMPlayer(_THIS)
437
{
438
struct SDL_PrivateAudioData *audiodata = (struct SDL_PrivateAudioData *) this->hidden;
439
440
441
SLresult result;
/* set the player's state to 'stopped' */
442
443
444
445
446
if (bqPlayerPlay != NULL) {
result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_STOPPED);
if (SL_RESULT_SUCCESS != result) {
SDL_SetError("Stopped set state failed");
}
447
}
448
449
/* destroy buffer queue audio player object, and invalidate all associated interfaces */
450
if (bqPlayerObject != NULL) {
451
452
(*bqPlayerObject)->Destroy(bqPlayerObject);
453
454
bqPlayerObject = NULL;
455
bqPlayerPlay = NULL;
456
bqPlayerBufferQueue = NULL;
457
/* bqPlayerEffectSend = NULL; */
458
459
bqPlayerMuteSolo = NULL;
bqPlayerVolume = NULL;
460
461
}
462
463
464
if (audiodata->playsem) {
SDL_DestroySemaphore(audiodata->playsem);
audiodata->playsem = NULL;
465
}
466
467
468
if (audiodata->mixbuff) {
SDL_free(audiodata->mixbuff);
469
}
470
471
return;
472
473
}
474
475
static int
openslES_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
476
{
477
478
479
480
481
this->hidden = (struct SDL_PrivateAudioData *) SDL_calloc(1, (sizeof *this->hidden));
if (this->hidden == NULL) {
return SDL_OutOfMemory();
}
482
483
484
485
486
487
488
if (iscapture) {
LOGI("openslES_OpenDevice( ) %s for capture", devname);
return openslES_CreatePCMRecorder(this);
} else {
LOGI("openslES_OpenDevice( ) %s for playing", devname);
return openslES_CreatePCMPlayer(this);
}
489
490
}
491
492
static void
openslES_CloseDevice(_THIS)
493
{
494
495
/* struct SDL_PrivateAudioData *audiodata = (struct SDL_PrivateAudioData *) this->hidden; */
496
497
if (this->iscapture) {
LOGI("openslES_CloseDevice( ) for capture");
498
openslES_DestroyPCMRecorder(this);
499
500
} else {
LOGI("openslES_CloseDevice( ) for playing");
501
openslES_DestroyPCMPlayer(this);
502
}
503
504
505
SDL_free(this->hidden);
506
return;
507
508
}
509
510
static void
openslES_WaitDevice(_THIS)
511
{
512
513
struct SDL_PrivateAudioData *audiodata = (struct SDL_PrivateAudioData *) this->hidden;
514
LOGI("openslES_WaitDevice( )");
515
516
/* Wait for an audio chunk to finish */
517
518
/* WaitForSingleObject(this->hidden->audio_sem, INFINITE); */
SDL_SemWait(audiodata->playsem);
519
520
return;
521
522
}
523
524
525
526
527
528
529
530
531
532
533
/*/ n playn sem */
/* getbuf 0 - 1 */
/* fill buff 0 - 1 */
/* play 0 - 0 1 */
/* wait 1 0 0 */
/* getbuf 1 0 0 */
/* fill buff 1 0 0 */
/* play 0 0 0 */
/* wait */
/* */
/* okay.. */
534
535
536
static Uint8 *
openslES_GetDeviceBuf(_THIS)
537
{
538
539
struct SDL_PrivateAudioData *audiodata = (struct SDL_PrivateAudioData *) this->hidden;
540
LOGI("openslES_GetDeviceBuf( )");
541
return audiodata->pmixbuff[audiodata->next_buffer];
542
543
}
544
545
static void
openslES_PlayDevice(_THIS)
546
{
547
struct SDL_PrivateAudioData *audiodata = (struct SDL_PrivateAudioData *) this->hidden;
548
SLresult result;
549
550
LOGI("======openslES_PlayDevice( )======");
551
552
/* Queue it up */
553
result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, audiodata->pmixbuff[audiodata->next_buffer], this->spec.size);
554
555
556
557
audiodata->next_buffer++;
if (audiodata->next_buffer >= NUM_BUFFERS) {
audiodata->next_buffer = 0;
558
}
559
560
561
562
563
564
565
/* If Enqueue fails, callback won't be called.
* Post the semphore, not to run out of buffer */
if (SL_RESULT_SUCCESS != result) {
SDL_SemPost(audiodata->playsem);
}
566
return;
567
568
}
569
570
static int
openslES_Init(SDL_AudioDriverImpl * impl)
571
{
572
LOGI("openslES_Init() called");
573
574
575
576
if (!openslES_CreateEngine()) {
return 0;
}
577
578
LOGI("openslES_Init() - set pointers");
579
580
/* Set the function pointers */
581
/* impl->DetectDevices = openslES_DetectDevices; */
582
impl->OpenDevice = openslES_OpenDevice;
583
impl->CloseDevice = openslES_CloseDevice;
584
585
586
587
impl->PlayDevice = openslES_PlayDevice;
impl->GetDeviceBuf = openslES_GetDeviceBuf;
impl->Deinitialize = openslES_DestroyEngine;
impl->WaitDevice = openslES_WaitDevice;
588
589
590
591
/* and the capabilities */
impl->HasCaptureSupport = 0; /* TODO */
impl->OnlyHasDefaultOutputDevice = 1;
592
/* impl->OnlyHasDefaultInputDevice = 1; */
593
594
LOGI("openslES_Init() - succes");
595
596
597
/* this audio target is available. */
return 1;
598
599
600
}
AudioBootStrap openslES_bootstrap = {
601
"openslES", "opensl ES audio driver", openslES_Init, 0
602
603
};
604
605
void openslES_ResumeDevices()
{
606
607
608
609
610
611
if (bqPlayerPlay != NULL) {
/* set the player's state to 'playing' */
SLresult result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING);
if (SL_RESULT_SUCCESS != result) {
SDL_SetError("openslES_ResumeDevices failed");
}
612
613
614
615
616
}
}
void openslES_PauseDevices()
{
617
618
619
620
621
622
if (bqPlayerPlay != NULL) {
/* set the player's state to 'paused' */
SLresult result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PAUSED);
if (SL_RESULT_SUCCESS != result) {
SDL_SetError("openslES_PauseDevices failed");
}
623
624
625
}
}
626
627
628
#endif /* SDL_AUDIO_DRIVER_OPENSLES */
/* vi: set ts=4 sw=4 expandtab: */