21 #include "../../SDL_internal.h" 23 #if SDL_AUDIO_DRIVER_OPENSLES 30 #include "../SDL_audio_c.h" 34 #include <SLES/OpenSLES.h> 35 #include <SLES/OpenSLES_Android.h> 37 #include <android/log.h> 39 #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__) 53 static SLObjectItf engineObject =
NULL;
54 static SLEngineItf engineEngine =
NULL;
57 static SLObjectItf outputMixObject =
NULL;
64 static SLObjectItf bqPlayerObject =
NULL;
65 static SLPlayItf bqPlayerPlay =
NULL;
66 static SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue =
NULL;
68 static SLEffectSendItf bqPlayerEffectSend =
NULL;
69 static SLMuteSoloItf bqPlayerMuteSolo =
NULL;
70 static SLVolumeItf bqPlayerVolume =
NULL;
75 static SLObjectItf recorderObject =
NULL;
76 static SLRecordItf recorderRecord;
77 static SLAndroidSimpleBufferQueueItf recorderBufferQueue;
82 static short *nextBuffer;
83 static unsigned nextSize;
90 static const char *sldevaudiorecorderstr =
"SLES Audio Recorder";
91 static const char *sldevaudioplayerstr =
"SLES Audio Player";
93 #define SLES_DEV_AUDIO_RECORDER sldevaudiorecorderstr 94 #define SLES_DEV_AUDIO_PLAYER sldevaudioplayerstr 95 static void openslES_DetectDevices(
int iscapture )
97 LOGI(
"openSLES_DetectDevices()" );
99 addfn( SLES_DEV_AUDIO_RECORDER );
101 addfn( SLES_DEV_AUDIO_PLAYER );
106 static void openslES_DestroyEngine();
109 openslES_CreateEngine()
113 LOGI(
"openSLES_CreateEngine()");
116 result = slCreateEngine(&engineObject, 0,
NULL, 0,
NULL,
NULL);
117 if (SL_RESULT_SUCCESS != result) {
118 LOGE(
"slCreateEngine failed");
122 LOGI(
"slCreateEngine OK");
125 result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
126 if (SL_RESULT_SUCCESS != result) {
127 LOGE(
"RealizeEngine failed");
131 LOGI(
"RealizeEngine OK");
134 result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
135 if (SL_RESULT_SUCCESS != result) {
136 LOGE(
"EngineGetInterface failed");
140 LOGI(
"EngineGetInterface OK");
146 const SLInterfaceID
ids[1] = { SL_IID_VOLUME };
147 const SLboolean req[1] = { SL_BOOLEAN_FALSE };
148 result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 1, ids, req);
150 if (SL_RESULT_SUCCESS != result) {
151 LOGE(
"CreateOutputMix failed");
154 LOGI(
"CreateOutputMix OK");
157 result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
158 if (SL_RESULT_SUCCESS != result) {
159 LOGE(
"RealizeOutputMix failed");
165 openslES_DestroyEngine();
169 static void openslES_DestroyPCMPlayer(
_THIS);
170 static void openslES_DestroyPCMRecorder(
_THIS);
172 static void openslES_DestroyEngine()
174 LOGI(
"openslES_DestroyEngine()");
180 if (outputMixObject !=
NULL) {
181 (*outputMixObject)->Destroy(outputMixObject);
182 outputMixObject =
NULL;
187 if (engineObject !=
NULL) {
188 (*engineObject)->Destroy(engineObject);
198 bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq,
void *
context)
201 LOGV(
"SLES: Playback Callmeback");
207 openslES_CreatePCMRecorder(
_THIS)
211 LOGE(
"openslES_CreatePCMRecorder not implimented yet!");
212 return SDL_SetError(
"openslES_CreatePCMRecorder not implimented yet!");
216 openslES_DestroyPCMRecorder(
_THIS)
224 openslES_CreatePCMPlayer(
_THIS)
227 SLDataFormat_PCM format_pcm;
240 while (test_format != 0) {
247 if (test_format == 0) {
249 LOGI(
"No compatible audio format, using signed 16-bit audio" );
258 LOGI(
"Try to open %u hz %u bit chan %u %s samples %u",
260 this->spec.channels, (this->spec.format & 0x1000) ?
"BE" :
"LE", this->spec.samples);
263 SLDataLocator_AndroidSimpleBufferQueue loc_bufq = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,
NUM_BUFFERS };
265 format_pcm.formatType = SL_DATAFORMAT_PCM;
267 format_pcm.samplesPerSec = this->
spec.
freq * 1000;
272 format_pcm.endianness = SL_BYTEORDER_BIGENDIAN;
274 format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
297 #define SL_ANDROID_SPEAKER_STEREO (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT) 298 #define SL_ANDROID_SPEAKER_QUAD (SL_ANDROID_SPEAKER_STEREO | SL_SPEAKER_BACK_LEFT | SL_SPEAKER_BACK_RIGHT) 299 #define SL_ANDROID_SPEAKER_5DOT1 (SL_ANDROID_SPEAKER_QUAD | SL_SPEAKER_FRONT_CENTER | SL_SPEAKER_LOW_FREQUENCY) 300 #define SL_ANDROID_SPEAKER_7DOT1 (SL_ANDROID_SPEAKER_5DOT1 | SL_SPEAKER_SIDE_LEFT | SL_SPEAKER_SIDE_RIGHT) 305 format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT;
308 format_pcm.channelMask = SL_ANDROID_SPEAKER_STEREO;
311 format_pcm.channelMask = SL_ANDROID_SPEAKER_STEREO | SL_SPEAKER_FRONT_CENTER;
314 format_pcm.channelMask = SL_ANDROID_SPEAKER_QUAD;
317 format_pcm.channelMask = SL_ANDROID_SPEAKER_QUAD | SL_SPEAKER_FRONT_CENTER;
320 format_pcm.channelMask = SL_ANDROID_SPEAKER_5DOT1;
323 format_pcm.channelMask = SL_ANDROID_SPEAKER_5DOT1 | SL_SPEAKER_BACK_CENTER;
326 format_pcm.channelMask = SL_ANDROID_SPEAKER_7DOT1;
331 format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
335 SLDataSource audioSrc = { &loc_bufq, &format_pcm };
338 SLDataLocator_OutputMix loc_outmix = { SL_DATALOCATOR_OUTPUTMIX, outputMixObject };
339 SLDataSink audioSnk = { &loc_outmix,
NULL };
342 const SLInterfaceID ids[2] = {
343 SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
347 const SLboolean req[2] = {
352 result = (*engineEngine)->CreateAudioPlayer(engineEngine, &bqPlayerObject, &audioSrc, &audioSnk, 2, ids, req);
353 if (SL_RESULT_SUCCESS != result) {
354 LOGE(
"CreateAudioPlayer failed");
359 result = (*bqPlayerObject)->Realize(bqPlayerObject, SL_BOOLEAN_FALSE);
360 if (SL_RESULT_SUCCESS != result) {
361 LOGE(
"RealizeAudioPlayer failed");
366 result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_PLAY, &bqPlayerPlay);
367 if (SL_RESULT_SUCCESS != result) {
368 LOGE(
"SL_IID_PLAY interface get failed");
373 result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &bqPlayerBufferQueue);
374 if (SL_RESULT_SUCCESS != result) {
375 LOGE(
"SL_IID_BUFFERQUEUE interface get failed");
381 result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, this->hidden);
382 if (SL_RESULT_SUCCESS != result) {
383 LOGE(
"RegisterCallback failed");
389 result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_EFFECTSEND, &bqPlayerEffectSend);
390 if (SL_RESULT_SUCCESS != result)
393 LOGE(
"SL_IID_EFFECTSEND interface get failed");
400 result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_MUTESOLO, &bqPlayerMuteSolo);
401 assert(SL_RESULT_SUCCESS == result);
407 result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_VOLUME, &bqPlayerVolume);
408 if (SL_RESULT_SUCCESS != result) {
409 LOGE(
"SL_IID_VOLUME interface get failed");
417 LOGE(
"cannot create Semaphore!");
423 if (audiodata->
mixbuff == NULL) {
424 LOGE(
"mixbuffer allocate - out of memory");
433 result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING);
434 if (SL_RESULT_SUCCESS != result) {
435 LOGE(
"Play set state failed");
443 openslES_DestroyPCMPlayer(
this);
449 openslES_DestroyPCMPlayer(
_THIS)
455 if (bqPlayerPlay != NULL) {
456 result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_STOPPED);
457 if (SL_RESULT_SUCCESS != result) {
463 if (bqPlayerObject != NULL) {
465 (*bqPlayerObject)->Destroy(bqPlayerObject);
467 bqPlayerObject =
NULL;
469 bqPlayerBufferQueue =
NULL;
471 bqPlayerEffectSend =
NULL;
472 bqPlayerMuteSolo =
NULL;
473 bqPlayerVolume =
NULL;
490 openslES_OpenDevice(
_THIS,
void *
handle,
const char *devname,
int iscapture)
493 if (this->hidden == NULL) {
498 LOGI(
"openslES_OpenDevice( ) %s for capture", devname);
499 return openslES_CreatePCMRecorder(
this);
501 LOGI(
"openslES_OpenDevice( ) %s for playing", devname);
502 return openslES_CreatePCMPlayer(
this);
507 openslES_CloseDevice(
_THIS)
511 if (this->iscapture) {
512 LOGI(
"openslES_CloseDevice( ) for capture");
513 openslES_DestroyPCMRecorder(
this);
515 LOGI(
"openslES_CloseDevice( ) for playing");
516 openslES_DestroyPCMPlayer(
this);
525 openslES_WaitDevice(
_THIS)
529 LOGV(
"openslES_WaitDevice( )");
551 openslES_GetDeviceBuf(
_THIS)
555 LOGV(
"openslES_GetDeviceBuf( )");
560 openslES_PlayDevice(
_THIS)
565 LOGV(
"======openslES_PlayDevice( )======");
568 result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, audiodata->
pmixbuff[audiodata->
next_buffer], this->spec.size);
577 if (SL_RESULT_SUCCESS != result) {
587 LOGI(
"openslES_Init() called");
589 if (!openslES_CreateEngine()) {
593 LOGI(
"openslES_Init() - set pointers");
609 LOGI(
"openslES_Init() - succes");
616 "openslES",
"opensl ES audio driver", openslES_Init, 0
621 if (bqPlayerPlay != NULL) {
623 SLresult result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING);
624 if (SL_RESULT_SUCCESS != result) {
632 if (bqPlayerPlay != NULL) {
634 SLresult result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PAUSED);
635 if (SL_RESULT_SUCCESS != result) {
void openslES_ResumeDevices(void)
SDL_AudioFormat SDL_FirstAudioFormat(SDL_AudioFormat format)
#define SDL_AUDIO_ISBIGENDIAN(x)
#define SDL_CreateSemaphore
static screen_context_t context
void(* PlayDevice)(_THIS)
void(* WaitDevice)(_THIS)
#define SDL_AUDIO_ISSIGNED(x)
Uint16 SDL_AudioFormat
Audio format flags.
Uint8 * pmixbuff[NUM_BUFFERS]
SDL_AudioFormat SDL_NextAudioFormat(void)
AudioBootStrap openslES_bootstrap
int OnlyHasDefaultOutputDevice
EGLImageKHR EGLint EGLint * handle
#define SDL_AUDIO_BITSIZE(x)
void(* Deinitialize)(void)
void SDL_CalculateAudioSpec(SDL_AudioSpec *spec)
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)
int(* OpenDevice)(_THIS, void *handle, const char *devname, int iscapture)
#define SDL_OutOfMemory()
void(* CloseDevice)(_THIS)
#define SDL_AUDIO_ISINT(x)
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 void
#define SDL_DestroySemaphore
Uint8 *(* GetDeviceBuf)(_THIS)
void openslES_PauseDevices(void)