21 #include "../../SDL_internal.h"
23 #if SDL_AUDIO_DRIVER_OPENSLES
30 #include "../SDL_audio_c.h"
31 #include "../../core/android/SDL_android.h"
35 #include <SLES/OpenSLES.h>
36 #include <SLES/OpenSLES_Android.h>
38 #include <android/log.h>
41 #define LOG_TAG "SDL_openslES"
42 #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
43 #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
72 #define SL_ANDROID_SPEAKER_STEREO (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT)
73 #define SL_ANDROID_SPEAKER_QUAD (SL_ANDROID_SPEAKER_STEREO | SL_SPEAKER_BACK_LEFT | SL_SPEAKER_BACK_RIGHT)
74 #define SL_ANDROID_SPEAKER_5DOT1 (SL_ANDROID_SPEAKER_QUAD | SL_SPEAKER_FRONT_CENTER | SL_SPEAKER_LOW_FREQUENCY)
75 #define SL_ANDROID_SPEAKER_7DOT1 (SL_ANDROID_SPEAKER_5DOT1 | SL_SPEAKER_SIDE_LEFT | SL_SPEAKER_SIDE_RIGHT)
78 static SLObjectItf engineObject;
79 static SLEngineItf engineEngine;
82 static SLObjectItf outputMixObject;
85 static SLObjectItf bqPlayerObject;
86 static SLPlayItf bqPlayerPlay;
87 static SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue;
89 static SLVolumeItf bqPlayerVolume;
93 static SLObjectItf recorderObject;
94 static SLRecordItf recorderRecord;
95 static SLAndroidSimpleBufferQueueItf recorderBufferQueue;
98 static const char *sldevaudiorecorderstr =
"SLES Audio Recorder";
99 static const char *sldevaudioplayerstr =
"SLES Audio Player";
101 #define SLES_DEV_AUDIO_RECORDER sldevaudiorecorderstr
102 #define SLES_DEV_AUDIO_PLAYER sldevaudioplayerstr
103 static void openslES_DetectDevices(
int iscapture )
105 LOGI(
"openSLES_DetectDevices()" );
107 addfn( SLES_DEV_AUDIO_RECORDER );
109 addfn( SLES_DEV_AUDIO_PLAYER );
113 static void openslES_DestroyEngine(
void)
115 LOGI(
"openslES_DestroyEngine()");
118 if (outputMixObject !=
NULL) {
119 (*outputMixObject)->Destroy(outputMixObject);
120 outputMixObject =
NULL;
124 if (engineObject !=
NULL) {
125 (*engineObject)->Destroy(engineObject);
132 openslES_CreateEngine(
void)
136 LOGI(
"openSLES_CreateEngine()");
140 if (SL_RESULT_SUCCESS !=
result) {
141 LOGE(
"slCreateEngine failed: %d",
result);
144 LOGI(
"slCreateEngine OK");
147 result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
148 if (SL_RESULT_SUCCESS !=
result) {
149 LOGE(
"RealizeEngine failed: %d",
result);
152 LOGI(
"RealizeEngine OK");
155 result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
156 if (SL_RESULT_SUCCESS !=
result) {
157 LOGE(
"EngineGetInterface failed: %d",
result);
160 LOGI(
"EngineGetInterface OK");
163 const SLInterfaceID
ids[1] = { SL_IID_VOLUME };
164 const SLboolean req[1] = { SL_BOOLEAN_FALSE };
165 result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 1,
ids, req);
166 if (SL_RESULT_SUCCESS !=
result) {
167 LOGE(
"CreateOutputMix failed: %d",
result);
170 LOGI(
"CreateOutputMix OK");
173 result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
174 if (SL_RESULT_SUCCESS !=
result) {
175 LOGE(
"RealizeOutputMix failed: %d",
result);
181 openslES_DestroyEngine();
187 bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq,
void *
context)
191 LOGV(
"SLES: Recording Callback");
196 openslES_DestroyPCMRecorder(
_THIS)
202 if (recorderRecord !=
NULL) {
203 result = (*recorderRecord)->SetRecordState(recorderRecord, SL_RECORDSTATE_STOPPED);
204 if (SL_RESULT_SUCCESS !=
result) {
205 LOGE(
"SetRecordState stopped: %d",
result);
210 if (recorderObject !=
NULL) {
211 (*recorderObject)->Destroy(recorderObject);
212 recorderObject =
NULL;
213 recorderRecord =
NULL;
214 recorderBufferQueue =
NULL;
228 openslES_CreatePCMRecorder(
_THIS)
231 SLDataFormat_PCM format_pcm;
236 LOGE(
"This app doesn't have RECORD_AUDIO permission");
237 return SDL_SetError(
"This app doesn't have RECORD_AUDIO permission");
248 LOGI(
"Try to open %u hz %u bit chan %u %s samples %u",
250 this->spec.channels, (this->spec.format & 0x1000) ?
"BE" :
"LE", this->spec.samples);
253 SLDataLocator_IODevice loc_dev = {SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT, SL_DEFAULTDEVICEID_AUDIOINPUT,
NULL};
254 SLDataSource audioSrc = {&loc_dev,
NULL};
257 SLDataLocator_AndroidSimpleBufferQueue loc_bufq = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,
NUM_BUFFERS };
259 format_pcm.formatType = SL_DATAFORMAT_PCM;
261 format_pcm.samplesPerSec = this->
spec.
freq * 1000;
264 format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
265 format_pcm.channelMask = SL_SPEAKER_FRONT_CENTER;
267 SLDataSink audioSnk = { &loc_bufq, &format_pcm };
271 const SLInterfaceID
ids[1] = {
272 SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
274 const SLboolean req[1] = {
278 result = (*engineEngine)->CreateAudioRecorder(engineEngine, &recorderObject, &audioSrc, &audioSnk, 1,
ids, req);
279 if (SL_RESULT_SUCCESS !=
result) {
280 LOGE(
"CreateAudioRecorder failed: %d",
result);
285 result = (*recorderObject)->Realize(recorderObject, SL_BOOLEAN_FALSE);
286 if (SL_RESULT_SUCCESS !=
result) {
287 LOGE(
"RealizeAudioPlayer failed: %d",
result);
292 result = (*recorderObject)->GetInterface(recorderObject, SL_IID_RECORD, &recorderRecord);
293 if (SL_RESULT_SUCCESS !=
result) {
294 LOGE(
"SL_IID_RECORD interface get failed: %d",
result);
299 result = (*recorderObject)->GetInterface(recorderObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &recorderBufferQueue);
300 if (SL_RESULT_SUCCESS !=
result) {
301 LOGE(
"SL_IID_BUFFERQUEUE interface get failed: %d",
result);
307 result = (*recorderBufferQueue)->RegisterCallback(recorderBufferQueue, bqRecorderCallback, this->hidden);
308 if (SL_RESULT_SUCCESS !=
result) {
309 LOGE(
"RegisterCallback failed: %d",
result);
316 LOGE(
"cannot create Semaphore!");
323 LOGE(
"mixbuffer allocate - out of memory");
332 result = (*recorderRecord)->SetRecordState(recorderRecord, SL_RECORDSTATE_STOPPED);
333 if (SL_RESULT_SUCCESS !=
result) {
334 LOGE(
"Record set state failed: %d",
result);
340 result = (*recorderBufferQueue)->Enqueue(recorderBufferQueue, audiodata->
pmixbuff[
i], this->spec.size);
341 if (SL_RESULT_SUCCESS !=
result) {
342 LOGE(
"Record enqueue buffers failed: %d",
result);
348 result = (*recorderRecord)->SetRecordState(recorderRecord, SL_RECORDSTATE_RECORDING);
349 if (SL_RESULT_SUCCESS !=
result) {
350 LOGE(
"Record set state failed: %d",
result);
358 openslES_DestroyPCMRecorder(
this);
365 bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq,
void *
context)
369 LOGV(
"SLES: Playback Callback");
374 openslES_DestroyPCMPlayer(
_THIS)
380 if (bqPlayerPlay !=
NULL) {
381 result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_STOPPED);
382 if (SL_RESULT_SUCCESS !=
result) {
383 LOGE(
"SetPlayState stopped failed: %d",
result);
388 if (bqPlayerObject !=
NULL) {
390 (*bqPlayerObject)->Destroy(bqPlayerObject);
392 bqPlayerObject =
NULL;
394 bqPlayerBufferQueue =
NULL;
408 openslES_CreatePCMPlayer(
_THIS)
411 SLDataFormat_PCM format_pcm;
424 while (test_format != 0) {
431 if (test_format == 0) {
433 LOGI(
"No compatible audio format, using signed 16-bit audio" );
442 LOGI(
"Try to open %u hz %u bit chan %u %s samples %u",
444 this->spec.channels, (this->spec.format & 0x1000) ?
"BE" :
"LE", this->spec.samples);
447 SLDataLocator_AndroidSimpleBufferQueue loc_bufq = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,
NUM_BUFFERS };
449 format_pcm.formatType = SL_DATAFORMAT_PCM;
451 format_pcm.samplesPerSec = this->
spec.
freq * 1000;
456 format_pcm.endianness = SL_BYTEORDER_BIGENDIAN;
458 format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
464 format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT;
467 format_pcm.channelMask = SL_ANDROID_SPEAKER_STEREO;
470 format_pcm.channelMask = SL_ANDROID_SPEAKER_STEREO | SL_SPEAKER_FRONT_CENTER;
473 format_pcm.channelMask = SL_ANDROID_SPEAKER_QUAD;
476 format_pcm.channelMask = SL_ANDROID_SPEAKER_QUAD | SL_SPEAKER_FRONT_CENTER;
479 format_pcm.channelMask = SL_ANDROID_SPEAKER_5DOT1;
482 format_pcm.channelMask = SL_ANDROID_SPEAKER_5DOT1 | SL_SPEAKER_BACK_CENTER;
485 format_pcm.channelMask = SL_ANDROID_SPEAKER_7DOT1;
490 format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
494 SLDataSource audioSrc = { &loc_bufq, &format_pcm };
497 SLDataLocator_OutputMix loc_outmix = { SL_DATALOCATOR_OUTPUTMIX, outputMixObject };
498 SLDataSink audioSnk = { &loc_outmix,
NULL };
501 const SLInterfaceID
ids[2] = {
502 SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
506 const SLboolean req[2] = {
511 result = (*engineEngine)->CreateAudioPlayer(engineEngine, &bqPlayerObject, &audioSrc, &audioSnk, 2,
ids, req);
512 if (SL_RESULT_SUCCESS !=
result) {
513 LOGE(
"CreateAudioPlayer failed: %d",
result);
518 result = (*bqPlayerObject)->Realize(bqPlayerObject, SL_BOOLEAN_FALSE);
519 if (SL_RESULT_SUCCESS !=
result) {
520 LOGE(
"RealizeAudioPlayer failed: %d",
result);
525 result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_PLAY, &bqPlayerPlay);
526 if (SL_RESULT_SUCCESS !=
result) {
527 LOGE(
"SL_IID_PLAY interface get failed: %d",
result);
532 result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &bqPlayerBufferQueue);
533 if (SL_RESULT_SUCCESS !=
result) {
534 LOGE(
"SL_IID_BUFFERQUEUE interface get failed: %d",
result);
540 result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, this->hidden);
541 if (SL_RESULT_SUCCESS !=
result) {
542 LOGE(
"RegisterCallback failed: %d",
result);
548 result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_VOLUME, &bqPlayerVolume);
549 if (SL_RESULT_SUCCESS !=
result) {
550 LOGE(
"SL_IID_VOLUME interface get failed: %d",
result);
558 LOGE(
"cannot create Semaphore!");
565 LOGE(
"mixbuffer allocate - out of memory");
574 result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING);
575 if (SL_RESULT_SUCCESS !=
result) {
576 LOGE(
"Play set state failed: %d",
result);
584 openslES_DestroyPCMPlayer(
this);
593 if (this->hidden ==
NULL) {
598 LOGI(
"openslES_OpenDevice() %s for capture", devname);
599 return openslES_CreatePCMRecorder(
this);
601 LOGI(
"openslES_OpenDevice() %s for playing", devname);
602 return openslES_CreatePCMPlayer(
this);
607 openslES_WaitDevice(
_THIS)
611 LOGV(
"openslES_WaitDevice()");
618 openslES_PlayDevice(
_THIS)
623 LOGV(
"======openslES_PlayDevice()======");
626 result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, audiodata->
pmixbuff[audiodata->
next_buffer], this->spec.size);
635 if (SL_RESULT_SUCCESS !=
result) {
653 openslES_GetDeviceBuf(
_THIS)
657 LOGV(
"openslES_GetDeviceBuf()");
662 openslES_CaptureFromDevice(
_THIS,
void *
buffer,
int buflen)
675 result = (*recorderBufferQueue)->Enqueue(recorderBufferQueue, audiodata->
pmixbuff[audiodata->
next_buffer], this->spec.size);
676 if (SL_RESULT_SUCCESS !=
result) {
677 LOGE(
"Record enqueue buffers failed: %d",
result);
690 openslES_CloseDevice(
_THIS)
694 if (this->iscapture) {
695 LOGI(
"openslES_CloseDevice() for capture");
696 openslES_DestroyPCMRecorder(
this);
698 LOGI(
"openslES_CloseDevice() for playing");
699 openslES_DestroyPCMPlayer(
this);
708 LOGI(
"openslES_Init() called");
710 if (!openslES_CreateEngine()) {
714 LOGI(
"openslES_Init() - set pointers");
731 LOGI(
"openslES_Init() - success");
738 "openslES",
"opensl ES audio driver", openslES_Init, 0
743 if (bqPlayerPlay !=
NULL) {
745 SLresult
result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING);
746 if (SL_RESULT_SUCCESS !=
result) {
747 LOGE(
"openslES_ResumeDevices failed: %d",
result);
754 if (bqPlayerPlay !=
NULL) {
756 SLresult
result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PAUSED);
757 if (SL_RESULT_SUCCESS !=
result) {
758 LOGE(
"openslES_PauseDevices failed: %d",
result);
SDL_bool Android_JNI_RequestPermission(const char *permission)
#define SDL_assert(condition)
void SDL_CalculateAudioSpec(SDL_AudioSpec *spec)
SDL_AudioFormat SDL_FirstAudioFormat(SDL_AudioFormat format)
SDL_AudioFormat SDL_NextAudioFormat(void)
#define SDL_AUDIO_ISINT(x)
#define SDL_AUDIO_ISBIGENDIAN(x)
Uint16 SDL_AudioFormat
Audio format flags.
#define SDL_AUDIO_ISSIGNED(x)
#define SDL_AUDIO_BITSIZE(x)
#define SDL_DestroySemaphore
#define SDL_CreateSemaphore
#define SDL_OutOfMemory()
void openslES_ResumeDevices(void)
void openslES_PauseDevices(void)
AudioBootStrap openslES_bootstrap
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
EGLImageKHR EGLint EGLint * handle
void(* PlayDevice)(_THIS)
void(* WaitDevice)(_THIS)
void(* CloseDevice)(_THIS)
int OnlyHasDefaultCaptureDevice
int OnlyHasDefaultOutputDevice
Uint8 *(* GetDeviceBuf)(_THIS)
void(* Deinitialize)(void)
int(* CaptureFromDevice)(_THIS, void *buffer, int buflen)
int(* OpenDevice)(_THIS, void *handle, const char *devname, int iscapture)
Uint8 * pmixbuff[NUM_BUFFERS]
static screen_context_t context