1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 
18 ////////////////////////////////////////////
19 /// Actual sles functions.
20 
21 
22 // Test program to record from default audio input and playback to default audio output.
23 // It will generate feedback (Larsen effect) if played through on-device speakers,
24 // or acts as a delay if played through headset.
25 
26 #include "sles.h"
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <stddef.h>
30 
31 #include <assert.h>
32 #include <pthread.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <unistd.h>
37 
slesInit(sles_data ** ppSles,int samplingRate,int frameCount,int micSource)38 int slesInit(sles_data ** ppSles, int samplingRate, int frameCount, int micSource) {
39     int status = SLES_FAIL;
40     if (ppSles != NULL) {
41         sles_data * pSles = (sles_data*) calloc(1, sizeof (sles_data));
42 
43         SLES_PRINTF("malloc %d bytes at %p",sizeof(sles_data), pSles);
44         *ppSles = pSles;
45         if (pSles != NULL)
46         {
47             SLES_PRINTF("creating server. Sampling rate =%d, frame count = %d",samplingRate,
48                     frameCount);
49             status = slesCreateServer(pSles, samplingRate, frameCount, micSource);
50             SLES_PRINTF("slesCreateServer =%d",status);
51         }
52     }
53     return status;
54 }
slesDestroy(sles_data ** ppSles)55 int slesDestroy(sles_data ** ppSles) {
56     int status = SLES_FAIL;
57     if (ppSles != NULL) {
58         slesDestroyServer(*ppSles);
59 
60         if (*ppSles != NULL)
61         {
62             free(*ppSles);
63             *ppSles = 0;
64         }
65         status = SLES_SUCCESS;
66     }
67     return status;
68 }
69 
70 #define ASSERT_EQ(x, y) do { if ((x) == (y)) ; else { fprintf(stderr, "0x%x != 0x%x\n", \
71         (unsigned) (x), (unsigned) (y)); assert((x) == (y)); } } while (0)
72 
73 
74 // Called after audio recorder fills a buffer with data
recorderCallback(SLAndroidSimpleBufferQueueItf caller __unused,void * context)75 static void recorderCallback(SLAndroidSimpleBufferQueueItf caller __unused, void *context) {
76     sles_data *pSles = (sles_data*) context;
77     if (pSles != NULL) {
78 
79 
80 
81         SLresult result;
82 
83         pthread_mutex_lock(&(pSles->mutex));
84         //ee  SLES_PRINTF("<R");
85 
86         // We should only be called when a recording buffer is done
87         assert(pSles->rxFront <= pSles->rxBufCount);
88         assert(pSles->rxRear <= pSles->rxBufCount);
89         assert(pSles->rxFront != pSles->rxRear);
90         char *buffer = pSles->rxBuffers[pSles->rxFront];
91 
92         // Remove buffer from record queue
93         if (++pSles->rxFront > pSles->rxBufCount) {
94             pSles->rxFront = 0;
95         }
96 
97         ssize_t actual = audio_utils_fifo_write(&(pSles->fifo), buffer,
98                 (size_t) pSles->bufSizeInFrames);
99         if (actual != (ssize_t) pSles->bufSizeInFrames) {
100             write(1, "?", 1);
101         }
102 
103         // This is called by a realtime (SCHED_FIFO) thread,
104         // and it is unsafe to do I/O as it could block for unbounded time.
105         // Flash filesystem is especially notorious for blocking.
106         if (pSles->fifo2Buffer != NULL) {
107             actual = audio_utils_fifo_write(&(pSles->fifo2), buffer,
108                     (size_t) pSles->bufSizeInFrames);
109             if (actual != (ssize_t) pSles->bufSizeInFrames) {
110                 write(1, "?", 1);
111             }
112         }
113 
114         // Enqueue this same buffer for the recorder to fill again.
115         result = (*(pSles->recorderBufferQueue))->Enqueue(pSles->recorderBufferQueue, buffer,
116                 pSles->bufSizeInBytes);
117         ASSERT_EQ(SL_RESULT_SUCCESS, result);
118 
119         // Update our model of the record queue
120         SLuint32 rxRearNext = pSles->rxRear+1;
121         if (rxRearNext > pSles->rxBufCount) {
122             rxRearNext = 0;
123         }
124         assert(rxRearNext != pSles->rxFront);
125         pSles->rxBuffers[pSles->rxRear] = buffer;
126         pSles->rxRear = rxRearNext;
127 
128 
129 
130         //ee  SLES_PRINTF("r>");
131         pthread_mutex_unlock(&(pSles->mutex));
132 
133     } //pSles not null
134 }
135 
136 
137 // Called after audio player empties a buffer of data
playerCallback(SLBufferQueueItf caller __unused,void * context)138 static void playerCallback(SLBufferQueueItf caller __unused, void *context) {
139     sles_data *pSles = (sles_data*) context;
140     if (pSles != NULL) {
141 
142         SLresult result;
143 
144         pthread_mutex_lock(&(pSles->mutex));
145         //ee  SLES_PRINTF("<P");
146 
147         // Get the buffer that just finished playing
148         assert(pSles->txFront <= pSles->txBufCount);
149         assert(pSles->txRear <= pSles->txBufCount);
150         assert(pSles->txFront != pSles->txRear);
151         char *buffer = pSles->txBuffers[pSles->txFront];
152         if (++pSles->txFront > pSles->txBufCount) {
153             pSles->txFront = 0;
154         }
155 
156 
157         ssize_t actual = audio_utils_fifo_read(&(pSles->fifo), buffer, pSles->bufSizeInFrames);
158         if (actual != (ssize_t) pSles->bufSizeInFrames) {
159             write(1, "/", 1);
160             // on underrun from pipe, substitute silence
161             memset(buffer, 0, pSles->bufSizeInFrames * pSles->channels * sizeof(short));
162         }
163 
164         if (pSles->injectImpulse == -1) {
165             // Experimentally, a single frame impulse was insufficient to trigger feedback.
166             // Also a Nyquist frequency signal was also insufficient, probably because
167             // the response of output and/or input path was not adequate at high frequencies.
168             // This short burst of a few cycles of square wave at Nyquist/4 was found to work well.
169             for (unsigned i = 0; i < pSles->bufSizeInFrames / 8; i += 8) {
170                 for (int j = 0; j < 8; j++) {
171                     for (unsigned k = 0; k < pSles->channels; k++) {
172                         ((short *)buffer)[(i+j)*pSles->channels+k] = j < 4 ? 0x7FFF : 0x8000;
173                     }
174                 }
175             }
176             pSles->injectImpulse = 0;
177         }
178 
179         // Enqueue the filled buffer for playing
180         result = (*(pSles->playerBufferQueue))->Enqueue(pSles->playerBufferQueue, buffer,
181                 pSles->bufSizeInBytes);
182         ASSERT_EQ(SL_RESULT_SUCCESS, result);
183 
184         // Update our model of the player queue
185         assert(pSles->txFront <= pSles->txBufCount);
186         assert(pSles->txRear <= pSles->txBufCount);
187         SLuint32 txRearNext = pSles->txRear+1;
188         if (txRearNext > pSles->txBufCount) {
189             txRearNext = 0;
190         }
191         assert(txRearNext != pSles->txFront);
192         pSles->txBuffers[pSles->txRear] = buffer;
193         pSles->txRear = txRearNext;
194 
195 
196         //ee    SLES_PRINTF("p>");
197         pthread_mutex_unlock(&(pSles->mutex));
198 
199     } //pSles not null
200 }
201 
slesCreateServer(sles_data * pSles,int samplingRate,int frameCount,int micSource)202 int slesCreateServer(sles_data *pSles, int samplingRate, int frameCount, int micSource) {
203     int status = SLES_FAIL;
204 
205     if (pSles == NULL) {
206         return status;
207     }
208 
209     //        adb shell slesTest_feedback -r1 -t1 -s48000 -f240 -i300 -e3 -o/sdcard/log.wav
210     //            r1 and t1 are the receive and transmit buffer counts, typically 1
211     //            s is the sample rate, typically 48000 or 44100
212     //            f is the frame count per buffer, typically 240 or 256
213     //            i is the number of milliseconds before impulse.  You may need to adjust this.
214     //            e is number of seconds to record
215     //            o is output .wav file name
216 
217 
218     //        // default values
219     //        SLuint32 rxBufCount = 1;     // -r#
220     //        SLuint32 txBufCount = 1;     // -t#
221     //        SLuint32 bufSizeInFrames = 240;  // -f#
222     //        SLuint32 channels = 1;       // -c#
223     //        SLuint32 sampleRate = 48000; // -s#
224     //        SLuint32 exitAfterSeconds = 3; // -e#
225     //        SLuint32 freeBufCount = 0;   // calculated
226     //        SLuint32 bufSizeInBytes = 0; // calculated
227     //        int injectImpulse = 300; // -i#i
228     //
229     //        // Storage area for the buffer queues
230     //        char **rxBuffers;
231     //        char **txBuffers;
232     //        char **freeBuffers;
233     //
234     //        // Buffer indices
235     //        SLuint32 rxFront;    // oldest recording
236     //        SLuint32 rxRear;     // next to be recorded
237     //        SLuint32 txFront;    // oldest playing
238     //        SLuint32 txRear;     // next to be played
239     //        SLuint32 freeFront;  // oldest free
240     //        SLuint32 freeRear;   // next to be freed
241     //
242     //        audio_utils_fifo fifo; //(*)
243     //        SLAndroidSimpleBufferQueueItf recorderBufferQueue;
244     //        SLBufferQueueItf playerBufferQueue;
245 
246     // default values
247     pSles->rxBufCount = 1;     // -r#
248     pSles->txBufCount = 1;     // -t#
249     pSles->bufSizeInFrames = frameCount;//240;  // -f#
250     pSles->channels = 1;       // -c#
251     pSles->sampleRate = samplingRate;//48000; // -s#
252     pSles->exitAfterSeconds = 3; // -e#
253     pSles->freeBufCount = 0;   // calculated
254     pSles->bufSizeInBytes = 0; // calculated
255     pSles->injectImpulse = 300; // -i#i
256 
257     // Storage area for the buffer queues
258     //        char **rxBuffers;
259     //        char **txBuffers;
260     //        char **freeBuffers;
261 
262     // Buffer indices
263     pSles->rxFront;    // oldest recording
264     pSles->rxRear;     // next to be recorded
265     pSles->txFront;    // oldest playing
266     pSles->txRear;     // next to be played
267     pSles->freeFront;  // oldest free
268     pSles->freeRear;   // next to be freed
269 
270     pSles->fifo; //(*)
271     pSles->fifo2Buffer = NULL;
272     pSles->recorderBufferQueue;
273     pSles->playerBufferQueue;
274 
275     // compute total free buffers as -r plus -t
276     pSles->freeBufCount = pSles->rxBufCount + pSles->txBufCount;
277     // compute buffer size
278     pSles->bufSizeInBytes = pSles->channels * pSles->bufSizeInFrames * sizeof(short);
279 
280     // Initialize free buffers
281     pSles->freeBuffers = (char **) calloc(pSles->freeBufCount+1, sizeof(char *));
282     unsigned j;
283     for (j = 0; j < pSles->freeBufCount; ++j) {
284         pSles->freeBuffers[j] = (char *) malloc(pSles->bufSizeInBytes);
285     }
286     pSles->freeFront = 0;
287     pSles->freeRear = pSles->freeBufCount;
288     pSles->freeBuffers[j] = NULL;
289 
290     // Initialize record queue
291     pSles->rxBuffers = (char **) calloc(pSles->rxBufCount+1, sizeof(char *));
292     pSles->rxFront = 0;
293     pSles->rxRear = 0;
294 
295     // Initialize play queue
296     pSles->txBuffers = (char **) calloc(pSles->txBufCount+1, sizeof(char *));
297     pSles->txFront = 0;
298     pSles->txRear = 0;
299 
300     size_t frameSize = pSles->channels * sizeof(short);
301 #define FIFO_FRAMES 1024
302     pSles->fifoBuffer = new short[FIFO_FRAMES * pSles->channels];
303     audio_utils_fifo_init(&(pSles->fifo), FIFO_FRAMES, frameSize, pSles->fifoBuffer);
304 
305     //        SNDFILE *sndfile;
306     //        if (outFileName != NULL) {
307     // create .wav writer
308     //            SF_INFO info;
309     //            info.frames = 0;
310     //            info.samplerate = sampleRate;
311     //            info.channels = channels;
312     //            info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
313     //            sndfile = sf_open(outFileName, SFM_WRITE, &info);
314     //            if (sndfile != NULL) {
315 #define FIFO2_FRAMES 65536
316     pSles->fifo2Buffer = new short[FIFO2_FRAMES * pSles->channels];
317     audio_utils_fifo_init(&(pSles->fifo2), FIFO2_FRAMES, frameSize, pSles->fifo2Buffer);
318     //            } else {
319     //                fprintf(stderr, "sf_open failed\n");
320     //            }
321     //        } else {
322     //            sndfile = NULL;
323     //        }
324 
325     SLresult result;
326 
327     // create engine
328     pSles->engineObject;
329     result = slCreateEngine(&(pSles->engineObject), 0, NULL, 0, NULL, NULL);
330     ASSERT_EQ(SL_RESULT_SUCCESS, result);
331     result = (*(pSles->engineObject))->Realize(pSles->engineObject, SL_BOOLEAN_FALSE);
332     ASSERT_EQ(SL_RESULT_SUCCESS, result);
333     SLEngineItf engineEngine;
334     result = (*(pSles->engineObject))->GetInterface(pSles->engineObject, SL_IID_ENGINE,
335             &engineEngine);
336     ASSERT_EQ(SL_RESULT_SUCCESS, result);
337 
338     // create output mix
339     pSles->outputmixObject;
340     result = (*engineEngine)->CreateOutputMix(engineEngine, &(pSles->outputmixObject), 0, NULL,
341             NULL);
342     ASSERT_EQ(SL_RESULT_SUCCESS, result);
343     result = (*(pSles->outputmixObject))->Realize(pSles->outputmixObject, SL_BOOLEAN_FALSE);
344     ASSERT_EQ(SL_RESULT_SUCCESS, result);
345 
346     // create an audio player with buffer queue source and output mix sink
347     SLDataSource audiosrc;
348     SLDataSink audiosnk;
349     SLDataFormat_PCM pcm;
350     SLDataLocator_OutputMix locator_outputmix;
351     SLDataLocator_BufferQueue locator_bufferqueue_tx;
352     locator_bufferqueue_tx.locatorType = SL_DATALOCATOR_BUFFERQUEUE;
353     locator_bufferqueue_tx.numBuffers = pSles->txBufCount;
354     locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
355     locator_outputmix.outputMix = pSles->outputmixObject;
356     pcm.formatType = SL_DATAFORMAT_PCM;
357     pcm.numChannels = pSles->channels;
358     pcm.samplesPerSec = pSles->sampleRate * 1000;
359     pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;
360     pcm.containerSize = 16;
361     pcm.channelMask = pSles->channels == 1 ? SL_SPEAKER_FRONT_CENTER :
362             (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT);
363     pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
364     audiosrc.pLocator = &locator_bufferqueue_tx;
365     audiosrc.pFormat = &pcm;
366     audiosnk.pLocator = &locator_outputmix;
367     audiosnk.pFormat = NULL;
368     pSles->playerObject = NULL;
369     pSles->recorderObject = NULL;
370     SLInterfaceID ids_tx[1] = {SL_IID_BUFFERQUEUE};
371     SLboolean flags_tx[1] = {SL_BOOLEAN_TRUE};
372     result = (*engineEngine)->CreateAudioPlayer(engineEngine, &(pSles->playerObject),
373             &audiosrc, &audiosnk, 1, ids_tx, flags_tx);
374     if (SL_RESULT_CONTENT_UNSUPPORTED == result) {
375         fprintf(stderr, "Could not create audio player (result %x), check sample rate\n",
376                 result);
377         SLES_PRINTF("ERROR: Could not create audio player (result %x), check sample rate\n",
378                 result);
379         goto cleanup;
380     }
381     ASSERT_EQ(SL_RESULT_SUCCESS, result);
382     result = (*(pSles->playerObject))->Realize(pSles->playerObject, SL_BOOLEAN_FALSE);
383     ASSERT_EQ(SL_RESULT_SUCCESS, result);
384     SLPlayItf playerPlay;
385     result = (*(pSles->playerObject))->GetInterface(pSles->playerObject, SL_IID_PLAY,
386             &playerPlay);
387     ASSERT_EQ(SL_RESULT_SUCCESS, result);
388     result = (*(pSles->playerObject))->GetInterface(pSles->playerObject, SL_IID_BUFFERQUEUE,
389             &(pSles->playerBufferQueue));
390     ASSERT_EQ(SL_RESULT_SUCCESS, result);
391     result = (*(pSles->playerBufferQueue))->RegisterCallback(pSles->playerBufferQueue,
392             playerCallback, pSles);
393     ASSERT_EQ(SL_RESULT_SUCCESS, result);
394 
395     // Enqueue some zero buffers for the player
396     for (j = 0; j < pSles->txBufCount; ++j) {
397 
398         // allocate a free buffer
399         assert(pSles->freeFront != pSles->freeRear);
400         char *buffer = pSles->freeBuffers[pSles->freeFront];
401         if (++pSles->freeFront > pSles->freeBufCount) {
402             pSles->freeFront = 0;
403         }
404 
405         // put on play queue
406         SLuint32 txRearNext = pSles->txRear + 1;
407         if (txRearNext > pSles->txBufCount) {
408             txRearNext = 0;
409         }
410         assert(txRearNext != pSles->txFront);
411         pSles->txBuffers[pSles->txRear] = buffer;
412         pSles->txRear = txRearNext;
413         result = (*(pSles->playerBufferQueue))->Enqueue(pSles->playerBufferQueue,
414                 buffer, pSles->bufSizeInBytes);
415         ASSERT_EQ(SL_RESULT_SUCCESS, result);
416     }
417 
418     result = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PLAYING);
419     ASSERT_EQ(SL_RESULT_SUCCESS, result);
420 
421     // Create an audio recorder with microphone device source and buffer queue sink.
422     // The buffer queue as sink is an Android-specific extension.
423 
424     SLDataLocator_IODevice locator_iodevice;
425     SLDataLocator_AndroidSimpleBufferQueue locator_bufferqueue_rx;
426     locator_iodevice.locatorType = SL_DATALOCATOR_IODEVICE;
427     locator_iodevice.deviceType = SL_IODEVICE_AUDIOINPUT;
428     locator_iodevice.deviceID = SL_DEFAULTDEVICEID_AUDIOINPUT;
429     locator_iodevice.device = NULL;
430     audiosrc.pLocator = &locator_iodevice;
431     audiosrc.pFormat = NULL;
432     locator_bufferqueue_rx.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
433     locator_bufferqueue_rx.numBuffers = pSles->rxBufCount;
434     audiosnk.pLocator = &locator_bufferqueue_rx;
435     audiosnk.pFormat = &pcm;
436     {
437         SLInterfaceID ids_rx[2] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
438                 SL_IID_ANDROIDCONFIGURATION};
439         SLboolean flags_rx[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
440         result = (*engineEngine)->CreateAudioRecorder(engineEngine, &(pSles->recorderObject),
441                 &audiosrc, &audiosnk, 2, ids_rx, flags_rx);
442         if (SL_RESULT_SUCCESS != result) {
443             fprintf(stderr, "Could not create audio recorder (result %x), "
444                     "check sample rate and channel count\n", result);
445             status = SLES_FAIL;
446 
447             SLES_PRINTF("ERROR: Could not create audio recorder (result %x), "
448                     "check sample rate and channel count\n", result);
449             goto cleanup;
450         }
451     }
452     ASSERT_EQ(SL_RESULT_SUCCESS, result);
453 
454     {
455         /* Get the Android configuration interface which is explicit */
456         SLAndroidConfigurationItf configItf;
457         result = (*(pSles->recorderObject))->GetInterface(pSles->recorderObject,
458                 SL_IID_ANDROIDCONFIGURATION, (void*)&configItf);
459         ASSERT_EQ(SL_RESULT_SUCCESS, result);
460         SLuint32 presetValue = micSource;
461         /* Use the configuration interface to configure the recorder before it's realized */
462         if (presetValue != SL_ANDROID_RECORDING_PRESET_NONE) {
463             result = (*configItf)->SetConfiguration(configItf, SL_ANDROID_KEY_RECORDING_PRESET,
464                     &presetValue, sizeof(SLuint32));
465             ASSERT_EQ(SL_RESULT_SUCCESS, result);
466         }
467 
468     }
469 
470     result = (*(pSles->recorderObject))->Realize(pSles->recorderObject, SL_BOOLEAN_FALSE);
471     ASSERT_EQ(SL_RESULT_SUCCESS, result);
472     SLRecordItf recorderRecord;
473     result = (*(pSles->recorderObject))->GetInterface(pSles->recorderObject, SL_IID_RECORD,
474             &recorderRecord);
475     ASSERT_EQ(SL_RESULT_SUCCESS, result);
476     result = (*(pSles->recorderObject))->GetInterface(pSles->recorderObject,
477             SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &(pSles->recorderBufferQueue));
478     ASSERT_EQ(SL_RESULT_SUCCESS, result);
479     result = (*(pSles->recorderBufferQueue))->RegisterCallback(pSles->recorderBufferQueue,
480             recorderCallback, pSles);
481     ASSERT_EQ(SL_RESULT_SUCCESS, result);
482 
483     // Enqueue some empty buffers for the recorder
484     for (j = 0; j < pSles->rxBufCount; ++j) {
485 
486         // allocate a free buffer
487         assert(pSles->freeFront != pSles->freeRear);
488         char *buffer = pSles->freeBuffers[pSles->freeFront];
489         if (++pSles->freeFront > pSles->freeBufCount) {
490             pSles->freeFront = 0;
491         }
492 
493         // put on record queue
494         SLuint32 rxRearNext = pSles->rxRear + 1;
495         if (rxRearNext > pSles->rxBufCount) {
496             rxRearNext = 0;
497         }
498         assert(rxRearNext != pSles->rxFront);
499         pSles->rxBuffers[pSles->rxRear] = buffer;
500         pSles->rxRear = rxRearNext;
501         result = (*(pSles->recorderBufferQueue))->Enqueue(pSles->recorderBufferQueue,
502                 buffer, pSles->bufSizeInBytes);
503         ASSERT_EQ(SL_RESULT_SUCCESS, result);
504     }
505 
506     // Kick off the recorder
507     result = (*recorderRecord)->SetRecordState(recorderRecord, SL_RECORDSTATE_RECORDING);
508     ASSERT_EQ(SL_RESULT_SUCCESS, result);
509 
510     // Tear down the objects and exit
511     status = SLES_SUCCESS;
512     cleanup:
513     SLES_PRINTF("Finished initialization with status: %d", status);
514 
515     return status;
516 }
517 
slesProcessNext(sles_data * pSles,double * pSamples,long maxSamples)518 int slesProcessNext(sles_data *pSles, double *pSamples, long maxSamples) {
519     //int status = SLES_FAIL;
520 
521     SLES_PRINTF("slesProcessNext: pSles = %p, currentSample: %p,  maxSamples = %ld", pSles,
522             pSamples, maxSamples);
523 
524     int samplesRead = 0;
525 
526     int currentSample = 0;
527     double *pCurrentSample = pSamples;
528     int maxValue = 32768;
529 
530     if (pSles == NULL) {
531         return samplesRead;
532     }
533 
534     SLresult result;
535     for (int i = 0; i < 10; i++) {
536         usleep(100000);
537         if (pSles->fifo2Buffer != NULL) {
538             for (;;) {
539                 short buffer[pSles->bufSizeInFrames * pSles->channels];
540                 ssize_t actual = audio_utils_fifo_read(&(pSles->fifo2), buffer,
541                         pSles->bufSizeInFrames);
542                 if (actual <= 0)
543                     break;
544                 {
545                     for (int jj =0; jj<actual && currentSample < maxSamples; jj++) {
546                         *(pCurrentSample++) = ((double)buffer[jj])/maxValue;
547                         currentSample++;
548                     }
549                 }
550                 samplesRead +=actual;
551             }
552         }
553         if (pSles->injectImpulse > 0) {
554             if (pSles->injectImpulse <= 100) {
555                 pSles->injectImpulse = -1;
556                 write(1, "I", 1);
557             } else {
558                 if ((pSles->injectImpulse % 1000) < 100) {
559                     write(1, "i", 1);
560                 }
561                 pSles->injectImpulse -= 100;
562             }
563         } else if (i == 9) {
564             write(1, ".", 1);
565         }
566     }
567     SLBufferQueueState playerBQState;
568     result = (*(pSles->playerBufferQueue))->GetState(pSles->playerBufferQueue,
569             &playerBQState);
570     ASSERT_EQ(SL_RESULT_SUCCESS, result);
571     SLAndroidSimpleBufferQueueState recorderBQState;
572     result = (*(pSles->recorderBufferQueue))->GetState(pSles->recorderBufferQueue,
573             &recorderBQState);
574     ASSERT_EQ(SL_RESULT_SUCCESS, result);
575 
576     SLES_PRINTF("End of slesProcessNext: pSles = %p, samplesRead = %d, maxSamples= %ld", pSles,
577             samplesRead, maxSamples);
578 
579     return samplesRead;
580 }
581 
slesDestroyServer(sles_data * pSles)582 int slesDestroyServer(sles_data *pSles) {
583     int status = SLES_FAIL;
584 
585     SLES_PRINTF("Start slesDestroyServer: pSles = %p", pSles);
586     if (pSles == NULL) {
587         return status;
588     }
589 
590     if (NULL != pSles->playerObject) {
591 
592         SLES_PRINTF("stopping player...");
593         SLPlayItf playerPlay;
594         SLresult result = (*(pSles->playerObject))->GetInterface(pSles->playerObject,
595                 SL_IID_PLAY, &playerPlay);
596 
597         ASSERT_EQ(SL_RESULT_SUCCESS, result);
598 
599         //stop player and recorder if they exist
600         result = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_STOPPED);
601         ASSERT_EQ(SL_RESULT_SUCCESS, result);
602     }
603 
604     if (NULL != pSles->recorderObject) {
605         SLES_PRINTF("stopping recorder...");
606         SLRecordItf recorderRecord;
607         SLresult result = (*(pSles->recorderObject))->GetInterface(pSles->recorderObject,
608                 SL_IID_RECORD, &recorderRecord);
609         ASSERT_EQ(SL_RESULT_SUCCESS, result);
610 
611         result = (*recorderRecord)->SetRecordState(recorderRecord, SL_RECORDSTATE_STOPPED);
612         ASSERT_EQ(SL_RESULT_SUCCESS, result);
613     }
614 
615     usleep(1000);
616 
617     audio_utils_fifo_deinit(&(pSles->fifo));
618     delete[] pSles->fifoBuffer;
619 
620     SLES_PRINTF("slesDestroyServer 2");
621 
622     //        if (sndfile != NULL) {
623     audio_utils_fifo_deinit(&(pSles->fifo2));
624     delete[] pSles->fifo2Buffer;
625 
626     SLES_PRINTF("slesDestroyServer 3");
627 
628     //            sf_close(sndfile);
629     //        }
630     if (NULL != pSles->playerObject) {
631         (*(pSles->playerObject))->Destroy(pSles->playerObject);
632     }
633 
634     SLES_PRINTF("slesDestroyServer 4");
635 
636     if (NULL != pSles->recorderObject) {
637         (*(pSles->recorderObject))->Destroy(pSles->recorderObject);
638     }
639 
640     SLES_PRINTF("slesDestroyServer 5");
641 
642     (*(pSles->outputmixObject))->Destroy(pSles->outputmixObject);
643     SLES_PRINTF("slesDestroyServer 6");
644     (*(pSles->engineObject))->Destroy(pSles->engineObject);
645     SLES_PRINTF("slesDestroyServer 7");
646 
647     //        free(pSles);
648     //        pSles=NULL;
649 
650     status = SLES_SUCCESS;
651 
652     SLES_PRINTF("End slesDestroyServer: status = %d", status);
653     return status;
654 }
655 
656