AudioPlayer_to_android.cpp revision a9a70a4451545034c9263dd55b181f2912534c37
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#include "sles_allinclusive.h" 18#include "utils/RefBase.h" 19#include "android_prompts.h" 20 21template class android::KeyedVector<SLuint32, android::AudioEffect* > ; 22 23#define KEY_STREAM_TYPE_PARAMSIZE sizeof(SLint32) 24 25//----------------------------------------------------------------------------- 26int android_getMinFrameCount(uint32_t sampleRate) { 27 int afSampleRate; 28 if (android::AudioSystem::getOutputSamplingRate(&afSampleRate, 29 ANDROID_DEFAULT_OUTPUT_STREAM_TYPE) != android::NO_ERROR) { 30 return ANDROID_DEFAULT_AUDIOTRACK_BUFFER_SIZE; 31 } 32 int afFrameCount; 33 if (android::AudioSystem::getOutputFrameCount(&afFrameCount, 34 ANDROID_DEFAULT_OUTPUT_STREAM_TYPE) != android::NO_ERROR) { 35 return ANDROID_DEFAULT_AUDIOTRACK_BUFFER_SIZE; 36 } 37 uint32_t afLatency; 38 if (android::AudioSystem::getOutputLatency(&afLatency, 39 ANDROID_DEFAULT_OUTPUT_STREAM_TYPE) != android::NO_ERROR) { 40 return ANDROID_DEFAULT_AUDIOTRACK_BUFFER_SIZE; 41 } 42 // minimum nb of buffers to cover output latency, given the size of each hardware audio buffer 43 uint32_t minBufCount = afLatency / ((1000 * afFrameCount)/afSampleRate); 44 if (minBufCount < 2) minBufCount = 2; 45 // minimum number of frames to cover output latency at the sample rate of the content 46 return (afFrameCount*sampleRate*minBufCount)/afSampleRate; 47} 48 49 50//----------------------------------------------------------------------------- 51#define LEFT_CHANNEL_MASK 0x1 << 0 52#define RIGHT_CHANNEL_MASK 0x1 << 1 53 54static void android_audioPlayer_updateStereoVolume(CAudioPlayer* ap) { 55 float leftVol = 1.0f, rightVol = 1.0f; 56 57 if (NULL == ap->mAudioTrack) { 58 return; 59 } 60 // should not be used when muted 61 if (SL_BOOLEAN_TRUE == ap->mMute) { 62 return; 63 } 64 65 int channelCount = ap->mNumChannels; 66 67 // mute has priority over solo 68 int leftAudibilityFactor = 1, rightAudibilityFactor = 1; 69 70 if (channelCount >= STEREO_CHANNELS) { 71 if (ap->mMuteMask & LEFT_CHANNEL_MASK) { 72 // left muted 73 leftAudibilityFactor = 0; 74 } else { 75 // left not muted 76 if (ap->mSoloMask & LEFT_CHANNEL_MASK) { 77 // left soloed 78 leftAudibilityFactor = 1; 79 } else { 80 // left not soloed 81 if (ap->mSoloMask & RIGHT_CHANNEL_MASK) { 82 // right solo silences left 83 leftAudibilityFactor = 0; 84 } else { 85 // left and right are not soloed, and left is not muted 86 leftAudibilityFactor = 1; 87 } 88 } 89 } 90 91 if (ap->mMuteMask & RIGHT_CHANNEL_MASK) { 92 // right muted 93 rightAudibilityFactor = 0; 94 } else { 95 // right not muted 96 if (ap->mSoloMask & RIGHT_CHANNEL_MASK) { 97 // right soloed 98 rightAudibilityFactor = 1; 99 } else { 100 // right not soloed 101 if (ap->mSoloMask & LEFT_CHANNEL_MASK) { 102 // left solo silences right 103 rightAudibilityFactor = 0; 104 } else { 105 // left and right are not soloed, and right is not muted 106 rightAudibilityFactor = 1; 107 } 108 } 109 } 110 } 111 112 // compute amplification as the combination of volume level and stereo position 113 // amplification from volume level 114 ap->mAmplFromVolLevel = sles_to_android_amplification(ap->mVolume.mLevel); 115 // amplification from direct level (changed in SLEffectSendtItf and SLAndroidEffectSendItf) 116 leftVol *= ap->mAmplFromVolLevel * ap->mAmplFromDirectLevel; 117 rightVol *= ap->mAmplFromVolLevel * ap->mAmplFromDirectLevel; 118 119 // amplification from stereo position 120 if (ap->mVolume.mEnableStereoPosition) { 121 // panning law depends on number of channels of content: stereo panning vs 2ch. balance 122 if(1 == channelCount) { 123 // stereo panning 124 double theta = (1000+ap->mVolume.mStereoPosition)*M_PI_4/1000.0f; // 0 <= theta <= Pi/2 125 ap->mAmplFromStereoPos[0] = cos(theta); 126 ap->mAmplFromStereoPos[1] = sin(theta); 127 } else { 128 // stereo balance 129 if (ap->mVolume.mStereoPosition > 0) { 130 ap->mAmplFromStereoPos[0] = (1000-ap->mVolume.mStereoPosition)/1000.0f; 131 ap->mAmplFromStereoPos[1] = 1.0f; 132 } else { 133 ap->mAmplFromStereoPos[0] = 1.0f; 134 ap->mAmplFromStereoPos[1] = (1000+ap->mVolume.mStereoPosition)/1000.0f; 135 } 136 } 137 leftVol *= ap->mAmplFromStereoPos[0]; 138 rightVol *= ap->mAmplFromStereoPos[1]; 139 } 140 141 ap->mAudioTrack->setVolume(leftVol * leftAudibilityFactor, rightVol * rightAudibilityFactor); 142 143 // changes in the AudioPlayer volume must be reflected in the send level: 144 // in SLEffectSendItf or in SLAndroidEffectSendItf? 145 // FIXME replace interface test by an internal API once we have one. 146 if (NULL != ap->mEffectSend.mItf) { 147 for (unsigned int i=0 ; i<AUX_MAX ; i++) { 148 if (ap->mEffectSend.mEnableLevels[i].mEnable) { 149 android_fxSend_setSendLevel(ap, 150 ap->mEffectSend.mEnableLevels[i].mSendLevel + ap->mVolume.mLevel); 151 // there's a single aux bus on Android, so we can stop looking once the first 152 // aux effect is found. 153 break; 154 } 155 } 156 } else if (NULL != ap->mAndroidEffectSend.mItf) { 157 android_fxSend_setSendLevel(ap, ap->mAndroidEffectSend.mSendLevel + ap->mVolume.mLevel); 158 } 159} 160 161//----------------------------------------------------------------------------- 162void audioTrack_handleMarker_lockPlay(CAudioPlayer* ap) { 163 //SL_LOGV("received event EVENT_MARKER from AudioTrack"); 164 slPlayCallback callback = NULL; 165 void* callbackPContext = NULL; 166 167 interface_lock_shared(&ap->mPlay); 168 callback = ap->mPlay.mCallback; 169 callbackPContext = ap->mPlay.mContext; 170 interface_unlock_shared(&ap->mPlay); 171 172 if (NULL != callback) { 173 // getting this event implies SL_PLAYEVENT_HEADATMARKER was set in the event mask 174 (*callback)(&ap->mPlay.mItf, callbackPContext, SL_PLAYEVENT_HEADATMARKER); 175 } 176} 177 178//----------------------------------------------------------------------------- 179void audioTrack_handleNewPos_lockPlay(CAudioPlayer* ap) { 180 //SL_LOGV("received event EVENT_NEW_POS from AudioTrack"); 181 slPlayCallback callback = NULL; 182 void* callbackPContext = NULL; 183 184 interface_lock_shared(&ap->mPlay); 185 callback = ap->mPlay.mCallback; 186 callbackPContext = ap->mPlay.mContext; 187 interface_unlock_shared(&ap->mPlay); 188 189 if (NULL != callback) { 190 // getting this event implies SL_PLAYEVENT_HEADATNEWPOS was set in the event mask 191 (*callback)(&ap->mPlay.mItf, callbackPContext, SL_PLAYEVENT_HEADATNEWPOS); 192 } 193} 194 195 196//----------------------------------------------------------------------------- 197void audioTrack_handleUnderrun_lockPlay(CAudioPlayer* ap) { 198 slPlayCallback callback = NULL; 199 void* callbackPContext = NULL; 200 201 interface_lock_shared(&ap->mPlay); 202 callback = ap->mPlay.mCallback; 203 callbackPContext = ap->mPlay.mContext; 204 bool headStalled = (ap->mPlay.mEventFlags & SL_PLAYEVENT_HEADSTALLED) != 0; 205 interface_unlock_shared(&ap->mPlay); 206 207 if ((NULL != callback) && headStalled) { 208 (*callback)(&ap->mPlay.mItf, callbackPContext, SL_PLAYEVENT_HEADSTALLED); 209 } 210} 211 212 213//----------------------------------------------------------------------------- 214/** 215 * post-condition: play state of AudioPlayer is SL_PLAYSTATE_PAUSED if setPlayStateToPaused is true 216 * 217 * note: a conditional flag, setPlayStateToPaused, is used here to specify whether the play state 218 * needs to be changed when the player reaches the end of the content to play. This is 219 * relative to what the specification describes for buffer queues vs the 220 * SL_PLAYEVENT_HEADATEND event. In the OpenSL ES specification 1.0.1: 221 * - section 8.12 SLBufferQueueItf states "In the case of starvation due to insufficient 222 * buffers in the queue, the playing of audio data stops. The player remains in the 223 * SL_PLAYSTATE_PLAYING state." 224 * - section 9.2.31 SL_PLAYEVENT states "SL_PLAYEVENT_HEADATEND Playback head is at the end 225 * of the current content and the player has paused." 226 */ 227void audioPlayer_dispatch_headAtEnd_lockPlay(CAudioPlayer *ap, bool setPlayStateToPaused, 228 bool needToLock) { 229 //SL_LOGV("ap=%p, setPlayStateToPaused=%d, needToLock=%d", ap, setPlayStateToPaused, 230 // needToLock); 231 slPlayCallback playCallback = NULL; 232 void * playContext = NULL; 233 // SLPlayItf callback or no callback? 234 if (needToLock) { 235 interface_lock_exclusive(&ap->mPlay); 236 } 237 if (ap->mPlay.mEventFlags & SL_PLAYEVENT_HEADATEND) { 238 playCallback = ap->mPlay.mCallback; 239 playContext = ap->mPlay.mContext; 240 } 241 if (setPlayStateToPaused) { 242 ap->mPlay.mState = SL_PLAYSTATE_PAUSED; 243 } 244 if (needToLock) { 245 interface_unlock_exclusive(&ap->mPlay); 246 } 247 // callback with no lock held 248 if (NULL != playCallback) { 249 (*playCallback)(&ap->mPlay.mItf, playContext, SL_PLAYEVENT_HEADATEND); 250 } 251 252} 253 254 255//----------------------------------------------------------------------------- 256/** 257 * pre-condition: AudioPlayer has SLPrefetchStatusItf initialized 258 * post-condition: 259 * - ap->mPrefetchStatus.mStatus == status 260 * - the prefetch status callback, if any, has been notified if a change occurred 261 * 262 */ 263void audioPlayer_dispatch_prefetchStatus_lockPrefetch(CAudioPlayer *ap, SLuint32 status, 264 bool needToLock) { 265 slPrefetchCallback prefetchCallback = NULL; 266 void * prefetchContext = NULL; 267 268 if (needToLock) { 269 interface_lock_exclusive(&ap->mPrefetchStatus); 270 } 271 // status change? 272 if (ap->mPrefetchStatus.mStatus != status) { 273 ap->mPrefetchStatus.mStatus = status; 274 // callback or no callback? 275 if (ap->mPrefetchStatus.mCallbackEventsMask & SL_PREFETCHEVENT_STATUSCHANGE) { 276 prefetchCallback = ap->mPrefetchStatus.mCallback; 277 prefetchContext = ap->mPrefetchStatus.mContext; 278 } 279 } 280 if (needToLock) { 281 interface_unlock_exclusive(&ap->mPrefetchStatus); 282 } 283 284 // callback with no lock held 285 if (NULL != prefetchCallback) { 286 (*prefetchCallback)(&ap->mPrefetchStatus.mItf, prefetchContext, status); 287 } 288} 289 290 291//----------------------------------------------------------------------------- 292SLresult audioPlayer_setStreamType(CAudioPlayer* ap, SLint32 type) { 293 SLresult result = SL_RESULT_SUCCESS; 294 SL_LOGV("type %ld", type); 295 296 int newStreamType = ANDROID_DEFAULT_OUTPUT_STREAM_TYPE; 297 switch(type) { 298 case SL_ANDROID_STREAM_VOICE: 299 newStreamType = android::AudioSystem::VOICE_CALL; 300 break; 301 case SL_ANDROID_STREAM_SYSTEM: 302 newStreamType = android::AudioSystem::SYSTEM; 303 break; 304 case SL_ANDROID_STREAM_RING: 305 newStreamType = android::AudioSystem::RING; 306 break; 307 case SL_ANDROID_STREAM_MEDIA: 308 newStreamType = android::AudioSystem::MUSIC; 309 break; 310 case SL_ANDROID_STREAM_ALARM: 311 newStreamType = android::AudioSystem::ALARM; 312 break; 313 case SL_ANDROID_STREAM_NOTIFICATION: 314 newStreamType = android::AudioSystem::NOTIFICATION; 315 break; 316 default: 317 SL_LOGE(ERROR_PLAYERSTREAMTYPE_SET_UNKNOWN_TYPE); 318 result = SL_RESULT_PARAMETER_INVALID; 319 break; 320 } 321 322 // stream type needs to be set before the object is realized 323 // (ap->mAudioTrack is supposed to be NULL until then) 324 if (SL_OBJECT_STATE_UNREALIZED != ap->mObject.mState) { 325 SL_LOGE(ERROR_PLAYERSTREAMTYPE_REALIZED); 326 result = SL_RESULT_PRECONDITIONS_VIOLATED; 327 } else { 328 ap->mStreamType = newStreamType; 329 } 330 331 return result; 332} 333 334 335//----------------------------------------------------------------------------- 336SLresult audioPlayer_getStreamType(CAudioPlayer* ap, SLint32 *pType) { 337 SLresult result = SL_RESULT_SUCCESS; 338 339 switch(ap->mStreamType) { 340 case android::AudioSystem::VOICE_CALL: 341 *pType = SL_ANDROID_STREAM_VOICE; 342 break; 343 case android::AudioSystem::SYSTEM: 344 *pType = SL_ANDROID_STREAM_SYSTEM; 345 break; 346 case android::AudioSystem::RING: 347 *pType = SL_ANDROID_STREAM_RING; 348 break; 349 case android::AudioSystem::DEFAULT: 350 case android::AudioSystem::MUSIC: 351 *pType = SL_ANDROID_STREAM_MEDIA; 352 break; 353 case android::AudioSystem::ALARM: 354 *pType = SL_ANDROID_STREAM_ALARM; 355 break; 356 case android::AudioSystem::NOTIFICATION: 357 *pType = SL_ANDROID_STREAM_NOTIFICATION; 358 break; 359 default: 360 result = SL_RESULT_INTERNAL_ERROR; 361 *pType = SL_ANDROID_STREAM_MEDIA; 362 break; 363 } 364 365 return result; 366} 367 368 369//----------------------------------------------------------------------------- 370#ifndef USE_BACKPORT 371static void sfplayer_prepare(CAudioPlayer *ap, bool lockAP) { 372 373 if (lockAP) { object_lock_exclusive(&ap->mObject); } 374 ap->mAndroidObjState = ANDROID_PREPARING; 375 if (lockAP) { object_unlock_exclusive(&ap->mObject); } 376 377 if (ap->mSfPlayer != 0) { 378 ap->mSfPlayer->prepare(); 379 } 380} 381#endif 382 383//----------------------------------------------------------------------------- 384#ifndef USE_BACKPORT 385// Callback associated with an SfPlayer of an SL ES AudioPlayer that gets its data 386// from a URI or FD, for prepare and prefetch events 387static void sfplayer_handlePrefetchEvent(const int event, const int data1, void* user) { 388 if (NULL == user) { 389 return; 390 } 391 392 CAudioPlayer *ap = (CAudioPlayer *)user; 393 //SL_LOGV("received event %d, data %d from SfAudioPlayer", event, data1); 394 switch(event) { 395 396 case(android::SfPlayer::kEventPrepared): { 397 object_lock_exclusive(&ap->mObject); 398 399 if (SFPLAYER_SUCCESS != data1) { 400 ap->mAudioTrack = NULL; 401 ap->mNumChannels = 0; 402 ap->mSampleRateMilliHz = 0; 403 ap->mAndroidObjState = ANDROID_UNINITIALIZED; 404 405 } else { 406 ap->mAudioTrack = ap->mSfPlayer->getAudioTrack(); 407 ap->mNumChannels = ap->mSfPlayer->getNumChannels(); 408 ap->mSampleRateMilliHz = android_to_sles_sampleRate(ap->mSfPlayer->getSampleRateHz()); 409 ap->mSfPlayer->startPrefetch_async(); 410 411 // update the new track with the current settings 412 android_audioPlayer_useEventMask(ap); 413 android_audioPlayer_volumeUpdate(ap); 414 android_audioPlayer_setPlayRate(ap, ap->mPlaybackRate.mRate, false /*lockAP*/); 415 416 ap->mAndroidObjState = ANDROID_READY; 417 } 418 419 object_unlock_exclusive(&ap->mObject); 420 } break; 421 422 case(android::SfPlayer::kEventPrefetchFillLevelUpdate): { 423 if (!IsInterfaceInitialized(&(ap->mObject), MPH_PREFETCHSTATUS)) { 424 break; 425 } 426 slPrefetchCallback callback = NULL; 427 void* callbackPContext = NULL; 428 429 // SLPrefetchStatusItf callback or no callback? 430 interface_lock_exclusive(&ap->mPrefetchStatus); 431 if (ap->mPrefetchStatus.mCallbackEventsMask & SL_PREFETCHEVENT_FILLLEVELCHANGE) { 432 callback = ap->mPrefetchStatus.mCallback; 433 callbackPContext = ap->mPrefetchStatus.mContext; 434 } 435 ap->mPrefetchStatus.mLevel = (SLpermille)data1; 436 interface_unlock_exclusive(&ap->mPrefetchStatus); 437 438 // callback with no lock held 439 if (NULL != callback) { 440 (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext, 441 SL_PREFETCHEVENT_FILLLEVELCHANGE); 442 } 443 } break; 444 445 case(android::SfPlayer::kEventPrefetchStatusChange): { 446 if (!IsInterfaceInitialized(&(ap->mObject), MPH_PREFETCHSTATUS)) { 447 break; 448 } 449 slPrefetchCallback callback = NULL; 450 void* callbackPContext = NULL; 451 452 // SLPrefetchStatusItf callback or no callback? 453 object_lock_exclusive(&ap->mObject); 454 if (ap->mPrefetchStatus.mCallbackEventsMask & SL_PREFETCHEVENT_STATUSCHANGE) { 455 callback = ap->mPrefetchStatus.mCallback; 456 callbackPContext = ap->mPrefetchStatus.mContext; 457 } 458 if (data1 >= android::SfPlayer::kStatusIntermediate) { 459 ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_SUFFICIENTDATA; 460 // FIXME estimate fill level better? 461 ap->mPrefetchStatus.mLevel = 1000; 462 ap->mAndroidObjState = ANDROID_READY; 463 } else if (data1 < android::SfPlayer::kStatusIntermediate) { 464 ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_UNDERFLOW; 465 // FIXME estimate fill level better? 466 ap->mPrefetchStatus.mLevel = 0; 467 } 468 object_unlock_exclusive(&ap->mObject); 469 470 // callback with no lock held 471 if (NULL != callback) { 472 (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext, SL_PREFETCHEVENT_STATUSCHANGE); 473 } 474 } break; 475 476 case(android::SfPlayer::kEventEndOfStream): { 477 audioPlayer_dispatch_headAtEnd_lockPlay(ap, true /*set state to paused?*/, true); 478 if ((NULL != ap->mAudioTrack) && (!ap->mSeek.mLoopEnabled)) { 479 ap->mAudioTrack->stop(); 480 } 481 } break; 482 483 default: 484 break; 485 } 486} 487#endif 488 489 490//----------------------------------------------------------------------------- 491SLresult android_audioPlayer_checkSourceSink(CAudioPlayer *pAudioPlayer) 492{ 493 const SLDataSource *pAudioSrc = &pAudioPlayer->mDataSource.u.mSource; 494 const SLDataSink *pAudioSnk = &pAudioPlayer->mDataSink.u.mSink; 495 //-------------------------------------- 496 // Sink check: 497 // currently only OutputMix sinks are supported, regardless of the data source 498 if (*(SLuint32 *)pAudioSnk->pLocator != SL_DATALOCATOR_OUTPUTMIX) { 499 SL_LOGE("Cannot create audio player: data sink is not SL_DATALOCATOR_OUTPUTMIX"); 500 return SL_RESULT_PARAMETER_INVALID; 501 } 502 503 //-------------------------------------- 504 // Source check: 505 SLuint32 locatorType = *(SLuint32 *)pAudioSrc->pLocator; 506 SLuint32 formatType = *(SLuint32 *)pAudioSrc->pFormat; 507 508 switch (locatorType) { 509 //------------------ 510 // Buffer Queues 511 case SL_DATALOCATOR_BUFFERQUEUE: 512 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 513 { 514 SLDataLocator_BufferQueue *dl_bq = (SLDataLocator_BufferQueue *) pAudioSrc->pLocator; 515 516 // Buffer format 517 switch (formatType) { 518 // currently only PCM buffer queues are supported, 519 case SL_DATAFORMAT_PCM: { 520 SLDataFormat_PCM *df_pcm = (SLDataFormat_PCM *) pAudioSrc->pFormat; 521 switch (df_pcm->numChannels) { 522 case 1: 523 case 2: 524 break; 525 default: 526 // this should have already been rejected by checkDataFormat 527 SL_LOGE("Cannot create audio player: unsupported " \ 528 "PCM data source with %u channels", (unsigned) df_pcm->numChannels); 529 return SL_RESULT_CONTENT_UNSUPPORTED; 530 } 531 switch (df_pcm->samplesPerSec) { 532 case SL_SAMPLINGRATE_8: 533 case SL_SAMPLINGRATE_11_025: 534 case SL_SAMPLINGRATE_12: 535 case SL_SAMPLINGRATE_16: 536 case SL_SAMPLINGRATE_22_05: 537 case SL_SAMPLINGRATE_24: 538 case SL_SAMPLINGRATE_32: 539 case SL_SAMPLINGRATE_44_1: 540 break; 541 case SL_SAMPLINGRATE_48: // not 48? 542 case SL_SAMPLINGRATE_64: 543 case SL_SAMPLINGRATE_88_2: 544 case SL_SAMPLINGRATE_96: 545 case SL_SAMPLINGRATE_192: 546 default: 547 SL_LOGE("Cannot create audio player: unsupported sample rate %u milliHz", 548 (unsigned) df_pcm->samplesPerSec); 549 return SL_RESULT_CONTENT_UNSUPPORTED; 550 } 551 switch (df_pcm->bitsPerSample) { 552 case SL_PCMSAMPLEFORMAT_FIXED_8: 553 // FIXME We should support this 554 SL_LOGE("Cannot create audio player: unsupported 8-bit data"); 555 return SL_RESULT_CONTENT_UNSUPPORTED; 556 case SL_PCMSAMPLEFORMAT_FIXED_16: 557 break; 558 // others 559 default: 560 // this should have already been rejected by checkDataFormat 561 SL_LOGE("Cannot create audio player: unsupported sample bit depth %lu", 562 (SLuint32)df_pcm->bitsPerSample); 563 return SL_RESULT_CONTENT_UNSUPPORTED; 564 } 565 switch (df_pcm->containerSize) { 566 case 16: 567 break; 568 // others 569 default: 570 SL_LOGE("Cannot create audio player: unsupported container size %u", 571 (unsigned) df_pcm->containerSize); 572 return SL_RESULT_CONTENT_UNSUPPORTED; 573 } 574 switch (df_pcm->channelMask) { 575 // FIXME needs work 576 default: 577 break; 578 } 579 switch (df_pcm->endianness) { 580 case SL_BYTEORDER_LITTLEENDIAN: 581 break; 582 case SL_BYTEORDER_BIGENDIAN: 583 SL_LOGE("Cannot create audio player: unsupported big-endian byte order"); 584 return SL_RESULT_CONTENT_UNSUPPORTED; 585 // native is proposed but not yet in spec 586 default: 587 SL_LOGE("Cannot create audio player: unsupported byte order %u", 588 (unsigned) df_pcm->endianness); 589 return SL_RESULT_CONTENT_UNSUPPORTED; 590 } 591 } //case SL_DATAFORMAT_PCM 592 break; 593 case SL_DATAFORMAT_MIME: 594 case SL_DATAFORMAT_RESERVED3: 595 SL_LOGE("Cannot create audio player with buffer queue data source " 596 "without SL_DATAFORMAT_PCM format"); 597 return SL_RESULT_CONTENT_UNSUPPORTED; 598 default: 599 SL_LOGE("Cannot create audio player with buffer queue data source " 600 "without SL_DATAFORMAT_PCM format"); 601 return SL_RESULT_PARAMETER_INVALID; 602 } // switch (formatType) 603 } // case SL_DATALOCATOR_BUFFERQUEUE or SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE 604 break; 605 //------------------ 606 // URI 607 case SL_DATALOCATOR_URI: 608 { 609 SLDataLocator_URI *dl_uri = (SLDataLocator_URI *) pAudioSrc->pLocator; 610 if (NULL == dl_uri->URI) { 611 return SL_RESULT_PARAMETER_INVALID; 612 } 613 // URI format 614 switch (formatType) { 615 case SL_DATAFORMAT_MIME: 616 break; 617 case SL_DATAFORMAT_PCM: 618 case SL_DATAFORMAT_RESERVED3: 619 SL_LOGE("Cannot create audio player with SL_DATALOCATOR_URI data source without " 620 "SL_DATAFORMAT_MIME format"); 621 return SL_RESULT_CONTENT_UNSUPPORTED; 622 } // switch (formatType) 623 } // case SL_DATALOCATOR_URI 624 break; 625 //------------------ 626 // File Descriptor 627 case SL_DATALOCATOR_ANDROIDFD: 628 { 629 // fd is already non null 630 switch (formatType) { 631 case SL_DATAFORMAT_MIME: 632 break; 633 case SL_DATAFORMAT_PCM: 634 // FIXME implement 635 SL_LOGD("[ FIXME implement PCM FD data sources ]"); 636 break; 637 case SL_DATAFORMAT_RESERVED3: 638 SL_LOGE("Cannot create audio player with SL_DATALOCATOR_ANDROIDFD data source " 639 "without SL_DATAFORMAT_MIME or SL_DATAFORMAT_PCM format"); 640 return SL_RESULT_CONTENT_UNSUPPORTED; 641 } // switch (formatType) 642 } // case SL_DATALOCATOR_ANDROIDFD 643 break; 644 //------------------ 645 // Address 646 case SL_DATALOCATOR_ADDRESS: 647 case SL_DATALOCATOR_IODEVICE: 648 case SL_DATALOCATOR_OUTPUTMIX: 649 case SL_DATALOCATOR_RESERVED5: 650 case SL_DATALOCATOR_MIDIBUFFERQUEUE: 651 case SL_DATALOCATOR_RESERVED8: 652 SL_LOGE("Cannot create audio player with data locator type 0x%x", (unsigned) locatorType); 653 return SL_RESULT_CONTENT_UNSUPPORTED; 654 default: 655 return SL_RESULT_PARAMETER_INVALID; 656 }// switch (locatorType) 657 658 return SL_RESULT_SUCCESS; 659} 660 661 662 663//----------------------------------------------------------------------------- 664static void audioTrack_callBack_uri(int event, void* user, void *info) { 665 // EVENT_MORE_DATA needs to be handled with priority over the other events 666 // because it will be called the most often during playback 667 if (event == android::AudioTrack::EVENT_MORE_DATA) { 668 //SL_LOGV("received event EVENT_MORE_DATA from AudioTrack"); 669 // set size to 0 to signal we're not using the callback to write more data 670 android::AudioTrack::Buffer* pBuff = (android::AudioTrack::Buffer*)info; 671 pBuff->size = 0; 672 } else if (NULL != user) { 673 switch (event) { 674 case (android::AudioTrack::EVENT_MARKER) : 675 audioTrack_handleMarker_lockPlay((CAudioPlayer *)user); 676 break; 677 case (android::AudioTrack::EVENT_NEW_POS) : 678 audioTrack_handleNewPos_lockPlay((CAudioPlayer *)user); 679 break; 680 case (android::AudioTrack::EVENT_UNDERRUN) : 681 audioTrack_handleUnderrun_lockPlay((CAudioPlayer *)user); 682 break; 683 default: 684 SL_LOGE("Encountered unknown AudioTrack event %d for CAudioPlayer %p", event, 685 (CAudioPlayer *)user); 686 break; 687 } 688 } 689} 690 691//----------------------------------------------------------------------------- 692// Callback associated with an AudioTrack of an SL ES AudioPlayer that gets its data 693// from a buffer queue. 694static void audioTrack_callBack_pullFromBuffQueue(int event, void* user, void *info) { 695 CAudioPlayer *ap = (CAudioPlayer *)user; 696 void * callbackPContext = NULL; 697 switch(event) { 698 699 case (android::AudioTrack::EVENT_MORE_DATA) : { 700 //SL_LOGV("received event EVENT_MORE_DATA from AudioTrack"); 701 slBufferQueueCallback callback = NULL; 702 android::AudioTrack::Buffer* pBuff = (android::AudioTrack::Buffer*)info; 703 // retrieve data from the buffer queue 704 interface_lock_exclusive(&ap->mBufferQueue); 705 if (ap->mBufferQueue.mState.count != 0) { 706 //SL_LOGV("nbBuffers in queue = %lu",ap->mBufferQueue.mState.count); 707 assert(ap->mBufferQueue.mFront != ap->mBufferQueue.mRear); 708 709 BufferHeader *oldFront = ap->mBufferQueue.mFront; 710 BufferHeader *newFront = &oldFront[1]; 711 712 // FIXME handle 8bit based on buffer format 713 short *pSrc = (short*)((char *)oldFront->mBuffer 714 + ap->mBufferQueue.mSizeConsumed); 715 if (ap->mBufferQueue.mSizeConsumed + pBuff->size < oldFront->mSize) { 716 // can't consume the whole or rest of the buffer in one shot 717 ap->mBufferQueue.mSizeConsumed += pBuff->size; 718 // leave pBuff->size untouched 719 // consume data 720 // FIXME can we avoid holding the lock during the copy? 721 memcpy (pBuff->i16, pSrc, pBuff->size); 722 } else { 723 // finish consuming the buffer or consume the buffer in one shot 724 pBuff->size = oldFront->mSize - ap->mBufferQueue.mSizeConsumed; 725 ap->mBufferQueue.mSizeConsumed = 0; 726 727 if (newFront == 728 &ap->mBufferQueue.mArray 729 [ap->mBufferQueue.mNumBuffers + 1]) 730 { 731 newFront = ap->mBufferQueue.mArray; 732 } 733 ap->mBufferQueue.mFront = newFront; 734 735 ap->mBufferQueue.mState.count--; 736 ap->mBufferQueue.mState.playIndex++; 737 738 // consume data 739 // FIXME can we avoid holding the lock during the copy? 740 memcpy (pBuff->i16, pSrc, pBuff->size); 741 742 // data has been consumed, and the buffer queue state has been updated 743 // we will notify the client if applicable 744 callback = ap->mBufferQueue.mCallback; 745 // save callback data 746 callbackPContext = ap->mBufferQueue.mContext; 747 } 748 } else { // empty queue 749 // signal no data available 750 pBuff->size = 0; 751 752 // signal we're at the end of the content, but don't pause (see note in function) 753 audioPlayer_dispatch_headAtEnd_lockPlay(ap, false /*set state to paused?*/, false); 754 755 // signal underflow to prefetch status itf 756 if (IsInterfaceInitialized(&(ap->mObject), MPH_PREFETCHSTATUS)) { 757 audioPlayer_dispatch_prefetchStatus_lockPrefetch(ap, SL_PREFETCHSTATUS_UNDERFLOW, 758 false); 759 } 760 761 // stop the track so it restarts playing faster when new data is enqueued 762 ap->mAudioTrack->stop(); 763 } 764 interface_unlock_exclusive(&ap->mBufferQueue); 765 // notify client 766 if (NULL != callback) { 767 (*callback)(&ap->mBufferQueue.mItf, callbackPContext); 768 } 769 } 770 break; 771 772 case (android::AudioTrack::EVENT_MARKER) : 773 audioTrack_handleMarker_lockPlay(ap); 774 break; 775 776 case (android::AudioTrack::EVENT_NEW_POS) : 777 audioTrack_handleNewPos_lockPlay(ap); 778 break; 779 780 case (android::AudioTrack::EVENT_UNDERRUN) : 781 audioTrack_handleUnderrun_lockPlay(ap); 782 break; 783 784 default: 785 // FIXME where does the notification of SL_PLAYEVENT_HEADMOVING fit? 786 SL_LOGE("Encountered unknown AudioTrack event %d for CAudioPlayer %p", event, 787 (CAudioPlayer *)user); 788 break; 789 } 790} 791 792 793//----------------------------------------------------------------------------- 794SLresult android_audioPlayer_create( 795 CAudioPlayer *pAudioPlayer) { 796 797 const SLDataSource *pAudioSrc = &pAudioPlayer->mDataSource.u.mSource; 798 const SLDataSink *pAudioSnk = &pAudioPlayer->mDataSink.u.mSink; 799 SLresult result = SL_RESULT_SUCCESS; 800 801 //-------------------------------------- 802 // Sink check: 803 // currently only OutputMix sinks are supported 804 // this has already been verified in sles_to_android_CheckAudioPlayerSourceSink 805 // SLuint32 locatorType = *(SLuint32 *)pAudioSnk->pLocator; 806 // if (SL_DATALOCATOR_OUTPUTMIX == locatorType) { 807 // } 808 809 //-------------------------------------- 810 // Source check: 811 SLuint32 locatorType = *(SLuint32 *)pAudioSrc->pLocator; 812 switch (locatorType) { 813 // ----------------------------------- 814 // Buffer Queue to AudioTrack 815 case SL_DATALOCATOR_BUFFERQUEUE: 816 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 817 pAudioPlayer->mAndroidObjType = AUDIOTRACK_PULL; 818 pAudioPlayer->mpLock = new android::Mutex(); 819 pAudioPlayer->mPlaybackRate.mCapabilities = SL_RATEPROP_NOPITCHCORAUDIO; 820 break; 821 // ----------------------------------- 822 // URI or FD to MediaPlayer 823 case SL_DATALOCATOR_URI: 824 case SL_DATALOCATOR_ANDROIDFD: 825 pAudioPlayer->mAndroidObjType = MEDIAPLAYER; 826 pAudioPlayer->mpLock = new android::Mutex(); 827 pAudioPlayer->mPlaybackRate.mCapabilities = SL_RATEPROP_NOPITCHCORAUDIO; 828 break; 829 default: 830 pAudioPlayer->mAndroidObjType = INVALID_TYPE; 831 pAudioPlayer->mpLock = NULL; 832 pAudioPlayer->mPlaybackRate.mCapabilities = 0; 833 result = SL_RESULT_PARAMETER_INVALID; 834 break; 835 } 836 837 pAudioPlayer->mAndroidObjState = ANDROID_UNINITIALIZED; 838 pAudioPlayer->mStreamType = ANDROID_DEFAULT_OUTPUT_STREAM_TYPE; 839 pAudioPlayer->mAudioTrack = NULL; 840#ifndef USE_BACKPORT 841 // no longer needed, as placement new (explicit constructor) already does this 842 // pAudioPlayer->mSfPlayer.clear(); 843#endif 844 845#ifndef USE_BACKPORT 846 pAudioPlayer->mSessionId = android::AudioSystem::newAudioSessionId(); 847#endif 848 849 pAudioPlayer->mAmplFromVolLevel = 1.0f; 850 pAudioPlayer->mAmplFromStereoPos[0] = 1.0f; 851 pAudioPlayer->mAmplFromStereoPos[1] = 1.0f; 852 pAudioPlayer->mDirectLevel = 0; // no attenuation 853 pAudioPlayer->mAmplFromDirectLevel = 1.0f; // matches initial mDirectLevel value 854 855 // initialize interface-specific fields that can be used regardless of whether the interface 856 // is exposed on the AudioPlayer or not 857 // (section no longer applicable, as all previous initializations were the same as the defaults) 858 859 return result; 860 861} 862 863 864//----------------------------------------------------------------------------- 865SLresult android_audioPlayer_setConfig(CAudioPlayer *ap, const SLchar *configKey, 866 const void *pConfigValue, SLuint32 valueSize) { 867 868 SLresult result = SL_RESULT_SUCCESS; 869 870 if (NULL == ap) { 871 result = SL_RESULT_INTERNAL_ERROR; 872 } else if (NULL == pConfigValue) { 873 SL_LOGE(ERROR_CONFIG_NULL_PARAM); 874 result = SL_RESULT_PARAMETER_INVALID; 875 876 } else if(strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_STREAM_TYPE) == 0) { 877 878 // stream type 879 if (KEY_STREAM_TYPE_PARAMSIZE > valueSize) { 880 SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW); 881 result = SL_RESULT_PARAMETER_INVALID; 882 } else { 883 result = audioPlayer_setStreamType(ap, *(SLuint32*)pConfigValue); 884 } 885 886 } else { 887 SL_LOGE(ERROR_CONFIG_UNKNOWN_KEY); 888 result = SL_RESULT_PARAMETER_INVALID; 889 } 890 891 return result; 892} 893 894 895//----------------------------------------------------------------------------- 896SLresult android_audioPlayer_getConfig(CAudioPlayer* ap, const SLchar *configKey, 897 SLuint32* pValueSize, void *pConfigValue) { 898 899 SLresult result = SL_RESULT_SUCCESS; 900 901 if (NULL == ap) { 902 return SL_RESULT_INTERNAL_ERROR; 903 } else if (NULL == pValueSize) { 904 SL_LOGE(ERROR_CONFIG_NULL_PARAM); 905 result = SL_RESULT_PARAMETER_INVALID; 906 907 } else if(strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_STREAM_TYPE) == 0) { 908 909 // stream type 910 if (KEY_STREAM_TYPE_PARAMSIZE > *pValueSize) { 911 SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW); 912 result = SL_RESULT_PARAMETER_INVALID; 913 } else { 914 *pValueSize = KEY_STREAM_TYPE_PARAMSIZE; 915 if (NULL != pConfigValue) { 916 result = audioPlayer_getStreamType(ap, (SLint32*)pConfigValue); 917 } 918 } 919 920 } else { 921 SL_LOGE(ERROR_CONFIG_UNKNOWN_KEY); 922 result = SL_RESULT_PARAMETER_INVALID; 923 } 924 925 return result; 926} 927 928 929//----------------------------------------------------------------------------- 930SLresult android_audioPlayer_realize(CAudioPlayer *pAudioPlayer, SLboolean async) { 931 932 SLresult result = SL_RESULT_SUCCESS; 933 SL_LOGV("Realize pAudioPlayer=%p", pAudioPlayer); 934 935 switch (pAudioPlayer->mAndroidObjType) { 936 //----------------------------------- 937 // AudioTrack 938 case AUDIOTRACK_PULL: 939 { 940 // initialize platform-specific CAudioPlayer fields 941 942 SLDataLocator_BufferQueue *dl_bq = (SLDataLocator_BufferQueue *) 943 pAudioPlayer->mDynamicSource.mDataSource; 944 SLDataFormat_PCM *df_pcm = (SLDataFormat_PCM *) 945 pAudioPlayer->mDynamicSource.mDataSource->pFormat; 946 947 uint32_t sampleRate = sles_to_android_sampleRate(df_pcm->samplesPerSec); 948 949 pAudioPlayer->mAudioTrack = new android::AudioTrack( 950 pAudioPlayer->mStreamType, // streamType 951 sampleRate, // sampleRate 952 sles_to_android_sampleFormat(df_pcm->bitsPerSample), // format 953 sles_to_android_channelMask(df_pcm->numChannels, df_pcm->channelMask),//channel mask 954 0, // frameCount (here min) 955 0, // flags 956 audioTrack_callBack_pullFromBuffQueue, // callback 957 (void *) pAudioPlayer, // user 958 0 // FIXME find appropriate frame count // notificationFrame 959#ifndef USE_BACKPORT 960 , pAudioPlayer->mSessionId 961#endif 962 ); 963 android::status_t status = pAudioPlayer->mAudioTrack->initCheck(); 964 if (status != android::NO_ERROR) { 965 SL_LOGE("AudioTrack::initCheck status %u", status); 966 result = SL_RESULT_CONTENT_UNSUPPORTED; 967 } 968 969 // initialize platform-independent CAudioPlayer fields 970 971 pAudioPlayer->mNumChannels = df_pcm->numChannels; 972 pAudioPlayer->mSampleRateMilliHz = df_pcm->samplesPerSec; // Note: bad field name in SL ES 973 974 pAudioPlayer->mAndroidObjState = ANDROID_READY; 975 } break; 976#ifndef USE_BACKPORT 977 //----------------------------------- 978 // MediaPlayer 979 case MEDIAPLAYER: { 980 object_lock_exclusive(&pAudioPlayer->mObject); 981 982 pAudioPlayer->mAndroidObjState = ANDROID_UNINITIALIZED; 983 pAudioPlayer->mNumChannels = 0; 984 pAudioPlayer->mSampleRateMilliHz = 0; 985 pAudioPlayer->mAudioTrack = NULL; 986 987 AudioPlayback_Parameters app; 988 app.sessionId = pAudioPlayer->mSessionId; 989 app.streamType = pAudioPlayer->mStreamType; 990 app.trackcb = audioTrack_callBack_uri; 991 app.trackcbUser = (void *) pAudioPlayer; 992 993 pAudioPlayer->mSfPlayer = new android::SfPlayer(&app); 994 pAudioPlayer->mSfPlayer->setNotifListener(sfplayer_handlePrefetchEvent, 995 (void*)pAudioPlayer /*notifUSer*/); 996 pAudioPlayer->mSfPlayer->armLooper(); 997 998 object_unlock_exclusive(&pAudioPlayer->mObject); 999 1000 switch (pAudioPlayer->mDataSource.mLocator.mLocatorType) { 1001 case SL_DATALOCATOR_URI: 1002 pAudioPlayer->mSfPlayer->setDataSource( 1003 (const char*)pAudioPlayer->mDataSource.mLocator.mURI.URI); 1004 break; 1005 case SL_DATALOCATOR_ANDROIDFD: { 1006 int64_t offset = (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.offset; 1007 pAudioPlayer->mSfPlayer->setDataSource( 1008 (int)pAudioPlayer->mDataSource.mLocator.mFD.fd, 1009 offset == SL_DATALOCATOR_ANDROIDFD_USE_FILE_SIZE ? 1010 (int64_t)SFPLAYER_FD_FIND_FILE_SIZE : offset, 1011 (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.length); 1012 } break; 1013 default: 1014 SL_LOGE(ERROR_PLAYERREALIZE_UNKNOWN_DATASOURCE_LOCATOR); 1015 break; 1016 } 1017 1018 } break; 1019#endif 1020 default: 1021 SL_LOGE("Unexpected object type %d", pAudioPlayer->mAndroidObjType); 1022 result = SL_RESULT_INTERNAL_ERROR; 1023 break; 1024 } 1025 1026#ifndef USE_BACKPORT 1027 1028 // proceed with effect initialization 1029 // initialize EQ 1030 // FIXME use a table of effect descriptors when adding support for more effects 1031 if (memcmp(SL_IID_EQUALIZER, &pAudioPlayer->mEqualizer.mEqDescriptor.type, 1032 sizeof(effect_uuid_t)) == 0) { 1033 SL_LOGV("Need to initialize EQ for AudioPlayer=%p", pAudioPlayer); 1034 android_eq_init(pAudioPlayer->mSessionId, &pAudioPlayer->mEqualizer); 1035 } 1036 // initialize BassBoost 1037 if (memcmp(SL_IID_BASSBOOST, &pAudioPlayer->mBassBoost.mBassBoostDescriptor.type, 1038 sizeof(effect_uuid_t)) == 0) { 1039 SL_LOGV("Need to initialize BassBoost for AudioPlayer=%p", pAudioPlayer); 1040 android_bb_init(pAudioPlayer->mSessionId, &pAudioPlayer->mBassBoost); 1041 } 1042 // initialize Virtualizer 1043 if (memcmp(SL_IID_VIRTUALIZER, &pAudioPlayer->mVirtualizer.mVirtualizerDescriptor.type, 1044 sizeof(effect_uuid_t)) == 0) { 1045 SL_LOGV("Need to initialize Virtualizer for AudioPlayer=%p", pAudioPlayer); 1046 android_virt_init(pAudioPlayer->mSessionId, &pAudioPlayer->mVirtualizer); 1047 } 1048 1049 // initialize EffectSend 1050 // FIXME initialize EffectSend 1051#endif 1052 1053 return result; 1054} 1055 1056 1057//----------------------------------------------------------------------------- 1058SLresult android_audioPlayer_destroy(CAudioPlayer *pAudioPlayer) { 1059 SLresult result = SL_RESULT_SUCCESS; 1060 SL_LOGV("android_audioPlayer_destroy(%p)", pAudioPlayer); 1061 switch (pAudioPlayer->mAndroidObjType) { 1062 //----------------------------------- 1063 // AudioTrack 1064 case AUDIOTRACK_PULL: 1065 break; 1066#ifndef USE_BACKPORT 1067 //----------------------------------- 1068 // MediaPlayer 1069 case MEDIAPLAYER: 1070 // FIXME might no longer be needed since we call explicit destructor 1071 if (pAudioPlayer->mSfPlayer != 0) { 1072 pAudioPlayer->mSfPlayer.clear(); 1073 } 1074 break; 1075#endif 1076 default: 1077 SL_LOGE("Unexpected object type %d", pAudioPlayer->mAndroidObjType); 1078 result = SL_RESULT_INTERNAL_ERROR; 1079 break; 1080 } 1081 1082 if (pAudioPlayer->mAudioTrack != NULL) { 1083 pAudioPlayer->mAudioTrack->stop(); 1084 delete pAudioPlayer->mAudioTrack; 1085 pAudioPlayer->mAudioTrack = NULL; 1086 } 1087 1088 // FIXME might not be needed 1089 pAudioPlayer->mAndroidObjType = INVALID_TYPE; 1090 1091 // explicit destructor 1092 pAudioPlayer->mSfPlayer.~sp(); 1093 1094 if (pAudioPlayer->mpLock != NULL) { 1095 delete pAudioPlayer->mpLock; 1096 pAudioPlayer->mpLock = NULL; 1097 } 1098 1099 return result; 1100} 1101 1102 1103//----------------------------------------------------------------------------- 1104SLresult android_audioPlayer_setPlayRate(CAudioPlayer *ap, SLpermille rate, bool lockAP) { 1105 SLresult result = SL_RESULT_SUCCESS; 1106 uint32_t contentRate = 0; 1107 switch(ap->mAndroidObjType) { 1108 case AUDIOTRACK_PULL: 1109 case MEDIAPLAYER: { 1110 // get the content sample rate 1111 if (lockAP) { object_lock_shared(&ap->mObject); } 1112 uint32_t contentRate = sles_to_android_sampleRate(ap->mSampleRateMilliHz); 1113 if (lockAP) { object_unlock_shared(&ap->mObject); } 1114 // apply the SL ES playback rate on the AudioTrack as a factor of its content sample rate 1115 if (ap->mAudioTrack != NULL) { 1116 ap->mAudioTrack->setSampleRate(contentRate * (rate/1000.0f)); 1117 } 1118 } 1119 break; 1120 1121 default: 1122 SL_LOGE("Unexpected object type %d", ap->mAndroidObjType); 1123 result = SL_RESULT_INTERNAL_ERROR; 1124 break; 1125 } 1126 return result; 1127} 1128 1129 1130//----------------------------------------------------------------------------- 1131// called with no lock held 1132SLresult android_audioPlayer_setPlaybackRateBehavior(CAudioPlayer *ap, 1133 SLuint32 constraints) { 1134 SLresult result = SL_RESULT_SUCCESS; 1135 switch(ap->mAndroidObjType) { 1136 case AUDIOTRACK_PULL: 1137 case MEDIAPLAYER: 1138 if (constraints != (constraints & SL_RATEPROP_NOPITCHCORAUDIO)) { 1139 result = SL_RESULT_FEATURE_UNSUPPORTED; 1140 } 1141 break; 1142 default: 1143 SL_LOGE("Unexpected object type %d", ap->mAndroidObjType); 1144 result = SL_RESULT_INTERNAL_ERROR; 1145 break; 1146 } 1147 return result; 1148} 1149 1150 1151//----------------------------------------------------------------------------- 1152// called with no lock held 1153SLresult android_audioPlayer_getCapabilitiesOfRate(CAudioPlayer *ap, 1154 SLuint32 *pCapabilities) { 1155 switch(ap->mAndroidObjType) { 1156 case AUDIOTRACK_PULL: 1157 case MEDIAPLAYER: 1158 *pCapabilities = SL_RATEPROP_NOPITCHCORAUDIO; 1159 break; 1160 default: 1161 *pCapabilities = 0; 1162 break; 1163 } 1164 return SL_RESULT_SUCCESS; 1165} 1166 1167 1168//----------------------------------------------------------------------------- 1169void android_audioPlayer_setPlayState(CAudioPlayer *ap, bool lockAP) { 1170 1171 if (lockAP) { object_lock_shared(&ap->mObject); } 1172 SLuint32 playState = ap->mPlay.mState; 1173 AndroidObject_state objState = ap->mAndroidObjState; 1174 if (lockAP) { object_unlock_shared(&ap->mObject); } 1175 1176 switch(ap->mAndroidObjType) { 1177 case AUDIOTRACK_PULL: 1178 switch (playState) { 1179 case SL_PLAYSTATE_STOPPED: 1180 SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_STOPPED"); 1181 if (NULL != ap->mAudioTrack) { 1182 ap->mAudioTrack->stop(); 1183 } 1184 break; 1185 case SL_PLAYSTATE_PAUSED: 1186 SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_PAUSED"); 1187 if (NULL != ap->mAudioTrack) { 1188 ap->mAudioTrack->pause(); 1189 } 1190 break; 1191 case SL_PLAYSTATE_PLAYING: 1192 SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_PLAYING"); 1193 if (NULL != ap->mAudioTrack) { 1194 ap->mAudioTrack->start(); 1195 } 1196 break; 1197 default: 1198 // checked by caller, should not happen 1199 break; 1200 } 1201 break; 1202#ifndef USE_BACKPORT 1203 case MEDIAPLAYER: 1204 switch (playState) { 1205 case SL_PLAYSTATE_STOPPED: { 1206 SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_STOPPED"); 1207 if (ap->mSfPlayer != 0) { 1208 ap->mSfPlayer->stop(); 1209 } 1210 } break; 1211 case SL_PLAYSTATE_PAUSED: { 1212 SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_PAUSED"); 1213 switch(objState) { 1214 case(ANDROID_UNINITIALIZED): 1215 sfplayer_prepare(ap, lockAP); 1216 break; 1217 case(ANDROID_PREPARING): 1218 break; 1219 case(ANDROID_READY): 1220 if (ap->mSfPlayer != 0) { 1221 ap->mSfPlayer->pause(); 1222 } 1223 break; 1224 default: 1225 break; 1226 } 1227 } break; 1228 case SL_PLAYSTATE_PLAYING: { 1229 SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_PLAYING"); 1230 switch(objState) { 1231 case(ANDROID_UNINITIALIZED): 1232 sfplayer_prepare(ap, lockAP); 1233 // fall through 1234 case(ANDROID_PREPARING): 1235 case(ANDROID_READY): 1236 if (ap->mSfPlayer != 0) { 1237 ap->mSfPlayer->play(); 1238 } 1239 break; 1240 default: 1241 break; 1242 } 1243 } break; 1244 1245 default: 1246 // checked by caller, should not happen 1247 break; 1248 } 1249 break; 1250#endif 1251 default: 1252 break; 1253 } 1254} 1255 1256 1257//----------------------------------------------------------------------------- 1258void android_audioPlayer_useEventMask(CAudioPlayer *ap) { 1259 IPlay *pPlayItf = &ap->mPlay; 1260 SLuint32 eventFlags = pPlayItf->mEventFlags; 1261 /*switch(ap->mAndroidObjType) { 1262 case AUDIOTRACK_PULL:*/ 1263 1264 if (NULL == ap->mAudioTrack) { 1265 return; 1266 } 1267 1268 if (eventFlags & SL_PLAYEVENT_HEADATMARKER) { 1269 ap->mAudioTrack->setMarkerPosition((uint32_t)((((int64_t)pPlayItf->mMarkerPosition 1270 * sles_to_android_sampleRate(ap->mSampleRateMilliHz)))/1000)); 1271 } else { 1272 // clear marker 1273 ap->mAudioTrack->setMarkerPosition(0); 1274 } 1275 1276 if (eventFlags & SL_PLAYEVENT_HEADATNEWPOS) { 1277 ap->mAudioTrack->setPositionUpdatePeriod( 1278 (uint32_t)((((int64_t)pPlayItf->mPositionUpdatePeriod 1279 * sles_to_android_sampleRate(ap->mSampleRateMilliHz)))/1000)); 1280 } else { 1281 // clear periodic update 1282 ap->mAudioTrack->setPositionUpdatePeriod(0); 1283 } 1284 1285 if (eventFlags & SL_PLAYEVENT_HEADATEND) { 1286 // nothing to do for SL_PLAYEVENT_HEADATEND, callback event will be checked against mask 1287 } 1288 1289 if (eventFlags & SL_PLAYEVENT_HEADMOVING) { 1290 // FIXME support SL_PLAYEVENT_HEADMOVING 1291 SL_LOGD("[ FIXME: IPlay_SetCallbackEventsMask(SL_PLAYEVENT_HEADMOVING) on an " 1292 "SL_OBJECTID_AUDIOPLAYER to be implemented ]"); 1293 } 1294 if (eventFlags & SL_PLAYEVENT_HEADSTALLED) { 1295 // nothing to do for SL_PLAYEVENT_HEADSTALLED, callback event will be checked against mask 1296 } 1297 1298} 1299 1300 1301//----------------------------------------------------------------------------- 1302SLresult android_audioPlayer_getDuration(IPlay *pPlayItf, SLmillisecond *pDurMsec) { 1303 CAudioPlayer *ap = (CAudioPlayer *)pPlayItf->mThis; 1304 switch(ap->mAndroidObjType) { 1305 case AUDIOTRACK_PULL: 1306 *pDurMsec = SL_TIME_UNKNOWN; 1307 // FIXME if the data source is not a buffer queue, and the audio data is saved in 1308 // shared memory with the mixer process, the duration is the size of the buffer 1309 SL_LOGD("FIXME: android_audioPlayer_getDuration() verify if duration can be retrieved"); 1310 break; 1311#ifndef USE_BACKPORT 1312 case MEDIAPLAYER: { 1313 int64_t durationUsec = SL_TIME_UNKNOWN; 1314 if (ap->mSfPlayer != 0) { 1315 durationUsec = ap->mSfPlayer->getDurationUsec(); 1316 *pDurMsec = durationUsec == -1 ? SL_TIME_UNKNOWN : durationUsec / 1000; 1317 } 1318 } break; 1319#endif 1320 default: 1321 break; 1322 } 1323 return SL_RESULT_SUCCESS; 1324} 1325 1326 1327//----------------------------------------------------------------------------- 1328void android_audioPlayer_getPosition(IPlay *pPlayItf, SLmillisecond *pPosMsec) { 1329 CAudioPlayer *ap = (CAudioPlayer *)pPlayItf->mThis; 1330 switch(ap->mAndroidObjType) { 1331 case AUDIOTRACK_PULL: 1332 if ((ap->mSampleRateMilliHz == 0) || (NULL == ap->mAudioTrack)) { 1333 *pPosMsec = 0; 1334 } else { 1335 uint32_t positionInFrames; 1336 ap->mAudioTrack->getPosition(&positionInFrames); 1337 *pPosMsec = ((int64_t)positionInFrames * 1000) / 1338 sles_to_android_sampleRate(ap->mSampleRateMilliHz); 1339 } 1340 break; 1341 case MEDIAPLAYER: 1342 if (ap->mSfPlayer != 0) { 1343 *pPosMsec = ap->mSfPlayer->getPositionMsec(); 1344 } else { 1345 *pPosMsec = 0; 1346 } 1347 break; 1348 default: 1349 break; 1350 } 1351} 1352 1353 1354//----------------------------------------------------------------------------- 1355void android_audioPlayer_seek(CAudioPlayer *ap, SLmillisecond posMsec) { 1356 1357 switch(ap->mAndroidObjType) { 1358 case AUDIOTRACK_PULL: 1359 break; 1360#ifndef USE_BACKPORT 1361 case MEDIAPLAYER: 1362 if (ap->mSfPlayer != 0) { 1363 ap->mSfPlayer->seek(posMsec); 1364 } 1365 break; 1366#endif 1367 default: 1368 break; 1369 } 1370} 1371 1372 1373//----------------------------------------------------------------------------- 1374void android_audioPlayer_loop(CAudioPlayer *ap, SLboolean loopEnable) { 1375 1376 if ((MEDIAPLAYER == ap->mAndroidObjType) && (ap->mSfPlayer != 0)) { 1377 ap->mSfPlayer->loop((bool)loopEnable); 1378 } 1379} 1380 1381 1382//----------------------------------------------------------------------------- 1383/* 1384 * Mutes or unmutes the Android media framework object associated with the CAudioPlayer that carries 1385 * the IVolume interface. 1386 * Pre-condition: 1387 * if ap->mMute is SL_BOOLEAN_FALSE, a call to this function was preceded by a call 1388 * to android_audioPlayer_volumeUpdate() 1389 */ 1390static void android_audioPlayer_setMute(CAudioPlayer* ap) { 1391 android::AudioTrack *t = NULL; 1392 switch(ap->mAndroidObjType) { 1393 case AUDIOTRACK_PULL: 1394 case MEDIAPLAYER: 1395 t = ap->mAudioTrack; 1396 break; 1397 default: 1398 break; 1399 } 1400 // when unmuting: volume levels have already been updated in IVolume_SetMute 1401 if (NULL != t) { 1402 t->mute(ap->mMute); 1403 } 1404} 1405 1406 1407//----------------------------------------------------------------------------- 1408SLresult android_audioPlayer_volumeUpdate(CAudioPlayer* ap) { 1409 android_audioPlayer_updateStereoVolume(ap); 1410 android_audioPlayer_setMute(ap); 1411 return SL_RESULT_SUCCESS; 1412} 1413 1414 1415//----------------------------------------------------------------------------- 1416void android_audioPlayer_bufferQueue_onRefilled(CAudioPlayer *ap) { 1417 // the AudioTrack associated with the AudioPlayer receiving audio from a PCM buffer 1418 // queue was stopped when the queue become empty, we restart as soon as a new buffer 1419 // has been enqueued since we're in playing state 1420 if (NULL != ap->mAudioTrack) { 1421 ap->mAudioTrack->start(); 1422 } 1423 1424 // when the queue became empty, an underflow on the prefetch status itf was sent. Now the queue 1425 // has received new data, signal it has sufficient data 1426 if (IsInterfaceInitialized(&(ap->mObject), MPH_PREFETCHSTATUS)) { 1427 audioPlayer_dispatch_prefetchStatus_lockPrefetch(ap, SL_PREFETCHSTATUS_SUFFICIENTDATA, 1428 true); 1429 } 1430} 1431 1432 1433//----------------------------------------------------------------------------- 1434/* 1435 * BufferQueue::Clear 1436 */ 1437SLresult android_audioPlayer_bufferQueue_onClear(CAudioPlayer *ap) { 1438 SLresult result = SL_RESULT_SUCCESS; 1439 1440 switch (ap->mAndroidObjType) { 1441 //----------------------------------- 1442 // AudioTrack 1443 case AUDIOTRACK_PULL: 1444 if (NULL != ap->mAudioTrack) { 1445 ap->mAudioTrack->flush(); 1446 } 1447 break; 1448 default: 1449 result = SL_RESULT_INTERNAL_ERROR; 1450 break; 1451 } 1452 1453 return result; 1454} 1455 1456