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