30 #include <winpr/assert.h>
32 #include "rdpsnd_main.h"
33 #include "opensl_io.h"
34 #define CONV16BIT 32768
35 #define CONVMYFLT (1. / 32768.)
37 static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq,
void* context);
44 result = slCreateEngine(&(p->engineObject), 0, NULL, 0, NULL, NULL);
45 DEBUG_SND(
"engineObject=%p", (
void*)p->engineObject);
47 if (result != SL_RESULT_SUCCESS)
51 result = (*p->engineObject)->Realize(p->engineObject, SL_BOOLEAN_FALSE);
52 DEBUG_SND(
"Realize=%" PRIu32
"", result);
54 if (result != SL_RESULT_SUCCESS)
58 result = (*p->engineObject)->GetInterface(p->engineObject, SL_IID_ENGINE, &(p->engineEngine));
59 DEBUG_SND(
"engineEngine=%p", (
void*)p->engineEngine);
61 if (result != SL_RESULT_SUCCESS)
73 SLuint32 channels = p->outchannels;
74 WINPR_ASSERT(p->engineObject);
75 WINPR_ASSERT(p->engineEngine);
80 SLDataLocator_AndroidSimpleBufferQueue loc_bufq = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,
86 sr = SL_SAMPLINGRATE_8;
90 sr = SL_SAMPLINGRATE_11_025;
94 sr = SL_SAMPLINGRATE_16;
98 sr = SL_SAMPLINGRATE_22_05;
102 sr = SL_SAMPLINGRATE_24;
106 sr = SL_SAMPLINGRATE_32;
110 sr = SL_SAMPLINGRATE_44_1;
114 sr = SL_SAMPLINGRATE_48;
118 sr = SL_SAMPLINGRATE_64;
122 sr = SL_SAMPLINGRATE_88_2;
126 sr = SL_SAMPLINGRATE_96;
130 sr = SL_SAMPLINGRATE_192;
137 const SLInterfaceID ids[] = { SL_IID_VOLUME };
138 const SLboolean req[] = { SL_BOOLEAN_FALSE };
139 result = (*p->engineEngine)
140 ->CreateOutputMix(p->engineEngine, &(p->outputMixObject), 1, ids, req);
141 DEBUG_SND(
"engineEngine=%p", (
void*)p->engineEngine);
142 WINPR_ASSERT(!result);
144 if (result != SL_RESULT_SUCCESS)
148 result = (*p->outputMixObject)->Realize(p->outputMixObject, SL_BOOLEAN_FALSE);
149 DEBUG_SND(
"Realize=%" PRIu32
"", result);
150 WINPR_ASSERT(!result);
152 if (result != SL_RESULT_SUCCESS)
158 speakers = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
160 speakers = SL_SPEAKER_FRONT_CENTER;
162 SLDataFormat_PCM format_pcm = { SL_DATAFORMAT_PCM,
165 SL_PCMSAMPLEFORMAT_FIXED_16,
166 SL_PCMSAMPLEFORMAT_FIXED_16,
168 SL_BYTEORDER_LITTLEENDIAN };
169 SLDataSource audioSrc = { &loc_bufq, &format_pcm };
171 SLDataLocator_OutputMix loc_outmix = { SL_DATALOCATOR_OUTPUTMIX, p->outputMixObject };
172 SLDataSink audioSnk = { &loc_outmix, NULL };
174 const SLInterfaceID ids1[] = { SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_VOLUME };
175 const SLboolean req1[] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE };
176 result = (*p->engineEngine)
177 ->CreateAudioPlayer(p->engineEngine, &(p->bqPlayerObject), &audioSrc,
178 &audioSnk, 2, ids1, req1);
179 DEBUG_SND(
"bqPlayerObject=%p", (
void*)p->bqPlayerObject);
180 WINPR_ASSERT(!result);
182 if (result != SL_RESULT_SUCCESS)
186 result = (*p->bqPlayerObject)->Realize(p->bqPlayerObject, SL_BOOLEAN_FALSE);
187 DEBUG_SND(
"Realize=%" PRIu32
"", result);
188 WINPR_ASSERT(!result);
190 if (result != SL_RESULT_SUCCESS)
195 (*p->bqPlayerObject)->GetInterface(p->bqPlayerObject, SL_IID_PLAY, &(p->bqPlayerPlay));
196 DEBUG_SND(
"bqPlayerPlay=%p", (
void*)p->bqPlayerPlay);
197 WINPR_ASSERT(!result);
199 if (result != SL_RESULT_SUCCESS)
203 result = (*p->bqPlayerObject)
204 ->GetInterface(p->bqPlayerObject, SL_IID_VOLUME, &(p->bqPlayerVolume));
205 DEBUG_SND(
"bqPlayerVolume=%p", (
void*)p->bqPlayerVolume);
206 WINPR_ASSERT(!result);
208 if (result != SL_RESULT_SUCCESS)
212 result = (*p->bqPlayerObject)
213 ->GetInterface(p->bqPlayerObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
214 &(p->bqPlayerBufferQueue));
215 DEBUG_SND(
"bqPlayerBufferQueue=%p", (
void*)p->bqPlayerBufferQueue);
216 WINPR_ASSERT(!result);
218 if (result != SL_RESULT_SUCCESS)
222 result = (*p->bqPlayerBufferQueue)
223 ->RegisterCallback(p->bqPlayerBufferQueue, bqPlayerCallback, p);
224 DEBUG_SND(
"bqPlayerCallback=%p", (
void*)p->bqPlayerCallback);
225 WINPR_ASSERT(!result);
227 if (result != SL_RESULT_SUCCESS)
231 result = (*p->bqPlayerPlay)->SetPlayState(p->bqPlayerPlay, SL_PLAYSTATE_PLAYING);
232 DEBUG_SND(
"SetPlayState=%" PRIu32
"", result);
233 WINPR_ASSERT(!result);
235 WINPR_ASSERT(!result);
239 return SL_RESULT_SUCCESS;
246 if (p->bqPlayerObject != NULL)
248 (*p->bqPlayerObject)->Destroy(p->bqPlayerObject);
249 p->bqPlayerObject = NULL;
250 p->bqPlayerVolume = NULL;
251 p->bqPlayerPlay = NULL;
252 p->bqPlayerBufferQueue = NULL;
253 p->bqPlayerEffectSend = NULL;
257 if (p->outputMixObject != NULL)
259 (*p->outputMixObject)->Destroy(p->outputMixObject);
260 p->outputMixObject = NULL;
264 if (p->engineObject != NULL)
266 (*p->engineObject)->Destroy(p->engineObject);
267 p->engineObject = NULL;
268 p->engineEngine = NULL;
273 OPENSL_STREAM* android_OpenAudioDevice(
int sr,
int outchannels,
int bufferframes)
281 p->queuesize = bufferframes;
282 p->outchannels = outchannels;
285 if (openSLCreateEngine(p) != SL_RESULT_SUCCESS)
287 android_CloseAudioDevice(p);
291 if (openSLPlayOpen(p) != SL_RESULT_SUCCESS)
293 android_CloseAudioDevice(p);
297 p->queue = Queue_New(TRUE, -1, -1);
301 android_CloseAudioDevice(p);
314 openSLDestroyEngine(p);
317 Queue_Free(p->queue);
323 static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq,
void* context)
327 WINPR_ASSERT(p->queue);
328 void* data = Queue_Dequeue(p->queue);
333 int android_AudioOut(
OPENSL_STREAM* p,
const short* buffer,
int size)
337 WINPR_ASSERT(buffer);
338 WINPR_ASSERT(size > 0);
340 ev = Queue_Event(p->queue);
342 if (p->queuesize <= Queue_Count(p->queue) && WaitForSingleObject(ev, INFINITE) == WAIT_FAILED)
344 DEBUG_SND(
"WaitForSingleObject failed!");
348 void* data = calloc(size,
sizeof(
short));
352 DEBUG_SND(
"unable to allocate a buffer");
356 memcpy(data, buffer, size *
sizeof(
short));
357 Queue_Enqueue(p->queue, data);
358 (*p->bqPlayerBufferQueue)->Enqueue(p->bqPlayerBufferQueue, data,
sizeof(
short) * size);
366 WINPR_ASSERT(p->bqPlayerVolume);
367 SLresult rc = (*p->bqPlayerVolume)->GetMute(p->bqPlayerVolume, &mute);
369 if (SL_RESULT_SUCCESS != rc)
370 return SL_BOOLEAN_FALSE;
377 SLboolean mute = _mute;
379 WINPR_ASSERT(p->bqPlayerVolume);
380 SLresult rc = (*p->bqPlayerVolume)->SetMute(p->bqPlayerVolume, mute);
382 if (SL_RESULT_SUCCESS != rc)
392 WINPR_ASSERT(p->bqPlayerVolume);
393 SLresult rc = (*p->bqPlayerVolume)->GetVolumeLevel(p->bqPlayerVolume, &level);
395 if (SL_RESULT_SUCCESS != rc)
405 WINPR_ASSERT(p->bqPlayerVolume);
406 SLresult rc = (*p->bqPlayerVolume)->GetMaxVolumeLevel(p->bqPlayerVolume, &level);
408 if (SL_RESULT_SUCCESS != rc)
416 SLresult rc = (*p->bqPlayerVolume)->SetVolumeLevel(p->bqPlayerVolume, level);
418 if (SL_RESULT_SUCCESS != rc)