1/* 2 * Copyright (C) 2010 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/* Audio Record Test 18 19First run the program from shell: 20 % adb shell slesTest_recBuffQueue /sdcard/myrec.wav 21 22These use adb on host to retrive the file: 23 % adb pull /sdcard/myrec.wav 24 25*/ 26 27 28#include <stdlib.h> 29#include <stdio.h> 30#include <string.h> 31#include <unistd.h> 32#include <sys/time.h> 33#include <fcntl.h> 34#include <system/audio.h> 35#include <audio_utils/primitives.h> 36#include <audio_utils/sndfile.h> 37 38#include <SLES/OpenSLES.h> 39#include <SLES/OpenSLES_Android.h> 40 41audio_format_t transferFormat = AUDIO_FORMAT_DEFAULT; 42uint32_t sampleRate = 48000; 43int channelCount = 1; 44bool useIndexChannelMask = false; 45size_t frameSize; 46uint32_t performanceMode = SL_ANDROID_PERFORMANCE_LATENCY; 47bool aec = false; 48bool agc = false; 49bool ns = false; 50 51/* Preset number to use for recording */ 52SLuint32 presetValue = SL_ANDROID_RECORDING_PRESET_NONE; 53 54/* Explicitly requesting SL_IID_ANDROIDSIMPLEBUFFERQUEUE and SL_IID_ANDROIDCONFIGURATION 55 * on the AudioRecorder object */ 56#define NUM_EXPLICIT_INTERFACES_FOR_RECORDER 2 57 58/* Size of the recording buffer queue */ 59#define NB_BUFFERS_IN_QUEUE 1 60/* Size of each buffer in the queue */ 61#define BUFFER_SIZE_IN_BYTES 2048 62 63/* Local storage for Audio data */ 64int8_t pcmData[NB_BUFFERS_IN_QUEUE * BUFFER_SIZE_IN_BYTES]; 65 66/* destination for recorded data */ 67SNDFILE *sndfile; 68 69//----------------------------------------------------------------- 70/* Exits the application if an error is encountered */ 71#define ExitOnError(x) ExitOnErrorFunc(x,__LINE__) 72 73void ExitOnErrorFunc( SLresult result , int line) 74{ 75 if (SL_RESULT_SUCCESS != result) { 76 fprintf(stderr, "%u error code encountered at line %d, exiting\n", result, line); 77 exit(EXIT_FAILURE); 78 } 79} 80 81//----------------------------------------------------------------- 82/* Structure for passing information to callback function */ 83typedef struct CallbackCntxt_ { 84 SLPlayItf playItf; 85 SLuint32 size; 86 SLint8* pDataBase; // Base address of local audio data storage 87 SLint8* pData; // Current address of local audio data storage 88} CallbackCntxt; 89 90 91//----------------------------------------------------------------- 92/* Callback for recording buffer queue events */ 93void RecCallback( 94 SLRecordItf caller, 95 void *pContext __unused, 96 SLuint32 event) 97{ 98 if (SL_RECORDEVENT_HEADATNEWPOS & event) { 99 SLmillisecond pMsec = 0; 100 (*caller)->GetPosition(caller, &pMsec); 101 printf("SL_RECORDEVENT_HEADATNEWPOS current position=%ums\n", pMsec); 102 } 103 104 if (SL_RECORDEVENT_HEADATMARKER & event) { 105 SLmillisecond pMsec = 0; 106 (*caller)->GetPosition(caller, &pMsec); 107 printf("SL_RECORDEVENT_HEADATMARKER current position=%ums\n", pMsec); 108 } 109} 110 111//----------------------------------------------------------------- 112/* Callback for recording buffer queue events */ 113void RecBufferQueueCallback( 114 SLAndroidSimpleBufferQueueItf queueItf, 115 void *pContext) 116{ 117 //printf("RecBufferQueueCallback called\n"); 118 119 CallbackCntxt *pCntxt = (CallbackCntxt*)pContext; 120 121 /* Save the recorded data */ 122 sf_count_t frameCount = BUFFER_SIZE_IN_BYTES / frameSize; 123 switch (transferFormat) { 124 case AUDIO_FORMAT_PCM_8_BIT: { 125 short temp[BUFFER_SIZE_IN_BYTES]; 126 memcpy_to_i16_from_u8(temp, (const unsigned char *) pCntxt->pDataBase, 127 BUFFER_SIZE_IN_BYTES); 128 (void) sf_writef_short(sndfile, (const short *) temp, frameCount); 129 } break; 130 case AUDIO_FORMAT_PCM_16_BIT: 131 (void) sf_writef_short(sndfile, (const short *) pCntxt->pDataBase, frameCount); 132 break; 133 case AUDIO_FORMAT_PCM_32_BIT: 134 (void) sf_writef_int(sndfile, (const int *) pCntxt->pDataBase, frameCount); 135 break; 136 case AUDIO_FORMAT_PCM_FLOAT: 137 (void) sf_writef_float(sndfile, (const float *) pCntxt->pDataBase, frameCount); 138 break; 139 default: 140 fprintf(stderr, "Unsupported transfer format %d\n", transferFormat); 141 exit(EXIT_FAILURE); 142 } 143 144 /* Increase data pointer by buffer size */ 145 pCntxt->pData += BUFFER_SIZE_IN_BYTES; 146 147 if (pCntxt->pData >= pCntxt->pDataBase + (NB_BUFFERS_IN_QUEUE * BUFFER_SIZE_IN_BYTES)) { 148 pCntxt->pData = pCntxt->pDataBase; 149 } 150 151 ExitOnError( (*queueItf)->Enqueue(queueItf, pCntxt->pDataBase, BUFFER_SIZE_IN_BYTES) ); 152 153 SLAndroidSimpleBufferQueueState recQueueState; 154 ExitOnError( (*queueItf)->GetState(queueItf, &recQueueState) ); 155 156 /*fprintf(stderr, "\tRecBufferQueueCallback now has pCntxt->pData=%p queue: " 157 "count=%u playIndex=%u\n", 158 pCntxt->pData, recQueueState.count, recQueueState.index);*/ 159 //printf("RecBufferQueueCallback returned\n"); 160} 161 162//----------------------------------------------------------------- 163 164/* Record to an audio path by opening a file descriptor on that path */ 165void TestRecToBuffQueue( SLObjectItf sl, const char* path, SLAint64 durationInSeconds) 166{ 167 SF_INFO info; 168 info.frames = 0; 169 info.samplerate = sampleRate; 170 info.channels = channelCount; 171 switch (transferFormat) { 172 case AUDIO_FORMAT_PCM_8_BIT: 173 info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_U8; 174 break; 175 case AUDIO_FORMAT_PCM_16_BIT: 176 info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16; 177 break; 178 case AUDIO_FORMAT_PCM_32_BIT: 179 info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_32; 180 break; 181 case AUDIO_FORMAT_PCM_FLOAT: 182 info.format = SF_FORMAT_WAV | SF_FORMAT_FLOAT; 183 break; 184 default: 185 fprintf(stderr, "Unsupported transfer format %d\n", transferFormat); 186 exit(EXIT_FAILURE); 187 } 188 sndfile = sf_open(path, SFM_WRITE, &info); 189 if (sndfile == NULL) { 190 ExitOnError(SL_RESULT_RESOURCE_ERROR); 191 } 192 193 SLresult result; 194 SLEngineItf EngineItf; 195 196 /* Objects this application uses: one audio recorder */ 197 SLObjectItf recorder; 198 199 /* Interfaces for the audio recorder */ 200 SLAndroidSimpleBufferQueueItf recBuffQueueItf; 201 SLRecordItf recordItf; 202 SLAndroidConfigurationItf configItf; 203 204 /* Source of audio data for the recording */ 205 SLDataSource recSource; 206 SLDataLocator_IODevice ioDevice; 207 208 /* Data sink for recorded audio */ 209 SLDataSink recDest; 210 SLDataLocator_AndroidSimpleBufferQueue recBuffQueue; 211 /* As mentioned in the Android extension API documentation this is identical to 212 * OpenSL ES 1.1 SLDataFormat_PCM_EX, and can be used for an instance of SLDataFormat_PCM. 213 */ 214 SLAndroidDataFormat_PCM_EX pcm; 215 216 int numInterfaces = NUM_EXPLICIT_INTERFACES_FOR_RECORDER; 217 if (aec) numInterfaces++; 218 if (agc) numInterfaces++; 219 if (ns) numInterfaces++; 220 221 SLboolean required[numInterfaces]; 222 SLInterfaceID iidArray[numInterfaces]; 223 224 /* Get the SL Engine Interface which is implicit */ 225 result = (*sl)->GetInterface(sl, SL_IID_ENGINE, (void*)&EngineItf); 226 ExitOnError(result); 227 228 /* Initialize arrays required[] and iidArray[] */ 229 for (int i=0 ; i < numInterfaces ; i++) { 230 required[i] = SL_BOOLEAN_FALSE; 231 iidArray[i] = SL_IID_NULL; 232 } 233 234 235 /* ------------------------------------------------------ */ 236 /* Configuration of the recorder */ 237 238 /* Request the AndroidSimpleBufferQueue and AndroidConfiguration interfaces */ 239 int index = 0; 240 required[index] = SL_BOOLEAN_TRUE; 241 iidArray[index++] = SL_IID_ANDROIDSIMPLEBUFFERQUEUE; 242 required[index] = SL_BOOLEAN_TRUE; 243 iidArray[index++] = SL_IID_ANDROIDCONFIGURATION; 244 if (aec) { 245 iidArray[index++] = SL_IID_ANDROIDACOUSTICECHOCANCELLATION; 246 } 247 if (agc) { 248 iidArray[index++] = SL_IID_ANDROIDAUTOMATICGAINCONTROL; 249 } 250 if (ns) { 251 iidArray[index++] = SL_IID_ANDROIDNOISESUPPRESSION; 252 } 253 254 /* Setup the data source */ 255 ioDevice.locatorType = SL_DATALOCATOR_IODEVICE; 256 ioDevice.deviceType = SL_IODEVICE_AUDIOINPUT; 257 ioDevice.deviceID = SL_DEFAULTDEVICEID_AUDIOINPUT; 258 ioDevice.device = NULL; 259 recSource.pLocator = (void *) &ioDevice; 260 recSource.pFormat = NULL; 261 262 /* Setup the data sink */ 263 recBuffQueue.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE; 264 recBuffQueue.numBuffers = NB_BUFFERS_IN_QUEUE; 265 /* set up the format of the data in the buffer queue */ 266 pcm.formatType = transferFormat == AUDIO_FORMAT_PCM_FLOAT || 267 transferFormat == AUDIO_FORMAT_PCM_8_BIT ? 268 SL_ANDROID_DATAFORMAT_PCM_EX : SL_DATAFORMAT_PCM; 269 pcm.numChannels = channelCount; 270 pcm.sampleRate = sampleRate * 1000; // milliHz 271 pcm.representation = SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT; 272 switch (transferFormat) { 273 case AUDIO_FORMAT_PCM_16_BIT: 274 pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16; 275 pcm.containerSize = 16; 276 break; 277 case AUDIO_FORMAT_PCM_32_BIT: 278 pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_32; 279 pcm.containerSize = 32; 280 break; 281 case AUDIO_FORMAT_PCM_8_BIT: 282 pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_8; 283 pcm.containerSize = 8; 284 pcm.representation = SL_ANDROID_PCM_REPRESENTATION_UNSIGNED_INT; 285 break; 286 case AUDIO_FORMAT_PCM_FLOAT: 287 pcm.bitsPerSample = 32; 288 pcm.containerSize = 32; 289 pcm.representation = SL_ANDROID_PCM_REPRESENTATION_FLOAT; 290 break; 291 default: 292 fprintf(stderr, "Unsupported transfer format %d\n", transferFormat); 293 exit(EXIT_FAILURE); 294 } 295 if (useIndexChannelMask) { 296 pcm.channelMask = (1 << channelCount) - 1; 297 } else { 298 switch (channelCount) { 299 case 1: 300 pcm.channelMask = SL_SPEAKER_FRONT_LEFT; 301 break; 302 case 2: 303 pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; 304 break; 305 default: 306 fprintf(stderr, "Unsupported channel count %d\n", channelCount); 307 exit(EXIT_FAILURE); 308 } 309 } 310 pcm.endianness = SL_BYTEORDER_LITTLEENDIAN; 311 312 recDest.pLocator = (void *) &recBuffQueue; 313 recDest.pFormat = (void * ) &pcm; 314 315 /* Create the audio recorder */ 316 result = (*EngineItf)->CreateAudioRecorder(EngineItf, &recorder, &recSource, &recDest, 317 numInterfaces, iidArray, required); 318 ExitOnError(result); 319 printf("Recorder created\n"); 320 321 /* Get the Android configuration interface which is explicit */ 322 result = (*recorder)->GetInterface(recorder, SL_IID_ANDROIDCONFIGURATION, (void*)&configItf); 323 ExitOnError(result); 324 325 /* Use the configuration interface to configure the recorder before it's realized */ 326 if (presetValue != SL_ANDROID_RECORDING_PRESET_NONE) { 327 result = (*configItf)->SetConfiguration(configItf, SL_ANDROID_KEY_RECORDING_PRESET, 328 &presetValue, sizeof(SLuint32)); 329 ExitOnError(result); 330 printf("Recorder configured with preset %u\n", presetValue); 331 } else { 332 printf("Using default record preset\n"); 333 } 334 335 if (performanceMode != SL_ANDROID_PERFORMANCE_LATENCY) { 336 result = (*configItf)->SetConfiguration(configItf, SL_ANDROID_KEY_PERFORMANCE_MODE, 337 &performanceMode, sizeof(SLuint32)); 338 ExitOnError(result); 339 printf("Recorder configured with performance mode %u\n", performanceMode); 340 } else { 341 printf("Using default performance mode\n"); 342 } 343 344 SLuint32 presetRetrieved = SL_ANDROID_RECORDING_PRESET_NONE; 345 SLuint32 presetSize = 2*sizeof(SLuint32); // intentionally too big 346 result = (*configItf)->GetConfiguration(configItf, SL_ANDROID_KEY_RECORDING_PRESET, 347 &presetSize, (void*)&presetRetrieved); 348 ExitOnError(result); 349 if (presetValue == SL_ANDROID_RECORDING_PRESET_NONE) { 350 printf("The default record preset appears to be %u\n", presetRetrieved); 351 } else if (presetValue != presetRetrieved) { 352 fprintf(stderr, "Error retrieving recording preset as %u instead of %u\n", presetRetrieved, 353 presetValue); 354 ExitOnError(SL_RESULT_INTERNAL_ERROR); 355 } 356 357 /* Realize the recorder in synchronous mode. */ 358 result = (*recorder)->Realize(recorder, SL_BOOLEAN_FALSE); 359 ExitOnError(result); 360 printf("Recorder realized\n"); 361 362 /* Check actual performance mode granted*/ 363 SLuint32 modeRetrieved = SL_ANDROID_PERFORMANCE_NONE; 364 SLuint32 modeSize = sizeof(SLuint32); 365 result = (*configItf)->GetConfiguration(configItf, SL_ANDROID_KEY_PERFORMANCE_MODE, 366 &modeSize, (void*)&modeRetrieved); 367 ExitOnError(result); 368 printf("Actual performance mode is %u\n", modeRetrieved); 369 370 /* Get the record interface which is implicit */ 371 result = (*recorder)->GetInterface(recorder, SL_IID_RECORD, (void*)&recordItf); 372 ExitOnError(result); 373 374 /* Set up the recorder callback to get events during the recording */ 375 result = (*recordItf)->SetMarkerPosition(recordItf, 2000); 376 ExitOnError(result); 377 result = (*recordItf)->SetPositionUpdatePeriod(recordItf, 500); 378 ExitOnError(result); 379 result = (*recordItf)->SetCallbackEventsMask(recordItf, 380 SL_RECORDEVENT_HEADATMARKER | SL_RECORDEVENT_HEADATNEWPOS); 381 ExitOnError(result); 382 result = (*recordItf)->RegisterCallback(recordItf, RecCallback, NULL); 383 ExitOnError(result); 384 printf("Recorder callback registered\n"); 385 386 /* Enable AEC if requested */ 387 if (aec) { 388 SLAndroidAcousticEchoCancellationItf aecItf; 389 result = (*recorder)->GetInterface( 390 recorder, SL_IID_ANDROIDACOUSTICECHOCANCELLATION, (void*)&aecItf); 391 printf("AEC is %savailable\n", SL_RESULT_SUCCESS == result ? "" : "not "); 392 if (SL_RESULT_SUCCESS == result) { 393 result = (*aecItf)->SetEnabled(aecItf, true); 394 ExitOnError(result); 395 SLboolean enabled; 396 result = (*aecItf)->IsEnabled(aecItf, &enabled); 397 ExitOnError(result); 398 printf("AEC is %s\n", enabled ? "enabled" : "not enabled"); 399 } 400 } 401 402 /* Enable AGC if requested */ 403 if (agc) { 404 SLAndroidAutomaticGainControlItf agcItf; 405 result = (*recorder)->GetInterface( 406 recorder, SL_IID_ANDROIDAUTOMATICGAINCONTROL, (void*)&agcItf); 407 printf("AGC is %savailable\n", SL_RESULT_SUCCESS == result ? "" : "not "); 408 if (SL_RESULT_SUCCESS == result) { 409 result = (*agcItf)->SetEnabled(agcItf, true); 410 ExitOnError(result); 411 SLboolean enabled; 412 result = (*agcItf)->IsEnabled(agcItf, &enabled); 413 ExitOnError(result); 414 printf("AGC is %s\n", enabled ? "enabled" : "not enabled"); 415 } 416 } 417 418 /* Enable NS if requested */ 419 if (ns) { 420 SLAndroidNoiseSuppressionItf nsItf; 421 result = (*recorder)->GetInterface( 422 recorder, SL_IID_ANDROIDNOISESUPPRESSION, (void*)&nsItf); 423 printf("NS is %savailable\n", SL_RESULT_SUCCESS == result ? "" : "not "); 424 if (SL_RESULT_SUCCESS == result) { 425 result = (*nsItf)->SetEnabled(nsItf, true); 426 ExitOnError(result); 427 SLboolean enabled; 428 result = (*nsItf)->IsEnabled(nsItf, &enabled); 429 ExitOnError(result); 430 printf("NS is %s\n", enabled ? "enabled" : "not enabled"); 431 } 432 } 433 434 /* Get the buffer queue interface which was explicitly requested */ 435 result = (*recorder)->GetInterface(recorder, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, 436 (void*)&recBuffQueueItf); 437 ExitOnError(result); 438 439 /* ------------------------------------------------------ */ 440 /* Initialize the callback and its context for the recording buffer queue */ 441 CallbackCntxt cntxt; 442 cntxt.pDataBase = (int8_t*)&pcmData; 443 cntxt.pData = cntxt.pDataBase; 444 cntxt.size = sizeof(pcmData); 445 result = (*recBuffQueueItf)->RegisterCallback(recBuffQueueItf, RecBufferQueueCallback, &cntxt); 446 ExitOnError(result); 447 448 /* Enqueue buffers to map the region of memory allocated to store the recorded data */ 449 printf("Enqueueing buffer "); 450 for(int i = 0 ; i < NB_BUFFERS_IN_QUEUE ; i++) { 451 printf("%d ", i); 452 result = (*recBuffQueueItf)->Enqueue(recBuffQueueItf, cntxt.pData, BUFFER_SIZE_IN_BYTES); 453 ExitOnError(result); 454 cntxt.pData += BUFFER_SIZE_IN_BYTES; 455 } 456 printf("\n"); 457 cntxt.pData = cntxt.pDataBase; 458 459 /* ------------------------------------------------------ */ 460 /* Start recording */ 461 result = (*recordItf)->SetRecordState(recordItf, SL_RECORDSTATE_RECORDING); 462 ExitOnError(result); 463 printf("Starting to record\n"); 464 465 /* Record for at least a second */ 466 if (durationInSeconds < 1) { 467 durationInSeconds = 1; 468 } 469 usleep(durationInSeconds * 1000 * 1000); 470 471 /* ------------------------------------------------------ */ 472 /* End of recording */ 473 474 /* Stop recording */ 475 result = (*recordItf)->SetRecordState(recordItf, SL_RECORDSTATE_STOPPED); 476 ExitOnError(result); 477 printf("Stopped recording\n"); 478 479 /* Destroy the AudioRecorder object */ 480 (*recorder)->Destroy(recorder); 481 482 sf_close(sndfile); 483} 484 485//----------------------------------------------------------------- 486int main(int argc, char* const argv[]) 487{ 488 int durationInSeconds = 10; 489 SLresult result; 490 SLObjectItf sl; 491 492 const char *prog = argv[0]; 493 printf("OpenSL ES test %s: exercises SLRecordItf and SLAndroidSimpleBufferQueueItf ", 494 prog); 495 printf("on an AudioRecorder object\n"); 496 497 int i; 498 for (i = 1; i < argc; ++i) { 499 const char *arg = argv[i]; 500 if (arg[0] != '-') { 501 break; 502 } 503 switch (arg[1]) { 504 case 'c': // channel count 505 channelCount = atoi(&arg[2]); 506 break; 507 case 'd': // duration in seconds 508 durationInSeconds = atoi(&arg[2]); 509 break; 510 case 'f': 511 transferFormat = AUDIO_FORMAT_PCM_FLOAT; 512 break; 513 case 'i': 514 useIndexChannelMask = true; 515 break; 516 case 'p': // preset number 517 presetValue = atoi(&arg[2]); 518 break; 519 case 'r': 520 sampleRate = atoi(&arg[2]); 521 break; 522 case '1': 523 transferFormat = AUDIO_FORMAT_PCM_8_BIT; 524 break; 525 case '2': 526 transferFormat = AUDIO_FORMAT_PCM_16_BIT; 527 break; 528 case '4': 529 transferFormat = AUDIO_FORMAT_PCM_32_BIT; 530 break; 531 case 'm': 532 performanceMode = atoi(&arg[2]); 533 break; 534 case 'x': 535 if (strstr(arg, "e") != NULL) { 536 aec = true; 537 } 538 if (strstr(arg, "a") != NULL) { 539 agc = true; 540 } 541 if (strstr(arg, "n") != NULL) { 542 ns = true; 543 } 544 break; 545 default: 546 fprintf(stderr, "%s: unknown option %s\n", prog, arg); 547 break; 548 } 549 } 550 551 if (transferFormat == AUDIO_FORMAT_DEFAULT) { 552 transferFormat = AUDIO_FORMAT_PCM_16_BIT; 553 } 554 frameSize = audio_bytes_per_sample(transferFormat) * channelCount; 555 556 if (argc-i != 1) { 557 printf("Usage: \t%s [-c#] [-d#] [-i] [-p#] [-r#] [-1/2/4/f] destination_file\n", prog); 558 printf(" -c# channel count, defaults to 1\n"); 559 printf(" -d# duration in seconds, default to 10\n"); 560 printf(" -i index channel mask, not yet implemented\n"); 561 printf(" -p# is the preset value which defaults to SL_ANDROID_RECORDING_PRESET_NONE\n"); 562 printf(" possible values are:\n"); 563 printf(" -p%d SL_ANDROID_RECORDING_PRESET_NONE\n", 564 SL_ANDROID_RECORDING_PRESET_NONE); 565 printf(" -p%d SL_ANDROID_RECORDING_PRESET_GENERIC\n", 566 SL_ANDROID_RECORDING_PRESET_GENERIC); 567 printf(" -p%d SL_ANDROID_RECORDING_PRESET_CAMCORDER\n", 568 SL_ANDROID_RECORDING_PRESET_CAMCORDER); 569 printf(" -p%d SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION\n", 570 SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION); 571 printf(" -p%d SL_ANDROID_RECORDING_PRESET_VOICE_COMMUNICATION\n", 572 SL_ANDROID_RECORDING_PRESET_VOICE_COMMUNICATION); 573 printf(" -r# sample rate in Hz, defaults to 48000\n"); 574 printf(" -[1/2/4/f] sample format: 8-bit unsigned, 16-bit signed, 32-bit signed, float, " 575 "defaults to 16-bit signed\n"); 576 printf(" -m# is the performance mode value which defaults to" 577 " SL_ANDROID_PERFORMANCE_LATENCY\n"); 578 printf(" possible values are:\n"); 579 printf(" -m%d SL_ANDROID_PERFORMANCE_NONE\n", 580 SL_ANDROID_PERFORMANCE_NONE); 581 printf(" -m%d SL_ANDROID_PERFORMANCE_LATENCY\n", 582 SL_ANDROID_PERFORMANCE_LATENCY); 583 printf(" -m%d SL_ANDROID_PERFORMANCE_LATENCY_EFFECTS\n", 584 SL_ANDROID_PERFORMANCE_LATENCY_EFFECTS); 585 printf(" -m%d SL_ANDROID_PERFORMANCE_POWER_SAVING\n", 586 SL_ANDROID_PERFORMANCE_POWER_SAVING); 587 printf(" -x[e][a][n] for pre processing:\n" 588 " - e: Echo canceler\n" 589 " - a: Automatic Gain Control\n" 590 " - n: Noise Suppression\n"); 591 printf("Example: \"%s /sdcard/myrec.wav\" \n", prog); 592 exit(EXIT_FAILURE); 593 } 594 595 SLEngineOption EngineOption[] = { 596 {(SLuint32) SL_ENGINEOPTION_THREADSAFE, (SLuint32) SL_BOOLEAN_TRUE} 597 }; 598 599 result = slCreateEngine( &sl, 1, EngineOption, 0, NULL, NULL); 600 ExitOnError(result); 601 602 /* Realizing the SL Engine in synchronous mode. */ 603 result = (*sl)->Realize(sl, SL_BOOLEAN_FALSE); 604 ExitOnError(result); 605 606 TestRecToBuffQueue(sl, argv[i], durationInSeconds); 607 608 /* Shutdown OpenSL ES */ 609 (*sl)->Destroy(sl); 610 611 return EXIT_SUCCESS; 612} 613