Merge pull request #2414 from zavadovsky/opensles_fixes
[platform/upstream/freerdp.git] / channels / rdpsnd / client / opensles / opensl_io.c
1 /*
2 opensl_io.c:
3 Android OpenSL input/output module
4 Copyright (c) 2012, Victor Lazzarini
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9     * Redistributions of source code must retain the above copyright
10       notice, this list of conditions and the following disclaimer.
11     * Redistributions in binary form must reproduce the above copyright
12       notice, this list of conditions and the following disclaimer in the
13       documentation and/or other materials provided with the distribution.
14     * Neither the name of the <organization> nor the
15       names of its contributors may be used to endorse or promote products
16       derived from this software without specific prior written permission.
17
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
22 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include <assert.h>
31
32 #include "rdpsnd_main.h"
33 #include "opensl_io.h"
34 #define CONV16BIT 32768
35 #define CONVMYFLT (1./32768.)
36
37 static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context);
38
39 // creates the OpenSL ES audio engine
40 static SLresult openSLCreateEngine(OPENSL_STREAM *p)
41 {
42   SLresult result;
43   // create engine
44   result = slCreateEngine(&(p->engineObject), 0, NULL, 0, NULL, NULL);
45         DEBUG_SND("engineObject=%p", p->engineObject);
46   if(result != SL_RESULT_SUCCESS) goto  engine_end;
47
48   // realize the engine 
49   result = (*p->engineObject)->Realize(p->engineObject, SL_BOOLEAN_FALSE);
50         DEBUG_SND("Realize=%d", result);
51   if(result != SL_RESULT_SUCCESS) goto engine_end;
52
53   // get the engine interface, which is needed in order to create other objects
54   result = (*p->engineObject)->GetInterface(p->engineObject, SL_IID_ENGINE, &(p->engineEngine));
55         DEBUG_SND("engineEngine=%p", p->engineEngine);
56   if(result != SL_RESULT_SUCCESS) goto  engine_end;
57
58  engine_end:
59   return result;
60 }
61
62 // opens the OpenSL ES device for output
63 static SLresult openSLPlayOpen(OPENSL_STREAM *p)
64 {
65   SLresult result;
66   SLuint32 sr = p->sr;
67   SLuint32  channels = p->outchannels;
68
69         assert(p->engineObject);
70         assert(p->engineEngine);
71
72   if(channels){
73     // configure audio source
74     SLDataLocator_AndroidSimpleBufferQueue loc_bufq =
75                 {
76                         SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,
77                         p->queuesize
78                 };
79
80     switch(sr){
81
82     case 8000:
83       sr = SL_SAMPLINGRATE_8;
84       break;
85     case 11025:
86       sr = SL_SAMPLINGRATE_11_025;
87       break;
88     case 16000:
89       sr = SL_SAMPLINGRATE_16;
90       break;
91     case 22050:
92       sr = SL_SAMPLINGRATE_22_05;
93       break;
94     case 24000:
95       sr = SL_SAMPLINGRATE_24;
96       break;
97     case 32000:
98       sr = SL_SAMPLINGRATE_32;
99       break;
100     case 44100:
101       sr = SL_SAMPLINGRATE_44_1;
102       break;
103     case 48000:
104       sr = SL_SAMPLINGRATE_48;
105       break;
106     case 64000:
107       sr = SL_SAMPLINGRATE_64;
108       break;
109     case 88200:
110       sr = SL_SAMPLINGRATE_88_2;
111       break;
112     case 96000:
113       sr = SL_SAMPLINGRATE_96;
114       break;
115     case 192000:
116       sr = SL_SAMPLINGRATE_192;
117       break;
118     default:
119       return -1;
120     }
121    
122     const SLInterfaceID ids[] = {SL_IID_VOLUME};
123     const SLboolean req[] = {SL_BOOLEAN_FALSE};
124     result = (*p->engineEngine)->CreateOutputMix(p->engineEngine, &(p->outputMixObject), 1, ids, req);
125                 DEBUG_SND("engineEngine=%p", p->engineEngine);
126                 assert(!result);
127     if(result != SL_RESULT_SUCCESS) goto end_openaudio;
128
129     // realize the output mix
130     result = (*p->outputMixObject)->Realize(p->outputMixObject, SL_BOOLEAN_FALSE);
131                 DEBUG_SND("Realize=%d", result);
132                 assert(!result);
133     if(result != SL_RESULT_SUCCESS) goto end_openaudio;
134    
135     int speakers;
136     if(channels > 1) 
137       speakers = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
138     else speakers = SL_SPEAKER_FRONT_CENTER;
139     SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM,channels, sr,
140                                    SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16,
141                                    speakers, SL_BYTEORDER_LITTLEENDIAN};
142
143     SLDataSource audioSrc = {&loc_bufq, &format_pcm};
144
145     // configure audio sink
146     SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, p->outputMixObject};
147     SLDataSink audioSnk = {&loc_outmix, NULL};
148
149     // create audio player
150     const SLInterfaceID ids1[] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_VOLUME};
151     const SLboolean req1[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
152     result = (*p->engineEngine)->CreateAudioPlayer(p->engineEngine,
153                                 &(p->bqPlayerObject), &audioSrc, &audioSnk, 2, ids1, req1);
154                 DEBUG_SND("bqPlayerObject=%p", p->bqPlayerObject);
155                 assert(!result);
156     if(result != SL_RESULT_SUCCESS) goto end_openaudio;
157
158     // realize the player
159     result = (*p->bqPlayerObject)->Realize(p->bqPlayerObject, SL_BOOLEAN_FALSE);
160                 DEBUG_SND("Realize=%d", result);
161                 assert(!result);
162     if(result != SL_RESULT_SUCCESS) goto end_openaudio;
163
164     // get the play interface
165     result = (*p->bqPlayerObject)->GetInterface(p->bqPlayerObject, SL_IID_PLAY, &(p->bqPlayerPlay));
166                 DEBUG_SND("bqPlayerPlay=%p", p->bqPlayerPlay);
167                 assert(!result);
168     if(result != SL_RESULT_SUCCESS) goto end_openaudio;
169
170     // get the volume interface
171     result = (*p->bqPlayerObject)->GetInterface(p->bqPlayerObject, SL_IID_VOLUME, &(p->bqPlayerVolume));
172                 DEBUG_SND("bqPlayerVolume=%p", p->bqPlayerVolume);
173                 assert(!result);
174     if(result != SL_RESULT_SUCCESS) goto end_openaudio;
175
176     // get the buffer queue interface
177     result = (*p->bqPlayerObject)->GetInterface(p->bqPlayerObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
178                                                 &(p->bqPlayerBufferQueue));
179                 DEBUG_SND("bqPlayerBufferQueue=%p", p->bqPlayerBufferQueue);
180                 assert(!result);
181     if(result != SL_RESULT_SUCCESS) goto end_openaudio;
182
183     // register callback on the buffer queue
184     result = (*p->bqPlayerBufferQueue)->RegisterCallback(p->bqPlayerBufferQueue, bqPlayerCallback, p);
185                 DEBUG_SND("bqPlayerCallback=%p", p->bqPlayerCallback);
186                 assert(!result);
187     if(result != SL_RESULT_SUCCESS) goto end_openaudio;
188
189     // set the player's state to playing
190     result = (*p->bqPlayerPlay)->SetPlayState(p->bqPlayerPlay, SL_PLAYSTATE_PLAYING);
191                 DEBUG_SND("SetPlayState=%d", result);
192                 assert(!result);
193  
194   end_openaudio:
195                 assert(!result);
196     return result;
197   }
198   return SL_RESULT_SUCCESS;
199 }
200
201 // close the OpenSL IO and destroy the audio engine
202 static void openSLDestroyEngine(OPENSL_STREAM *p){
203
204   // destroy buffer queue audio player object, and invalidate all associated interfaces
205   if (p->bqPlayerObject != NULL) {
206     (*p->bqPlayerObject)->Destroy(p->bqPlayerObject);
207     p->bqPlayerObject = NULL;
208     p->bqPlayerVolume = NULL;
209     p->bqPlayerPlay = NULL;
210     p->bqPlayerBufferQueue = NULL;
211     p->bqPlayerEffectSend = NULL;
212   }
213
214   // destroy output mix object, and invalidate all associated interfaces
215   if (p->outputMixObject != NULL) {
216     (*p->outputMixObject)->Destroy(p->outputMixObject);
217     p->outputMixObject = NULL;
218   }
219
220   // destroy engine object, and invalidate all associated interfaces
221   if (p->engineObject != NULL) {
222     (*p->engineObject)->Destroy(p->engineObject);
223     p->engineObject = NULL;
224     p->engineEngine = NULL;
225   }
226
227 }
228
229
230 // open the android audio device for and/or output
231 OPENSL_STREAM *android_OpenAudioDevice(int sr, int outchannels, int bufferframes){
232         OPENSL_STREAM *p;
233         p = (OPENSL_STREAM *) calloc(sizeof(OPENSL_STREAM), 1);
234         if (!p)
235                 return NULL;
236
237         p->queuesize = bufferframes;
238         p->outchannels = outchannels;
239         p->sr = sr;
240
241         if(openSLCreateEngine(p) != SL_RESULT_SUCCESS)
242         {
243                 android_CloseAudioDevice(p);
244                 return NULL;
245         }
246
247         if(openSLPlayOpen(p) != SL_RESULT_SUCCESS)
248         {
249                 android_CloseAudioDevice(p);
250                 return NULL;
251         }
252
253         p->queue = Queue_New(TRUE, -1, -1);
254         if (!p->queue)
255         {
256                 android_CloseAudioDevice(p);
257                 return NULL;
258         }
259
260         return p;
261 }
262
263 // close the android audio device
264 void android_CloseAudioDevice(OPENSL_STREAM *p){
265
266   if (p == NULL)
267     return;
268
269   openSLDestroyEngine(p);
270         if (p->queue)
271                 Queue_Free(p->queue);
272
273   free(p);
274 }
275
276 // this callback handler is called every time a buffer finishes playing
277 void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context)
278 {
279   OPENSL_STREAM *p = (OPENSL_STREAM *) context;
280
281         assert(p);
282         assert(p->queue);
283
284         void *data = Queue_Dequeue(p->queue);
285         free(data);
286 }
287
288 // puts a buffer of size samples to the device
289 int android_AudioOut(OPENSL_STREAM *p, const short *buffer,int size)
290 {
291         assert(p);
292         assert(buffer);
293         assert(size > 0);
294
295         /* Assure, that the queue is not full. */
296         if (p->queuesize <= Queue_Count(p->queue) && WaitForSingleObject(p->queue->event, INFINITE) == WAIT_FAILED)
297     {
298         DEBUG_SND("WaitForSingleObject failed!");
299         return -1;
300     }
301
302         void *data = calloc(size, sizeof(short));
303         if (!data)
304         {
305                 DEBUG_SND("unable to allocate a buffer");
306                 return -1;
307         }
308         memcpy(data, buffer, size * sizeof(short));
309         Queue_Enqueue(p->queue, data);
310         (*p->bqPlayerBufferQueue)->Enqueue(p->bqPlayerBufferQueue, 
311                 data, sizeof(short) * size);
312   
313         return size;
314 }
315
316 int android_GetOutputMute(OPENSL_STREAM *p) {
317         SLboolean mute;
318
319         assert(p);
320         assert(p->bqPlayerVolume);
321
322         SLresult rc = (*p->bqPlayerVolume)->GetMute(p->bqPlayerVolume, &mute);
323         assert(SL_RESULT_SUCCESS == rc);
324
325         return mute;
326 }
327
328 void android_SetOutputMute(OPENSL_STREAM *p, BOOL _mute) {
329         SLboolean mute = _mute;
330
331         assert(p);
332         assert(p->bqPlayerVolume);
333
334         SLresult rc = (*p->bqPlayerVolume)->SetMute(p->bqPlayerVolume, mute);
335         assert(SL_RESULT_SUCCESS == rc);
336 }
337
338 int android_GetOutputVolume(OPENSL_STREAM *p){
339         SLmillibel level;
340
341         assert(p);
342         assert(p->bqPlayerVolume);
343
344         SLresult rc = (*p->bqPlayerVolume)->GetVolumeLevel(p->bqPlayerVolume, &level);
345         assert(SL_RESULT_SUCCESS == rc);
346
347         return level;
348 }
349
350 int android_GetOutputVolumeMax(OPENSL_STREAM *p){
351         SLmillibel level;
352
353         assert(p);
354         assert(p->bqPlayerVolume);
355
356         SLresult rc = (*p->bqPlayerVolume)->GetMaxVolumeLevel(p->bqPlayerVolume, &level);
357         assert(SL_RESULT_SUCCESS == rc);
358
359         return level;
360 }
361
362
363 void android_SetOutputVolume(OPENSL_STREAM *p, int level){
364         SLresult rc = (*p->bqPlayerVolume)->SetVolumeLevel(p->bqPlayerVolume, level);
365         assert(SL_RESULT_SUCCESS == rc);
366 }
367