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// Play an audio file using buffer queue 18 19#include <assert.h> 20#include <math.h> 21#include <pthread.h> 22#include <stdio.h> 23#include <stdlib.h> 24#include <string.h> 25#include <time.h> 26#include <unistd.h> 27 28#include <SLES/OpenSLES.h> 29#ifdef ANDROID 30#include <audio_utils/sndfile.h> 31#else 32#include <sndfile.h> 33#endif 34 35#include <media/nbaio/MonoPipe.h> 36#include <media/nbaio/MonoPipeReader.h> 37 38#define max(a, b) ((a) > (b) ? (a) : (b)) 39#define min(a, b) ((a) < (b) ? (a) : (b)) 40 41unsigned numBuffers = 2; 42int framesPerBuffer = 512; 43SNDFILE *sndfile; 44SF_INFO sfinfo; 45unsigned which; // which buffer to use next 46SLboolean eof; // whether we have hit EOF on input yet 47short *buffers; 48SLuint32 byteOrder; // desired to use for PCM buffers 49SLuint32 nativeByteOrder; // of platform 50SLuint32 bitsPerSample = 16; 51 52// swap adjacent bytes; this would normally be in <unistd.h> but is missing here 53static void swab(const void *from, void *to, ssize_t n) 54{ 55 // from and to as char pointers 56 const char *from_ch = (const char *) from; 57 char *to_ch = (char *) to; 58 // note that we don't swap the last odd byte 59 while (n >= 2) { 60 to_ch[0] = from_ch[1]; 61 to_ch[1] = from_ch[0]; 62 to_ch += 2; 63 from_ch += 2; 64 n -= 2; 65 } 66} 67 68// squeeze 16-bit signed PCM samples down to 8-bit unsigned PCM samples by truncation; no dithering 69static void squeeze(const short *from, unsigned char *to, ssize_t n) 70{ 71 // note that we don't squeeze the last odd byte 72 while (n >= 2) { 73 *to++ = (*from++ + 32768) >> 8; 74 n -= 2; 75 } 76} 77 78static android::MonoPipeReader *pipeReader; 79static android::MonoPipe *pipeWriter; 80static unsigned underruns = 0; 81 82// This callback is called each time a buffer finishes playing 83 84static void callback(SLBufferQueueItf bufq, void *param) 85{ 86 assert(NULL == param); 87 if (!eof) { 88 short *buffer = &buffers[framesPerBuffer * sfinfo.channels * which]; 89 ssize_t count = pipeReader->read(buffer, framesPerBuffer, (int64_t) -1); 90 // on underrun from pipe, substitute silence 91 if (0 >= count) { 92 memset(buffer, 0, framesPerBuffer * sfinfo.channels * sizeof(short)); 93 count = framesPerBuffer; 94 ++underruns; 95 } 96 if (count > 0) { 97 SLuint32 nbytes = count * sfinfo.channels * sizeof(short); 98 if (byteOrder != nativeByteOrder) { 99 swab(buffer, buffer, nbytes); 100 } 101 if (bitsPerSample == 8) { 102 squeeze(buffer, (unsigned char *) buffer, nbytes); 103 nbytes /= 2; 104 } 105 SLresult result = (*bufq)->Enqueue(bufq, buffer, nbytes); 106 assert(SL_RESULT_SUCCESS == result); 107 if (++which >= numBuffers) 108 which = 0; 109 } 110 } 111} 112 113// This thread reads from a (slow) filesystem with unpredictable latency and writes to pipe 114 115static void *file_reader_loop(void *arg) 116{ 117#define READ_FRAMES 256 118 short *temp = (short *) malloc(READ_FRAMES * sfinfo.channels * sizeof(short)); 119 sf_count_t total = 0; 120 for (;;) { 121 sf_count_t count = sf_readf_short(sndfile, temp, (sf_count_t) READ_FRAMES); 122 if (0 >= count) { 123 eof = SL_BOOLEAN_TRUE; 124 break; 125 } 126 const short *ptr = temp; 127 while (count > 0) { 128 ssize_t actual = pipeWriter->write(ptr, (size_t) count); 129 if (actual < 0) { 130 break; 131 } 132 if ((sf_count_t) actual < count) { 133 usleep(10000); 134 } 135 ptr += actual * sfinfo.channels; 136 count -= actual; 137 total += actual; 138 } 139 // simulate occasional filesystem latency 140 if ((total & 0xFF00) == 0xFF00) { 141 usleep(100000); 142 } 143 } 144 free(temp); 145 return NULL; 146} 147 148// Main program 149 150int main(int argc, char **argv) 151{ 152 // Determine the native byte order (SL_BYTEORDER_NATIVE not available until 1.1) 153 union { 154 short s; 155 char c[2]; 156 } u; 157 u.s = 0x1234; 158 if (u.c[0] == 0x34) { 159 nativeByteOrder = SL_BYTEORDER_LITTLEENDIAN; 160 } else if (u.c[0] == 0x12) { 161 nativeByteOrder = SL_BYTEORDER_BIGENDIAN; 162 } else { 163 fprintf(stderr, "Unable to determine native byte order\n"); 164 return EXIT_FAILURE; 165 } 166 byteOrder = nativeByteOrder; 167 168 SLboolean enableReverb = SL_BOOLEAN_FALSE; 169 SLboolean enablePlaybackRate = SL_BOOLEAN_FALSE; 170 SLpermille initialRate = 0; 171 SLpermille finalRate = 0; 172 SLpermille deltaRate = 1; 173 SLmillisecond deltaRateMs = 0; 174 175 // process command-line options 176 int i; 177 for (i = 1; i < argc; ++i) { 178 char *arg = argv[i]; 179 if (arg[0] != '-') { 180 break; 181 } 182 if (!strcmp(arg, "-b")) { 183 byteOrder = SL_BYTEORDER_BIGENDIAN; 184 } else if (!strcmp(arg, "-l")) { 185 byteOrder = SL_BYTEORDER_LITTLEENDIAN; 186 } else if (!strcmp(arg, "-8")) { 187 bitsPerSample = 8; 188 } else if (!strncmp(arg, "-f", 2)) { 189 framesPerBuffer = atoi(&arg[2]); 190 } else if (!strncmp(arg, "-n", 2)) { 191 numBuffers = atoi(&arg[2]); 192 } else if (!strncmp(arg, "-p", 2)) { 193 initialRate = atoi(&arg[2]); 194 enablePlaybackRate = SL_BOOLEAN_TRUE; 195 } else if (!strncmp(arg, "-P", 2)) { 196 finalRate = atoi(&arg[2]); 197 enablePlaybackRate = SL_BOOLEAN_TRUE; 198 } else if (!strncmp(arg, "-q", 2)) { 199 deltaRate = atoi(&arg[2]); 200 // deltaRate is a magnitude, so take absolute value 201 if (deltaRate < 0) { 202 deltaRate = -deltaRate; 203 } 204 enablePlaybackRate = SL_BOOLEAN_TRUE; 205 } else if (!strncmp(arg, "-Q", 2)) { 206 deltaRateMs = atoi(&arg[2]); 207 enablePlaybackRate = SL_BOOLEAN_TRUE; 208 } else if (!strcmp(arg, "-r")) { 209 enableReverb = SL_BOOLEAN_TRUE; 210 } else { 211 fprintf(stderr, "option %s ignored\n", arg); 212 } 213 } 214 215 if (argc - i != 1) { 216 fprintf(stderr, "usage: [-b/l] [-8] [-f#] [-n#] [-p#] [-r] %s filename\n", argv[0]); 217 fprintf(stderr, " -b force big-endian byte order (default is native byte order)\n"); 218 fprintf(stderr, " -l force little-endian byte order (default is native byte order)\n"); 219 fprintf(stderr, " -8 output 8-bits per sample (default is 16-bits per sample)\n"); 220 fprintf(stderr, " -f# frames per buffer (default 512)\n"); 221 fprintf(stderr, " -n# number of buffers (default 2)\n"); 222 fprintf(stderr, " -p# initial playback rate in per mille (default 1000)\n"); 223 fprintf(stderr, " -P# final playback rate in per mille (default same as -p#)\n"); 224 fprintf(stderr, " -q# magnitude of playback rate changes in per mille (default 1)\n"); 225 fprintf(stderr, " -Q# period between playback rate changes in ms (default 50)\n"); 226 fprintf(stderr, " -r enable reverb (default disabled)\n"); 227 return EXIT_FAILURE; 228 } 229 230 const char *filename = argv[i]; 231 //memset(&sfinfo, 0, sizeof(SF_INFO)); 232 sfinfo.format = 0; 233 sndfile = sf_open(filename, SFM_READ, &sfinfo); 234 if (NULL == sndfile) { 235 perror(filename); 236 return EXIT_FAILURE; 237 } 238 239 // The sample rate is a lie, but it doesn't actually matter 240 const android::NBAIO_Format nbaio_format = android::Format_from_SR_C(44100, sfinfo.channels); 241 242 // verify the file format 243 switch (sfinfo.channels) { 244 case 1: 245 case 2: 246 break; 247 default: 248 fprintf(stderr, "unsupported channel count %d\n", sfinfo.channels); 249 goto close_sndfile; 250 } 251 252 switch (sfinfo.samplerate) { 253 case 8000: 254 case 11025: 255 case 12000: 256 case 16000: 257 case 22050: 258 case 24000: 259 case 32000: 260 case 44100: 261 case 48000: 262 break; 263 default: 264 fprintf(stderr, "unsupported sample rate %d\n", sfinfo.samplerate); 265 goto close_sndfile; 266 } 267 268 switch (sfinfo.format & SF_FORMAT_TYPEMASK) { 269 case SF_FORMAT_WAV: 270 break; 271 default: 272 fprintf(stderr, "unsupported format type 0x%x\n", sfinfo.format & SF_FORMAT_TYPEMASK); 273 goto close_sndfile; 274 } 275 276 switch (sfinfo.format & SF_FORMAT_SUBMASK) { 277 case SF_FORMAT_PCM_16: 278 case SF_FORMAT_PCM_U8: 279 break; 280 default: 281 fprintf(stderr, "unsupported sub-format 0x%x\n", sfinfo.format & SF_FORMAT_SUBMASK); 282 goto close_sndfile; 283 } 284 285 { 286 287 buffers = (short *) malloc(framesPerBuffer * sfinfo.channels * sizeof(short) * numBuffers); 288 289 // create engine 290 SLresult result; 291 SLObjectItf engineObject; 292 result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL); 293 assert(SL_RESULT_SUCCESS == result); 294 SLEngineItf engineEngine; 295 result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE); 296 assert(SL_RESULT_SUCCESS == result); 297 result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine); 298 assert(SL_RESULT_SUCCESS == result); 299 300 // create output mix 301 SLObjectItf outputMixObject; 302 SLInterfaceID ids[1] = {SL_IID_ENVIRONMENTALREVERB}; 303 SLboolean req[1] = {SL_BOOLEAN_TRUE}; 304 result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, enableReverb ? 1 : 0, 305 ids, req); 306 assert(SL_RESULT_SUCCESS == result); 307 result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE); 308 assert(SL_RESULT_SUCCESS == result); 309 310 // configure environmental reverb on output mix 311 SLEnvironmentalReverbItf mixEnvironmentalReverb = NULL; 312 if (enableReverb) { 313 result = (*outputMixObject)->GetInterface(outputMixObject, SL_IID_ENVIRONMENTALREVERB, 314 &mixEnvironmentalReverb); 315 assert(SL_RESULT_SUCCESS == result); 316 SLEnvironmentalReverbSettings settings = SL_I3DL2_ENVIRONMENT_PRESET_STONECORRIDOR; 317 result = (*mixEnvironmentalReverb)->SetEnvironmentalReverbProperties(mixEnvironmentalReverb, 318 &settings); 319 assert(SL_RESULT_SUCCESS == result); 320 } 321 322 // configure audio source 323 SLDataLocator_BufferQueue loc_bufq; 324 loc_bufq.locatorType = SL_DATALOCATOR_BUFFERQUEUE; 325 loc_bufq.numBuffers = numBuffers; 326 SLDataFormat_PCM format_pcm; 327 format_pcm.formatType = SL_DATAFORMAT_PCM; 328 format_pcm.numChannels = sfinfo.channels; 329 format_pcm.samplesPerSec = sfinfo.samplerate * 1000; 330 format_pcm.bitsPerSample = bitsPerSample; 331 format_pcm.containerSize = format_pcm.bitsPerSample; 332 format_pcm.channelMask = 1 == format_pcm.numChannels ? SL_SPEAKER_FRONT_CENTER : 333 SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; 334 format_pcm.endianness = byteOrder; 335 SLDataSource audioSrc; 336 audioSrc.pLocator = &loc_bufq; 337 audioSrc.pFormat = &format_pcm; 338 339 // configure audio sink 340 SLDataLocator_OutputMix loc_outmix; 341 loc_outmix.locatorType = SL_DATALOCATOR_OUTPUTMIX; 342 loc_outmix.outputMix = outputMixObject; 343 SLDataSink audioSnk; 344 audioSnk.pLocator = &loc_outmix; 345 audioSnk.pFormat = NULL; 346 347 // create audio player 348 SLInterfaceID ids2[3] = {SL_IID_BUFFERQUEUE, SL_IID_PLAYBACKRATE, SL_IID_EFFECTSEND}; 349 SLboolean req2[3] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE}; 350 SLObjectItf playerObject; 351 result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc, 352 &audioSnk, enableReverb ? 3 : (enablePlaybackRate ? 2 : 1), ids2, req2); 353 if (SL_RESULT_SUCCESS != result) { 354 fprintf(stderr, "can't create audio player\n"); 355 goto no_player; 356 } 357 358 { 359 360 // realize the player 361 result = (*playerObject)->Realize(playerObject, SL_BOOLEAN_FALSE); 362 assert(SL_RESULT_SUCCESS == result); 363 364 // get the effect send interface and enable effect send reverb for this player 365 if (enableReverb) { 366 SLEffectSendItf playerEffectSend; 367 result = (*playerObject)->GetInterface(playerObject, SL_IID_EFFECTSEND, &playerEffectSend); 368 assert(SL_RESULT_SUCCESS == result); 369 result = (*playerEffectSend)->EnableEffectSend(playerEffectSend, mixEnvironmentalReverb, 370 SL_BOOLEAN_TRUE, (SLmillibel) 0); 371 assert(SL_RESULT_SUCCESS == result); 372 } 373 374 // get the playback rate interface and configure the rate 375 SLPlaybackRateItf playerPlaybackRate; 376 SLpermille currentRate = 0; 377 if (enablePlaybackRate) { 378 result = (*playerObject)->GetInterface(playerObject, SL_IID_PLAYBACKRATE, 379 &playerPlaybackRate); 380 assert(SL_RESULT_SUCCESS == result); 381 SLpermille defaultRate; 382 result = (*playerPlaybackRate)->GetRate(playerPlaybackRate, &defaultRate); 383 assert(SL_RESULT_SUCCESS == result); 384 SLuint32 defaultProperties; 385 result = (*playerPlaybackRate)->GetProperties(playerPlaybackRate, &defaultProperties); 386 assert(SL_RESULT_SUCCESS == result); 387 printf("default playback rate %d per mille, properties 0x%x\n", defaultRate, 388 defaultProperties); 389 if (initialRate <= 0) { 390 initialRate = defaultRate; 391 } 392 if (finalRate <= 0) { 393 finalRate = initialRate; 394 } 395 currentRate = defaultRate; 396 if (finalRate == initialRate) { 397 deltaRate = 0; 398 } else if (finalRate < initialRate) { 399 deltaRate = -deltaRate; 400 } 401 if (initialRate != defaultRate) { 402 result = (*playerPlaybackRate)->SetRate(playerPlaybackRate, initialRate); 403 if (SL_RESULT_FEATURE_UNSUPPORTED == result) { 404 fprintf(stderr, "initial playback rate %d is unsupported\n", initialRate); 405 deltaRate = 0; 406 } else if (SL_RESULT_PARAMETER_INVALID == result) { 407 fprintf(stderr, "initial playback rate %d is invalid\n", initialRate); 408 deltaRate = 0; 409 } else { 410 assert(SL_RESULT_SUCCESS == result); 411 currentRate = initialRate; 412 } 413 } 414 } 415 416 // get the play interface 417 SLPlayItf playerPlay; 418 result = (*playerObject)->GetInterface(playerObject, SL_IID_PLAY, &playerPlay); 419 assert(SL_RESULT_SUCCESS == result); 420 421 // get the buffer queue interface 422 SLBufferQueueItf playerBufferQueue; 423 result = (*playerObject)->GetInterface(playerObject, SL_IID_BUFFERQUEUE, 424 &playerBufferQueue); 425 assert(SL_RESULT_SUCCESS == result); 426 427 // loop until EOF or no more buffers 428 for (which = 0; which < numBuffers; ++which) { 429 short *buffer = &buffers[framesPerBuffer * sfinfo.channels * which]; 430 sf_count_t frames = framesPerBuffer; 431 sf_count_t count; 432 count = sf_readf_short(sndfile, buffer, frames); 433 if (0 >= count) { 434 eof = SL_BOOLEAN_TRUE; 435 break; 436 } 437 438 // enqueue a buffer 439 SLuint32 nbytes = count * sfinfo.channels * sizeof(short); 440 if (byteOrder != nativeByteOrder) { 441 swab(buffer, buffer, nbytes); 442 } 443 if (bitsPerSample == 8) { 444 squeeze(buffer, (unsigned char *) buffer, nbytes); 445 nbytes /= 2; 446 } 447 result = (*playerBufferQueue)->Enqueue(playerBufferQueue, buffer, nbytes); 448 assert(SL_RESULT_SUCCESS == result); 449 } 450 if (which >= numBuffers) { 451 which = 0; 452 } 453 454 // register a callback on the buffer queue 455 result = (*playerBufferQueue)->RegisterCallback(playerBufferQueue, callback, NULL); 456 assert(SL_RESULT_SUCCESS == result); 457 458 pipeWriter = new android::MonoPipe(16384, nbaio_format, false /*writeCanBlock*/); 459 android::NBAIO_Format offer = nbaio_format; 460 size_t numCounterOffers = 0; 461 ssize_t neg = pipeWriter->negotiate(&offer, 1, NULL, numCounterOffers); 462 assert(0 == neg); 463 pipeReader = new android::MonoPipeReader(pipeWriter); 464 numCounterOffers = 0; 465 neg = pipeReader->negotiate(&offer, 1, NULL, numCounterOffers); 466 assert(0 == neg); 467 468 // create thread to read from file 469 pthread_t thread; 470 int ok = pthread_create(&thread, (const pthread_attr_t *) NULL, file_reader_loop, NULL); 471 assert(0 == ok); 472 473 // give thread a head start so that the pipe is initially filled 474 sleep(1); 475 476 // set the player's state to playing 477 result = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PLAYING); 478 assert(SL_RESULT_SUCCESS == result); 479 480 // get the initial time 481 struct timespec prevTs; 482 clock_gettime(CLOCK_MONOTONIC, &prevTs); 483 long elapsedNs = 0; 484 long deltaRateNs = deltaRateMs * 1000000; 485 486 // wait until the buffer queue is empty 487 SLBufferQueueState bufqstate; 488 for (;;) { 489 result = (*playerBufferQueue)->GetState(playerBufferQueue, &bufqstate); 490 assert(SL_RESULT_SUCCESS == result); 491 if (0 >= bufqstate.count) { 492 break; 493 } 494 if (!enablePlaybackRate || deltaRate == 0) { 495 sleep(1); 496 } else { 497 struct timespec curTs; 498 clock_gettime(CLOCK_MONOTONIC, &curTs); 499 elapsedNs += (curTs.tv_sec - prevTs.tv_sec) * 1000000000 + 500 // this term can be negative 501 (curTs.tv_nsec - prevTs.tv_nsec); 502 prevTs = curTs; 503 if (elapsedNs < deltaRateNs) { 504 usleep((deltaRateNs - elapsedNs) / 1000); 505 continue; 506 } 507 elapsedNs -= deltaRateNs; 508 SLpermille nextRate = currentRate + deltaRate; 509 result = (*playerPlaybackRate)->SetRate(playerPlaybackRate, nextRate); 510 if (SL_RESULT_SUCCESS != result) { 511 fprintf(stderr, "next playback rate %d is unsupported\n", nextRate); 512 } else if (SL_RESULT_PARAMETER_INVALID == result) { 513 fprintf(stderr, "next playback rate %d is invalid\n", nextRate); 514 } else { 515 assert(SL_RESULT_SUCCESS == result); 516 } 517 currentRate = nextRate; 518 if (currentRate >= max(initialRate, finalRate)) { 519 currentRate = max(initialRate, finalRate); 520 deltaRate = -abs(deltaRate); 521 } else if (currentRate <= min(initialRate, finalRate)) { 522 currentRate = min(initialRate, finalRate); 523 deltaRate = abs(deltaRate); 524 } 525 } 526 } 527 528 // destroy audio player 529 (*playerObject)->Destroy(playerObject); 530 531 } 532 533no_player: 534 535 // destroy output mix 536 (*outputMixObject)->Destroy(outputMixObject); 537 538 // destroy engine 539 (*engineObject)->Destroy(engineObject); 540 541 } 542 543close_sndfile: 544 545 (void) sf_close(sndfile); 546 547 return EXIT_SUCCESS; 548} 549