21 #include "../../SDL_internal.h"
23 #if SDL_AUDIO_DRIVER_OPENSLES
31 #include "../SDL_audio_c.h"
32 #include "../../core/android/SDL_android.h"
36 #include <SLES/OpenSLES.h>
37 #include <SLES/OpenSLES_Android.h>
39 #include <android/log.h>
42 #define LOG_TAG "SDL_openslES"
43 #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
44 #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
73 #define SL_ANDROID_SPEAKER_STEREO (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT)
74 #define SL_ANDROID_SPEAKER_QUAD (SL_ANDROID_SPEAKER_STEREO | SL_SPEAKER_BACK_LEFT | SL_SPEAKER_BACK_RIGHT)
75 #define SL_ANDROID_SPEAKER_5DOT1 (SL_ANDROID_SPEAKER_QUAD | SL_SPEAKER_FRONT_CENTER | SL_SPEAKER_LOW_FREQUENCY)
76 #define SL_ANDROID_SPEAKER_7DOT1 (SL_ANDROID_SPEAKER_5DOT1 | SL_SPEAKER_SIDE_LEFT | SL_SPEAKER_SIDE_RIGHT)
79 static SLObjectItf engineObject;
80 static SLEngineItf engineEngine;
83 static SLObjectItf outputMixObject;
86 static SLObjectItf bqPlayerObject;
87 static SLPlayItf bqPlayerPlay;
88 static SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue;
90 static SLVolumeItf bqPlayerVolume;
94 static SLObjectItf recorderObject;
95 static SLRecordItf recorderRecord;
96 static SLAndroidSimpleBufferQueueItf recorderBufferQueue;
99 static const char *sldevaudiorecorderstr =
"SLES Audio Recorder";
100 static const char *sldevaudioplayerstr =
"SLES Audio Player";
102 #define SLES_DEV_AUDIO_RECORDER sldevaudiorecorderstr
103 #define SLES_DEV_AUDIO_PLAYER sldevaudioplayerstr
104 static void openslES_DetectDevices(
int iscapture )
106 LOGI(
"openSLES_DetectDevices()" );
108 addfn( SLES_DEV_AUDIO_RECORDER );
110 addfn( SLES_DEV_AUDIO_PLAYER );
114 static void openslES_DestroyEngine(
void)
116 LOGI(
"openslES_DestroyEngine()");
119 if (outputMixObject !=
NULL) {
120 (*outputMixObject)->Destroy(outputMixObject);
121 outputMixObject =
NULL;
125 if (engineObject !=
NULL) {
126 (*engineObject)->Destroy(engineObject);
133 openslES_CreateEngine(
void)
137 LOGI(
"openSLES_CreateEngine()");
141 if (SL_RESULT_SUCCESS !=
result) {
142 LOGE(
"slCreateEngine failed: %d",
result);
145 LOGI(
"slCreateEngine OK");
148 result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
149 if (SL_RESULT_SUCCESS !=
result) {
150 LOGE(
"RealizeEngine failed: %d",
result);
153 LOGI(
"RealizeEngine OK");
156 result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
157 if (SL_RESULT_SUCCESS !=
result) {
158 LOGE(
"EngineGetInterface failed: %d",
result);
161 LOGI(
"EngineGetInterface OK");
164 const SLInterfaceID
ids[1] = { SL_IID_VOLUME };
165 const SLboolean req[1] = { SL_BOOLEAN_FALSE };
166 result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 1,
ids, req);
167 if (SL_RESULT_SUCCESS !=
result) {
168 LOGE(
"CreateOutputMix failed: %d",
result);
171 LOGI(
"CreateOutputMix OK");
174 result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
175 if (SL_RESULT_SUCCESS !=
result) {
176 LOGE(
"RealizeOutputMix failed: %d",
result);
182 openslES_DestroyEngine();
188 bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq,
void *
context)
192 LOGV(
"SLES: Recording Callback");
197 openslES_DestroyPCMRecorder(
_THIS)
203 if (recorderRecord !=
NULL) {
204 result = (*recorderRecord)->SetRecordState(recorderRecord, SL_RECORDSTATE_STOPPED);
205 if (SL_RESULT_SUCCESS !=
result) {
206 LOGE(
"SetRecordState stopped: %d",
result);
211 if (recorderObject !=
NULL) {
212 (*recorderObject)->Destroy(recorderObject);
213 recorderObject =
NULL;
214 recorderRecord =
NULL;
215 recorderBufferQueue =
NULL;
229 openslES_CreatePCMRecorder(
_THIS)
232 SLDataFormat_PCM format_pcm;
237 LOGE(
"This app doesn't have RECORD_AUDIO permission");
238 return SDL_SetError(
"This app doesn't have RECORD_AUDIO permission");
249 LOGI(
"Try to open %u hz %u bit chan %u %s samples %u",
251 this->spec.channels, (this->spec.format & 0x1000) ?
"BE" :
"LE", this->spec.samples);
254 SLDataLocator_IODevice loc_dev = {SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT, SL_DEFAULTDEVICEID_AUDIOINPUT,
NULL};
255 SLDataSource audioSrc = {&loc_dev,
NULL};
258 SLDataLocator_AndroidSimpleBufferQueue loc_bufq = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,
NUM_BUFFERS };
260 format_pcm.formatType = SL_DATAFORMAT_PCM;
262 format_pcm.samplesPerSec = this->
spec.
freq * 1000;
265 format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
266 format_pcm.channelMask = SL_SPEAKER_FRONT_CENTER;
268 SLDataSink audioSnk = { &loc_bufq, &format_pcm };
272 const SLInterfaceID
ids[1] = {
273 SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
275 const SLboolean req[1] = {
279 result = (*engineEngine)->CreateAudioRecorder(engineEngine, &recorderObject, &audioSrc, &audioSnk, 1,
ids, req);
280 if (SL_RESULT_SUCCESS !=
result) {
281 LOGE(
"CreateAudioRecorder failed: %d",
result);
286 result = (*recorderObject)->Realize(recorderObject, SL_BOOLEAN_FALSE);
287 if (SL_RESULT_SUCCESS !=
result) {
288 LOGE(
"RealizeAudioPlayer failed: %d",
result);
293 result = (*recorderObject)->GetInterface(recorderObject, SL_IID_RECORD, &recorderRecord);
294 if (SL_RESULT_SUCCESS !=
result) {
295 LOGE(
"SL_IID_RECORD interface get failed: %d",
result);
300 result = (*recorderObject)->GetInterface(recorderObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &recorderBufferQueue);
301 if (SL_RESULT_SUCCESS !=
result) {
302 LOGE(
"SL_IID_BUFFERQUEUE interface get failed: %d",
result);
308 result = (*recorderBufferQueue)->RegisterCallback(recorderBufferQueue, bqRecorderCallback, this->hidden);
309 if (SL_RESULT_SUCCESS !=
result) {
310 LOGE(
"RegisterCallback failed: %d",
result);
317 LOGE(
"cannot create Semaphore!");
324 LOGE(
"mixbuffer allocate - out of memory");
333 result = (*recorderRecord)->SetRecordState(recorderRecord, SL_RECORDSTATE_STOPPED);
334 if (SL_RESULT_SUCCESS !=
result) {
335 LOGE(
"Record set state failed: %d",
result);
341 result = (*recorderBufferQueue)->Enqueue(recorderBufferQueue, audiodata->
pmixbuff[
i], this->spec.size);
342 if (SL_RESULT_SUCCESS !=
result) {
343 LOGE(
"Record enqueue buffers failed: %d",
result);
349 result = (*recorderRecord)->SetRecordState(recorderRecord, SL_RECORDSTATE_RECORDING);
350 if (SL_RESULT_SUCCESS !=
result) {
351 LOGE(
"Record set state failed: %d",
result);
359 openslES_DestroyPCMRecorder(
this);
366 bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq,
void *
context)
370 LOGV(
"SLES: Playback Callback");
375 openslES_DestroyPCMPlayer(
_THIS)
381 if (bqPlayerPlay !=
NULL) {
382 result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_STOPPED);
383 if (SL_RESULT_SUCCESS !=
result) {
384 LOGE(
"SetPlayState stopped failed: %d",
result);
389 if (bqPlayerObject !=
NULL) {
391 (*bqPlayerObject)->Destroy(bqPlayerObject);
393 bqPlayerObject =
NULL;
395 bqPlayerBufferQueue =
NULL;
409 openslES_CreatePCMPlayer(
_THIS)
412 SLDataFormat_PCM format_pcm;
425 while (test_format != 0) {
432 if (test_format == 0) {
434 LOGI(
"No compatible audio format, using signed 16-bit audio" );
443 LOGI(
"Try to open %u hz %u bit chan %u %s samples %u",
445 this->spec.channels, (this->spec.format & 0x1000) ?
"BE" :
"LE", this->spec.samples);
448 SLDataLocator_AndroidSimpleBufferQueue loc_bufq = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,
NUM_BUFFERS };
450 format_pcm.formatType = SL_DATAFORMAT_PCM;
452 format_pcm.samplesPerSec = this->
spec.
freq * 1000;
457 format_pcm.endianness = SL_BYTEORDER_BIGENDIAN;
459 format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
465 format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT;
468 format_pcm.channelMask = SL_ANDROID_SPEAKER_STEREO;
471 format_pcm.channelMask = SL_ANDROID_SPEAKER_STEREO | SL_SPEAKER_FRONT_CENTER;
474 format_pcm.channelMask = SL_ANDROID_SPEAKER_QUAD;
477 format_pcm.channelMask = SL_ANDROID_SPEAKER_QUAD | SL_SPEAKER_FRONT_CENTER;
480 format_pcm.channelMask = SL_ANDROID_SPEAKER_5DOT1;
483 format_pcm.channelMask = SL_ANDROID_SPEAKER_5DOT1 | SL_SPEAKER_BACK_CENTER;
486 format_pcm.channelMask = SL_ANDROID_SPEAKER_7DOT1;
491 format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
495 SLDataSource audioSrc = { &loc_bufq, &format_pcm };
498 SLDataLocator_OutputMix loc_outmix = { SL_DATALOCATOR_OUTPUTMIX, outputMixObject };
499 SLDataSink audioSnk = { &loc_outmix,
NULL };
502 const SLInterfaceID
ids[2] = {
503 SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
507 const SLboolean req[2] = {
512 result = (*engineEngine)->CreateAudioPlayer(engineEngine, &bqPlayerObject, &audioSrc, &audioSnk, 2,
ids, req);
513 if (SL_RESULT_SUCCESS !=
result) {
514 LOGE(
"CreateAudioPlayer failed: %d",
result);
519 result = (*bqPlayerObject)->Realize(bqPlayerObject, SL_BOOLEAN_FALSE);
520 if (SL_RESULT_SUCCESS !=
result) {
521 LOGE(
"RealizeAudioPlayer failed: %d",
result);
526 result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_PLAY, &bqPlayerPlay);
527 if (SL_RESULT_SUCCESS !=
result) {
528 LOGE(
"SL_IID_PLAY interface get failed: %d",
result);
533 result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &bqPlayerBufferQueue);
534 if (SL_RESULT_SUCCESS !=
result) {
535 LOGE(
"SL_IID_BUFFERQUEUE interface get failed: %d",
result);
541 result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, this->hidden);
542 if (SL_RESULT_SUCCESS !=
result) {
543 LOGE(
"RegisterCallback failed: %d",
result);
549 result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_VOLUME, &bqPlayerVolume);
550 if (SL_RESULT_SUCCESS !=
result) {
551 LOGE(
"SL_IID_VOLUME interface get failed: %d",
result);
559 LOGE(
"cannot create Semaphore!");
566 LOGE(
"mixbuffer allocate - out of memory");
575 result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING);
576 if (SL_RESULT_SUCCESS !=
result) {
577 LOGE(
"Play set state failed: %d",
result);
585 openslES_DestroyPCMPlayer(
this);
594 if (this->hidden ==
NULL) {
599 LOGI(
"openslES_OpenDevice() %s for capture", devname);
600 return openslES_CreatePCMRecorder(
this);
602 LOGI(
"openslES_OpenDevice() %s for playing", devname);
603 return openslES_CreatePCMPlayer(
this);
608 openslES_WaitDevice(
_THIS)
612 LOGV(
"openslES_WaitDevice()");
619 openslES_PlayDevice(
_THIS)
624 LOGV(
"======openslES_PlayDevice()======");
627 result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, audiodata->
pmixbuff[audiodata->
next_buffer], this->spec.size);
636 if (SL_RESULT_SUCCESS !=
result) {
654 openslES_GetDeviceBuf(
_THIS)
658 LOGV(
"openslES_GetDeviceBuf()");
663 openslES_CaptureFromDevice(
_THIS,
void *
buffer,
int buflen)
676 result = (*recorderBufferQueue)->Enqueue(recorderBufferQueue, audiodata->
pmixbuff[audiodata->
next_buffer], this->spec.size);
677 if (SL_RESULT_SUCCESS !=
result) {
678 LOGE(
"Record enqueue buffers failed: %d",
result);
691 openslES_CloseDevice(
_THIS)
695 if (this->iscapture) {
696 LOGI(
"openslES_CloseDevice() for capture");
697 openslES_DestroyPCMRecorder(
this);
699 LOGI(
"openslES_CloseDevice() for playing");
700 openslES_DestroyPCMPlayer(
this);
709 LOGI(
"openslES_Init() called");
711 if (!openslES_CreateEngine()) {
715 LOGI(
"openslES_Init() - set pointers");
732 LOGI(
"openslES_Init() - success");
739 "openslES",
"opensl ES audio driver", openslES_Init, 0
744 if (bqPlayerPlay !=
NULL) {
746 SLresult
result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING);
747 if (SL_RESULT_SUCCESS !=
result) {
748 LOGE(
"openslES_ResumeDevices failed: %d",
result);
755 if (bqPlayerPlay !=
NULL) {
757 SLresult
result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PAUSED);
758 if (SL_RESULT_SUCCESS !=
result) {
759 LOGE(
"openslES_PauseDevices failed: %d",
result);