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__)
53static SLObjectItf engineObject =
NULL;
54static SLEngineItf engineEngine =
NULL;
57static SLObjectItf outputMixObject =
NULL;
64static SLObjectItf bqPlayerObject =
NULL;
65static SLPlayItf bqPlayerPlay =
NULL;
66static SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue =
NULL;
68static SLEffectSendItf bqPlayerEffectSend =
NULL;
69static SLMuteSoloItf bqPlayerMuteSolo =
NULL;
70static SLVolumeItf bqPlayerVolume =
NULL;
75static SLObjectItf recorderObject =
NULL;
76static SLRecordItf recorderRecord;
77static SLAndroidSimpleBufferQueueItf recorderBufferQueue;
82static short *nextBuffer;
83static unsigned nextSize;
90static const char *sldevaudiorecorderstr =
"SLES Audio Recorder";
91static const char *sldevaudioplayerstr =
"SLES Audio Player";
93#define SLES_DEV_AUDIO_RECORDER sldevaudiorecorderstr
94#define SLES_DEV_AUDIO_PLAYER sldevaudioplayerstr
95static void openslES_DetectDevices(
int iscapture )
97 LOGI(
"openSLES_DetectDevices()" );
99 addfn( SLES_DEV_AUDIO_RECORDER );
101 addfn( SLES_DEV_AUDIO_PLAYER );
106static void openslES_DestroyEngine();
109openslES_CreateEngine()
113 LOGI(
"openSLES_CreateEngine()");
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();
169static void openslES_DestroyPCMPlayer(
_THIS);
170static void openslES_DestroyPCMRecorder(
_THIS);
172static 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);
198bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq,
void *
context)
201 LOGV(
"SLES: Playback Callmeback");
207openslES_CreatePCMRecorder(
_THIS)
211 LOGE(
"openslES_CreatePCMRecorder not implimented yet!");
212 return SDL_SetError(
"openslES_CreatePCMRecorder not implimented yet!");
216openslES_DestroyPCMRecorder(
_THIS)
224openslES_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);
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!");
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);
449openslES_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;
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);
507openslES_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);
525openslES_WaitDevice(
_THIS)
529 LOGV(
"openslES_WaitDevice( )");
551openslES_GetDeviceBuf(
_THIS)
555 LOGV(
"openslES_GetDeviceBuf( )");
560openslES_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 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
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_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 OnlyHasDefaultOutputDevice
void(* Deinitialize)(void)
int(* OpenDevice)(_THIS, void *handle, const char *devname, int iscapture)
Uint8 *(* GetDeviceBuf)(_THIS)
Uint8 * pmixbuff[NUM_BUFFERS]
static screen_context_t context