30 #include <SLES/OpenSLES.h>
32 #include <SLES/OpenSLES_Android.h>
34 extern SLAPIENTRY
const SLInterfaceID SL_IID_ANDROIDSIMPLEBUFFERQUEUE;
36 struct SLAndroidSimpleBufferQueueItf_;
37 typedef const struct SLAndroidSimpleBufferQueueItf_ *
const * SLAndroidSimpleBufferQueueItf;
39 typedef void (*slAndroidSimpleBufferQueueCallback)(SLAndroidSimpleBufferQueueItf caller,
void *
pContext);
41 typedef struct SLAndroidSimpleBufferQueueState_ {
44 } SLAndroidSimpleBufferQueueState;
47 struct SLAndroidSimpleBufferQueueItf_ {
49 SLAndroidSimpleBufferQueueItf
self,
54 SLAndroidSimpleBufferQueueItf self
56 SLresult (*GetState) (
57 SLAndroidSimpleBufferQueueItf
self,
58 SLAndroidSimpleBufferQueueState *
pState
60 SLresult (*RegisterCallback) (
61 SLAndroidSimpleBufferQueueItf
self,
62 slAndroidSimpleBufferQueueCallback callback,
67 #define SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE ((SLuint32) 0x800007BD)
69 typedef struct SLDataLocator_AndroidSimpleBufferQueue {
72 } SLDataLocator_AndroidSimpleBufferQueue;
77 #define SLObjectItf_Realize(a,b) ((*(a))->Realize((a),(b)))
78 #define SLObjectItf_GetInterface(a,b,c) ((*(a))->GetInterface((a),(b),(c)))
79 #define SLObjectItf_Destroy(a) ((*(a))->Destroy((a)))
81 #define SLEngineItf_CreateOutputMix(a,b,c,d,e) ((*(a))->CreateOutputMix((a),(b),(c),(d),(e)))
82 #define SLEngineItf_CreateAudioPlayer(a,b,c,d,e,f,g) ((*(a))->CreateAudioPlayer((a),(b),(c),(d),(e),(f),(g)))
84 #define SLPlayItf_SetPlayState(a,b) ((*(a))->SetPlayState((a),(b)))
89 SLObjectItf engineObject;
93 SLObjectItf outputMix;
96 SLObjectItf bufferQueueObject;
112 case DevFmtMono:
return SL_SPEAKER_FRONT_CENTER;
113 case DevFmtStereo:
return SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT;
114 case DevFmtQuad:
return SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT|
115 SL_SPEAKER_BACK_LEFT|SL_SPEAKER_BACK_RIGHT;
116 case DevFmtX51:
return SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT|
117 SL_SPEAKER_FRONT_CENTER|SL_SPEAKER_LOW_FREQUENCY|
118 SL_SPEAKER_BACK_LEFT|SL_SPEAKER_BACK_RIGHT;
119 case DevFmtX61:
return SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT|
120 SL_SPEAKER_FRONT_CENTER|SL_SPEAKER_LOW_FREQUENCY|
121 SL_SPEAKER_BACK_CENTER|
122 SL_SPEAKER_SIDE_LEFT|SL_SPEAKER_SIDE_RIGHT;
123 case DevFmtX71:
return SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT|
124 SL_SPEAKER_FRONT_CENTER|SL_SPEAKER_LOW_FREQUENCY|
125 SL_SPEAKER_BACK_LEFT|SL_SPEAKER_BACK_RIGHT|
126 SL_SPEAKER_SIDE_LEFT|SL_SPEAKER_SIDE_RIGHT;
127 case DevFmtX51Side:
return SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT|
128 SL_SPEAKER_FRONT_CENTER|SL_SPEAKER_LOW_FREQUENCY|
129 SL_SPEAKER_SIDE_LEFT|SL_SPEAKER_SIDE_RIGHT;
138 case SL_RESULT_SUCCESS:
return "Success";
139 case SL_RESULT_PRECONDITIONS_VIOLATED:
return "Preconditions violated";
140 case SL_RESULT_PARAMETER_INVALID:
return "Parameter invalid";
141 case SL_RESULT_MEMORY_FAILURE:
return "Memory failure";
142 case SL_RESULT_RESOURCE_ERROR:
return "Resource error";
143 case SL_RESULT_RESOURCE_LOST:
return "Resource lost";
144 case SL_RESULT_IO_ERROR:
return "I/O error";
145 case SL_RESULT_BUFFER_INSUFFICIENT:
return "Buffer insufficient";
146 case SL_RESULT_CONTENT_CORRUPTED:
return "Content corrupted";
147 case SL_RESULT_CONTENT_UNSUPPORTED:
return "Content unsupported";
148 case SL_RESULT_CONTENT_NOT_FOUND:
return "Content not found";
149 case SL_RESULT_PERMISSION_DENIED:
return "Permission denied";
150 case SL_RESULT_FEATURE_UNSUPPORTED:
return "Feature unsupported";
151 case SL_RESULT_INTERNAL_ERROR:
return "Internal error";
152 case SL_RESULT_UNKNOWN_ERROR:
return "Unknown error";
153 case SL_RESULT_OPERATION_ABORTED:
return "Operation aborted";
154 case SL_RESULT_CONTROL_LOST:
return "Control lost";
155 case SL_RESULT_READONLY:
return "ReadOnly";
156 case SL_RESULT_ENGINEOPTION_UNSUPPORTED:
return "Engine option unsupported";
157 case SL_RESULT_SOURCE_SINK_INCOMPATIBLE:
return "Source/Sink incompatible";
159 return "Unknown error code";
162 #define PRINTERR(x, s) do { \
163 if((x) != SL_RESULT_SUCCESS) \
164 ERR("%s: %s\n", (s), res_str((x))); \
174 aluMixData(Device, data->buffer, data->bufferSize/data->frameSize);
176 result = (*bq)->Enqueue(bq, data->buffer, data->bufferSize);
191 data =
calloc(1,
sizeof(*data));
196 result = slCreateEngine(&data->engineObject, 0,
NULL, 0,
NULL,
NULL);
198 if(SL_RESULT_SUCCESS == result)
201 PRINTERR(result,
"engine->Realize");
203 if(SL_RESULT_SUCCESS == result)
206 PRINTERR(result,
"engine->GetInterface");
208 if(SL_RESULT_SUCCESS == result)
211 PRINTERR(result,
"engine->CreateOutputMix");
213 if(SL_RESULT_SUCCESS == result)
216 PRINTERR(result,
"outputMix->Realize");
219 if(SL_RESULT_SUCCESS != result)
221 if(data->outputMix !=
NULL)
223 data->outputMix =
NULL;
225 if(data->engineObject !=
NULL)
227 data->engineObject =
NULL;
245 if(data->bufferQueueObject !=
NULL)
247 data->bufferQueueObject =
NULL;
250 data->outputMix =
NULL;
253 data->engineObject =
NULL;
263 SLDataLocator_AndroidSimpleBufferQueue loc_bufq;
264 SLDataLocator_OutputMix loc_outmix;
265 SLDataFormat_PCM format_pcm;
266 SLDataSource audioSrc;
284 id = SL_IID_ANDROIDSIMPLEBUFFERQUEUE;
285 req = SL_BOOLEAN_TRUE;
287 loc_bufq.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
290 format_pcm.formatType = SL_DATAFORMAT_PCM;
292 format_pcm.samplesPerSec = Device->
Frequency * 1000;
294 format_pcm.containerSize = format_pcm.bitsPerSample;
296 format_pcm.endianness = SL_BYTEORDER_NATIVE;
298 audioSrc.pLocator = &loc_bufq;
299 audioSrc.pFormat = &format_pcm;
301 loc_outmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
302 loc_outmix.outputMix = data->outputMix;
303 audioSnk.pLocator = &loc_outmix;
304 audioSnk.pFormat =
NULL;
307 if(data->bufferQueueObject !=
NULL)
309 data->bufferQueueObject =
NULL;
312 PRINTERR(result,
"engine->CreateAudioPlayer");
313 if(SL_RESULT_SUCCESS == result)
316 PRINTERR(result,
"bufferQueue->Realize");
319 if(SL_RESULT_SUCCESS != result)
321 if(data->bufferQueueObject !=
NULL)
323 data->bufferQueueObject =
NULL;
334 SLAndroidSimpleBufferQueueItf bufferQueue;
340 PRINTERR(result,
"bufferQueue->GetInterface");
341 if(SL_RESULT_SUCCESS == result)
343 result = (*bufferQueue)->RegisterCallback(bufferQueue,
opensl_callback, Device);
344 PRINTERR(result,
"bufferQueue->RegisterCallback");
346 if(SL_RESULT_SUCCESS == result)
349 data->bufferSize = Device->
UpdateSize * data->frameSize;
350 data->buffer =
calloc(1, data->bufferSize);
353 result = SL_RESULT_MEMORY_FAILURE;
360 if(SL_RESULT_SUCCESS == result)
362 result = (*bufferQueue)->Enqueue(bufferQueue, data->buffer, data->bufferSize);
363 PRINTERR(result,
"bufferQueue->Enqueue");
366 if(SL_RESULT_SUCCESS == result)
369 PRINTERR(result,
"bufferQueue->GetInterface");
371 if(SL_RESULT_SUCCESS == result)
374 PRINTERR(result,
"player->SetPlayState");
377 if(SL_RESULT_SUCCESS != result)
379 if(data->bufferQueueObject !=
NULL)
381 data->bufferQueueObject =
NULL;
385 data->bufferSize = 0;
400 data->bufferSize = 0;
#define SLObjectItf_Realize(a, b)
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum type
GLvoid **typedef void(GLAPIENTRY *PFNGLGETVERTEXATTRIBDVPROC)(GLuint
char * strdup(const char *inStr)
static void opensl_stop_playback(ALCdevice *Device)
ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
ALint64 ALCdevice_GetLatencyDefault(ALCdevice *device)
static const ALCchar opensl_device[]
static void opensl_close_playback(ALCdevice *Device)
EGLContext EGLenum EGLClientBuffer buffer
static const char * res_str(SLresult result)
void alc_opensl_deinit(void)
static void opensl_callback(SLAndroidSimpleBufferQueueItf bq, void *context)
void SetDefaultWFXChannelOrder(ALCdevice *device)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
ALCboolean alc_opensl_init(BackendFuncs *func_list)
#define SLPlayItf_SetPlayState(a, b)
#define SLEngineItf_CreateAudioPlayer(a, b, c, d, e, f, g)
void alc_opensl_probe(enum DevProbe type)
enum DevFmtChannels FmtChans
void ALCdevice_LockDefault(ALCdevice *device)
static const BackendFuncs opensl_funcs
static SLuint32 GetChannelMask(enum DevFmtChannels chans)
#define SLEngineItf_CreateOutputMix(a, b, c, d, e)
#define ALC_INVALID_VALUE
#define ALC_OUT_OF_MEMORY
static ALCboolean opensl_reset_playback(ALCdevice *Device)
#define SLObjectItf_Destroy(a)
ALuint BytesFromDevFmt(enum DevFmtType type)
void ALCdevice_UnlockDefault(ALCdevice *device)
ALuint ChannelsFromDevFmt(enum DevFmtChannels chans)
static ALCenum opensl_open_playback(ALCdevice *Device, const ALCchar *deviceName)
#define SLObjectItf_GetInterface(a, b, c)
void AppendAllDevicesList(const ALCchar *name)
static ALCboolean opensl_start_playback(ALCdevice *Device)
static __inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type)