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