AudioPlayer_to_android.cpp revision 83ac345e264c1e22b7a2f1a110b2fe92473394ec
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//----------------------------------------------------------------------------- 26// FIXME this method will be absorbed into android_audioPlayer_setPlayState() once 27// bufferqueue and uri/fd playback are moved under the GenericPlayer C++ object 28SLresult aplayer_setPlayState(const android::sp<android::GenericPlayer> &ap, SLuint32 playState, 29 AndroidObject_state* pObjState) { 30 SLresult result = SL_RESULT_SUCCESS; 31 AndroidObject_state objState = *pObjState; 32 33 switch (playState) { 34 case SL_PLAYSTATE_STOPPED: 35 SL_LOGV("setting GenericPlayer to SL_PLAYSTATE_STOPPED"); 36 ap->stop(); 37 break; 38 case SL_PLAYSTATE_PAUSED: 39 SL_LOGV("setting GenericPlayer to SL_PLAYSTATE_PAUSED"); 40 switch(objState) { 41 case ANDROID_UNINITIALIZED: 42 *pObjState = ANDROID_PREPARING; 43 ap->prepare(); 44 break; 45 case ANDROID_PREPARING: 46 break; 47 case ANDROID_READY: 48 ap->pause(); 49 break; 50 default: 51 SL_LOGE(ERROR_PLAYERSETPLAYSTATE_INVALID_OBJECT_STATE_D, playState); 52 result = SL_RESULT_INTERNAL_ERROR; 53 break; 54 } 55 break; 56 case SL_PLAYSTATE_PLAYING: { 57 SL_LOGV("setting GenericPlayer to SL_PLAYSTATE_PLAYING"); 58 switch(objState) { 59 case ANDROID_UNINITIALIZED: 60 *pObjState = ANDROID_PREPARING; 61 ap->prepare(); 62 // intended fall through 63 case ANDROID_PREPARING: 64 // intended fall through 65 case ANDROID_READY: 66 ap->play(); 67 break; 68 default: 69 SL_LOGE(ERROR_PLAYERSETPLAYSTATE_INVALID_OBJECT_STATE_D, playState); 70 result = SL_RESULT_INTERNAL_ERROR; 71 break; 72 } 73 } 74 break; 75 default: 76 // checked by caller, should not happen 77 SL_LOGE(ERROR_SHOULDNT_BE_HERE_S, "aplayer_setPlayState"); 78 result = SL_RESULT_INTERNAL_ERROR; 79 break; 80 } 81 82 return result; 83} 84 85 86//----------------------------------------------------------------------------- 87// Callback associated with a AudioToCbRenderer of an SL ES AudioPlayer that gets its data 88// from a URI or FD, to write the decoded audio data to a buffer queue 89static size_t adecoder_writeToBufferQueue(const uint8_t *data, size_t size, void* user) { 90 size_t sizeConsumed = 0; 91 if (NULL == user) { 92 return sizeConsumed; 93 } 94 SL_LOGD("received %d bytes from decoder", size); 95 CAudioPlayer *ap = (CAudioPlayer *)user; 96 slBufferQueueCallback callback = NULL; 97 void * callbackPContext = NULL; 98 99 // push decoded data to the buffer queue 100 object_lock_exclusive(&ap->mObject); 101 102 if (ap->mBufferQueue.mState.count != 0) { 103 assert(ap->mBufferQueue.mFront != ap->mBufferQueue.mRear); 104 105 BufferHeader *oldFront = ap->mBufferQueue.mFront; 106 BufferHeader *newFront = &oldFront[1]; 107 108 uint8_t *pDest = (uint8_t *)oldFront->mBuffer + ap->mBufferQueue.mSizeConsumed; 109 if (ap->mBufferQueue.mSizeConsumed + size < oldFront->mSize) { 110 // room to consume the whole or rest of the decoded data in one shot 111 ap->mBufferQueue.mSizeConsumed += size; 112 // consume data but no callback to the BufferQueue interface here 113 memcpy (pDest, data, size); 114 sizeConsumed = size; 115 } else { 116 // push as much as possible of the decoded data into the buffer queue 117 sizeConsumed = oldFront->mSize - ap->mBufferQueue.mSizeConsumed; 118 119 // the buffer at the head of the buffer queue is full, update the state 120 ap->mBufferQueue.mSizeConsumed = 0; 121 if (newFront == &ap->mBufferQueue.mArray[ap->mBufferQueue.mNumBuffers + 1]) { 122 newFront = ap->mBufferQueue.mArray; 123 } 124 ap->mBufferQueue.mFront = newFront; 125 126 ap->mBufferQueue.mState.count--; 127 ap->mBufferQueue.mState.playIndex++; 128 // consume data 129 memcpy (pDest, data, sizeConsumed); 130 // data has been copied to the buffer, and the buffer queue state has been updated 131 // we will notify the client if applicable 132 callback = ap->mBufferQueue.mCallback; 133 // save callback data 134 callbackPContext = ap->mBufferQueue.mContext; 135 } 136 137 } else { 138 // no available buffers in the queue to write the decoded data 139 sizeConsumed = 0; 140 } 141 142 object_unlock_exclusive(&ap->mObject); 143 // notify client 144 if (NULL != callback) { 145 (*callback)(&ap->mBufferQueue.mItf, callbackPContext); 146 } 147 148 return sizeConsumed; 149} 150 151//----------------------------------------------------------------------------- 152int android_getMinFrameCount(uint32_t sampleRate) { 153 int afSampleRate; 154 if (android::AudioSystem::getOutputSamplingRate(&afSampleRate, 155 ANDROID_DEFAULT_OUTPUT_STREAM_TYPE) != android::NO_ERROR) { 156 return ANDROID_DEFAULT_AUDIOTRACK_BUFFER_SIZE; 157 } 158 int afFrameCount; 159 if (android::AudioSystem::getOutputFrameCount(&afFrameCount, 160 ANDROID_DEFAULT_OUTPUT_STREAM_TYPE) != android::NO_ERROR) { 161 return ANDROID_DEFAULT_AUDIOTRACK_BUFFER_SIZE; 162 } 163 uint32_t afLatency; 164 if (android::AudioSystem::getOutputLatency(&afLatency, 165 ANDROID_DEFAULT_OUTPUT_STREAM_TYPE) != android::NO_ERROR) { 166 return ANDROID_DEFAULT_AUDIOTRACK_BUFFER_SIZE; 167 } 168 // minimum nb of buffers to cover output latency, given the size of each hardware audio buffer 169 uint32_t minBufCount = afLatency / ((1000 * afFrameCount)/afSampleRate); 170 if (minBufCount < 2) minBufCount = 2; 171 // minimum number of frames to cover output latency at the sample rate of the content 172 return (afFrameCount*sampleRate*minBufCount)/afSampleRate; 173} 174 175 176//----------------------------------------------------------------------------- 177#define LEFT_CHANNEL_MASK 0x1 << 0 178#define RIGHT_CHANNEL_MASK 0x1 << 1 179 180static void android_audioPlayer_updateStereoVolume(CAudioPlayer* ap) { 181 float leftVol = 1.0f, rightVol = 1.0f; 182 183 if (NULL == ap->mAudioTrack) { 184 return; 185 } 186 // should not be used when muted 187 if (SL_BOOLEAN_TRUE == ap->mMute) { 188 return; 189 } 190 191 int channelCount = ap->mNumChannels; 192 193 // mute has priority over solo 194 int leftAudibilityFactor = 1, rightAudibilityFactor = 1; 195 196 if (channelCount >= STEREO_CHANNELS) { 197 if (ap->mMuteMask & LEFT_CHANNEL_MASK) { 198 // left muted 199 leftAudibilityFactor = 0; 200 } else { 201 // left not muted 202 if (ap->mSoloMask & LEFT_CHANNEL_MASK) { 203 // left soloed 204 leftAudibilityFactor = 1; 205 } else { 206 // left not soloed 207 if (ap->mSoloMask & RIGHT_CHANNEL_MASK) { 208 // right solo silences left 209 leftAudibilityFactor = 0; 210 } else { 211 // left and right are not soloed, and left is not muted 212 leftAudibilityFactor = 1; 213 } 214 } 215 } 216 217 if (ap->mMuteMask & RIGHT_CHANNEL_MASK) { 218 // right muted 219 rightAudibilityFactor = 0; 220 } else { 221 // right not muted 222 if (ap->mSoloMask & RIGHT_CHANNEL_MASK) { 223 // right soloed 224 rightAudibilityFactor = 1; 225 } else { 226 // right not soloed 227 if (ap->mSoloMask & LEFT_CHANNEL_MASK) { 228 // left solo silences right 229 rightAudibilityFactor = 0; 230 } else { 231 // left and right are not soloed, and right is not muted 232 rightAudibilityFactor = 1; 233 } 234 } 235 } 236 } 237 238 // compute amplification as the combination of volume level and stereo position 239 // amplification from volume level 240 ap->mAmplFromVolLevel = sles_to_android_amplification(ap->mVolume.mLevel); 241 // amplification from direct level (changed in SLEffectSendtItf and SLAndroidEffectSendItf) 242 leftVol *= ap->mAmplFromVolLevel * ap->mAmplFromDirectLevel; 243 rightVol *= ap->mAmplFromVolLevel * ap->mAmplFromDirectLevel; 244 245 // amplification from stereo position 246 if (ap->mVolume.mEnableStereoPosition) { 247 // panning law depends on number of channels of content: stereo panning vs 2ch. balance 248 if(1 == channelCount) { 249 // stereo panning 250 double theta = (1000+ap->mVolume.mStereoPosition)*M_PI_4/1000.0f; // 0 <= theta <= Pi/2 251 ap->mAmplFromStereoPos[0] = cos(theta); 252 ap->mAmplFromStereoPos[1] = sin(theta); 253 } else { 254 // stereo balance 255 if (ap->mVolume.mStereoPosition > 0) { 256 ap->mAmplFromStereoPos[0] = (1000-ap->mVolume.mStereoPosition)/1000.0f; 257 ap->mAmplFromStereoPos[1] = 1.0f; 258 } else { 259 ap->mAmplFromStereoPos[0] = 1.0f; 260 ap->mAmplFromStereoPos[1] = (1000+ap->mVolume.mStereoPosition)/1000.0f; 261 } 262 } 263 leftVol *= ap->mAmplFromStereoPos[0]; 264 rightVol *= ap->mAmplFromStereoPos[1]; 265 } 266 267 ap->mAudioTrack->setVolume(leftVol * leftAudibilityFactor, rightVol * rightAudibilityFactor); 268 269 // changes in the AudioPlayer volume must be reflected in the send level: 270 // in SLEffectSendItf or in SLAndroidEffectSendItf? 271 // FIXME replace interface test by an internal API once we have one. 272 if (NULL != ap->mEffectSend.mItf) { 273 for (unsigned int i=0 ; i<AUX_MAX ; i++) { 274 if (ap->mEffectSend.mEnableLevels[i].mEnable) { 275 android_fxSend_setSendLevel(ap, 276 ap->mEffectSend.mEnableLevels[i].mSendLevel + ap->mVolume.mLevel); 277 // there's a single aux bus on Android, so we can stop looking once the first 278 // aux effect is found. 279 break; 280 } 281 } 282 } else if (NULL != ap->mAndroidEffectSend.mItf) { 283 android_fxSend_setSendLevel(ap, ap->mAndroidEffectSend.mSendLevel + ap->mVolume.mLevel); 284 } 285} 286 287//----------------------------------------------------------------------------- 288void audioTrack_handleMarker_lockPlay(CAudioPlayer* ap) { 289 //SL_LOGV("received event EVENT_MARKER from AudioTrack"); 290 slPlayCallback callback = NULL; 291 void* callbackPContext = NULL; 292 293 interface_lock_shared(&ap->mPlay); 294 callback = ap->mPlay.mCallback; 295 callbackPContext = ap->mPlay.mContext; 296 interface_unlock_shared(&ap->mPlay); 297 298 if (NULL != callback) { 299 // getting this event implies SL_PLAYEVENT_HEADATMARKER was set in the event mask 300 (*callback)(&ap->mPlay.mItf, callbackPContext, SL_PLAYEVENT_HEADATMARKER); 301 } 302} 303 304//----------------------------------------------------------------------------- 305void audioTrack_handleNewPos_lockPlay(CAudioPlayer* ap) { 306 //SL_LOGV("received event EVENT_NEW_POS from AudioTrack"); 307 slPlayCallback callback = NULL; 308 void* callbackPContext = NULL; 309 310 interface_lock_shared(&ap->mPlay); 311 callback = ap->mPlay.mCallback; 312 callbackPContext = ap->mPlay.mContext; 313 interface_unlock_shared(&ap->mPlay); 314 315 if (NULL != callback) { 316 // getting this event implies SL_PLAYEVENT_HEADATNEWPOS was set in the event mask 317 (*callback)(&ap->mPlay.mItf, callbackPContext, SL_PLAYEVENT_HEADATNEWPOS); 318 } 319} 320 321 322//----------------------------------------------------------------------------- 323void audioTrack_handleUnderrun_lockPlay(CAudioPlayer* ap) { 324 slPlayCallback callback = NULL; 325 void* callbackPContext = NULL; 326 327 interface_lock_shared(&ap->mPlay); 328 callback = ap->mPlay.mCallback; 329 callbackPContext = ap->mPlay.mContext; 330 bool headStalled = (ap->mPlay.mEventFlags & SL_PLAYEVENT_HEADSTALLED) != 0; 331 interface_unlock_shared(&ap->mPlay); 332 333 if ((NULL != callback) && headStalled) { 334 (*callback)(&ap->mPlay.mItf, callbackPContext, SL_PLAYEVENT_HEADSTALLED); 335 } 336} 337 338 339//----------------------------------------------------------------------------- 340/** 341 * post-condition: play state of AudioPlayer is SL_PLAYSTATE_PAUSED if setPlayStateToPaused is true 342 * 343 * note: a conditional flag, setPlayStateToPaused, is used here to specify whether the play state 344 * needs to be changed when the player reaches the end of the content to play. This is 345 * relative to what the specification describes for buffer queues vs the 346 * SL_PLAYEVENT_HEADATEND event. In the OpenSL ES specification 1.0.1: 347 * - section 8.12 SLBufferQueueItf states "In the case of starvation due to insufficient 348 * buffers in the queue, the playing of audio data stops. The player remains in the 349 * SL_PLAYSTATE_PLAYING state." 350 * - section 9.2.31 SL_PLAYEVENT states "SL_PLAYEVENT_HEADATEND Playback head is at the end 351 * of the current content and the player has paused." 352 */ 353void audioPlayer_dispatch_headAtEnd_lockPlay(CAudioPlayer *ap, bool setPlayStateToPaused, 354 bool needToLock) { 355 //SL_LOGV("ap=%p, setPlayStateToPaused=%d, needToLock=%d", ap, setPlayStateToPaused, 356 // needToLock); 357 slPlayCallback playCallback = NULL; 358 void * playContext = NULL; 359 // SLPlayItf callback or no callback? 360 if (needToLock) { 361 interface_lock_exclusive(&ap->mPlay); 362 } 363 if (ap->mPlay.mEventFlags & SL_PLAYEVENT_HEADATEND) { 364 playCallback = ap->mPlay.mCallback; 365 playContext = ap->mPlay.mContext; 366 } 367 if (setPlayStateToPaused) { 368 ap->mPlay.mState = SL_PLAYSTATE_PAUSED; 369 } 370 if (needToLock) { 371 interface_unlock_exclusive(&ap->mPlay); 372 } 373 // callback with no lock held 374 if (NULL != playCallback) { 375 (*playCallback)(&ap->mPlay.mItf, playContext, SL_PLAYEVENT_HEADATEND); 376 } 377 378} 379 380 381//----------------------------------------------------------------------------- 382/** 383 * pre-condition: AudioPlayer has SLPrefetchStatusItf initialized 384 * post-condition: 385 * - ap->mPrefetchStatus.mStatus == status 386 * - the prefetch status callback, if any, has been notified if a change occurred 387 * 388 */ 389void audioPlayer_dispatch_prefetchStatus_lockPrefetch(CAudioPlayer *ap, SLuint32 status, 390 bool needToLock) { 391 slPrefetchCallback prefetchCallback = NULL; 392 void * prefetchContext = NULL; 393 394 if (needToLock) { 395 interface_lock_exclusive(&ap->mPrefetchStatus); 396 } 397 // status change? 398 if (ap->mPrefetchStatus.mStatus != status) { 399 ap->mPrefetchStatus.mStatus = status; 400 // callback or no callback? 401 if (ap->mPrefetchStatus.mCallbackEventsMask & SL_PREFETCHEVENT_STATUSCHANGE) { 402 prefetchCallback = ap->mPrefetchStatus.mCallback; 403 prefetchContext = ap->mPrefetchStatus.mContext; 404 } 405 } 406 if (needToLock) { 407 interface_unlock_exclusive(&ap->mPrefetchStatus); 408 } 409 410 // callback with no lock held 411 if (NULL != prefetchCallback) { 412 (*prefetchCallback)(&ap->mPrefetchStatus.mItf, prefetchContext, status); 413 } 414} 415 416 417//----------------------------------------------------------------------------- 418SLresult audioPlayer_setStreamType(CAudioPlayer* ap, SLint32 type) { 419 SLresult result = SL_RESULT_SUCCESS; 420 SL_LOGV("type %ld", type); 421 422 int newStreamType = ANDROID_DEFAULT_OUTPUT_STREAM_TYPE; 423 switch(type) { 424 case SL_ANDROID_STREAM_VOICE: 425 newStreamType = android::AudioSystem::VOICE_CALL; 426 break; 427 case SL_ANDROID_STREAM_SYSTEM: 428 newStreamType = android::AudioSystem::SYSTEM; 429 break; 430 case SL_ANDROID_STREAM_RING: 431 newStreamType = android::AudioSystem::RING; 432 break; 433 case SL_ANDROID_STREAM_MEDIA: 434 newStreamType = android::AudioSystem::MUSIC; 435 break; 436 case SL_ANDROID_STREAM_ALARM: 437 newStreamType = android::AudioSystem::ALARM; 438 break; 439 case SL_ANDROID_STREAM_NOTIFICATION: 440 newStreamType = android::AudioSystem::NOTIFICATION; 441 break; 442 default: 443 SL_LOGE(ERROR_PLAYERSTREAMTYPE_SET_UNKNOWN_TYPE); 444 result = SL_RESULT_PARAMETER_INVALID; 445 break; 446 } 447 448 // stream type needs to be set before the object is realized 449 // (ap->mAudioTrack is supposed to be NULL until then) 450 if (SL_OBJECT_STATE_UNREALIZED != ap->mObject.mState) { 451 SL_LOGE(ERROR_PLAYERSTREAMTYPE_REALIZED); 452 result = SL_RESULT_PRECONDITIONS_VIOLATED; 453 } else { 454 ap->mStreamType = newStreamType; 455 } 456 457 return result; 458} 459 460 461//----------------------------------------------------------------------------- 462SLresult audioPlayer_getStreamType(CAudioPlayer* ap, SLint32 *pType) { 463 SLresult result = SL_RESULT_SUCCESS; 464 465 switch(ap->mStreamType) { 466 case android::AudioSystem::VOICE_CALL: 467 *pType = SL_ANDROID_STREAM_VOICE; 468 break; 469 case android::AudioSystem::SYSTEM: 470 *pType = SL_ANDROID_STREAM_SYSTEM; 471 break; 472 case android::AudioSystem::RING: 473 *pType = SL_ANDROID_STREAM_RING; 474 break; 475 case android::AudioSystem::DEFAULT: 476 case android::AudioSystem::MUSIC: 477 *pType = SL_ANDROID_STREAM_MEDIA; 478 break; 479 case android::AudioSystem::ALARM: 480 *pType = SL_ANDROID_STREAM_ALARM; 481 break; 482 case android::AudioSystem::NOTIFICATION: 483 *pType = SL_ANDROID_STREAM_NOTIFICATION; 484 break; 485 default: 486 result = SL_RESULT_INTERNAL_ERROR; 487 *pType = SL_ANDROID_STREAM_MEDIA; 488 break; 489 } 490 491 return result; 492} 493 494 495//----------------------------------------------------------------------------- 496void audioPlayer_auxEffectUpdate(CAudioPlayer* ap) { 497 if ((NULL != ap->mAudioTrack) && (ap->mAuxEffect != 0)) { 498 android_fxSend_attach(ap, true, ap->mAuxEffect, ap->mVolume.mLevel + ap->mAuxSendLevel); 499 } 500} 501 502 503//----------------------------------------------------------------------------- 504void audioPlayer_setInvalid(CAudioPlayer* ap) { 505 ap->mAndroidObjType = INVALID_TYPE; 506 ap->mpLock = NULL; 507 ap->mPlaybackRate.mCapabilities = 0; 508} 509 510 511//----------------------------------------------------------------------------- 512/* 513 * returns true if the given data sink is supported by AudioPlayer that don't 514 * play to an OutputMix object, false otherwise 515 * 516 * pre-condition: the locator of the audio sink is not SL_DATALOCATOR_OUTPUTMIX 517 */ 518bool audioPlayer_isSupportedNonOutputMixSink(const SLDataSink* pAudioSink) { 519 bool result = true; 520 const SLuint32 sinkLocatorType = *(SLuint32 *)pAudioSink->pLocator; 521 const SLuint32 sinkFormatType = *(SLuint32 *)pAudioSink->pFormat; 522 523 switch (sinkLocatorType) { 524 525 case SL_DATALOCATOR_BUFFERQUEUE: 526 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 527 if (SL_DATAFORMAT_PCM != sinkFormatType) { 528 SL_LOGE("Unsupported sink format 0x%x, expected SL_DATAFORMAT_PCM", 529 (unsigned)sinkFormatType); 530 result = false; 531 } 532 // it's no use checking the PCM format fields because additional characteristics 533 // such as the number of channels, or sample size are unknown to the player at this stage 534 break; 535 536 default: 537 SL_LOGE("Unsupported sink locator type 0x%x", (unsigned)sinkLocatorType); 538 result = false; 539 break; 540 } 541 542 return result; 543} 544 545 546//----------------------------------------------------------------------------- 547/* 548 * returns the Android object type if the locator type combinations for the source and sinks 549 * are supported by this implementation, INVALID_TYPE otherwise 550 */ 551AndroidObject_type audioPlayer_getAndroidObjectTypeForSourceSink(CAudioPlayer *ap) { 552 553 const SLDataSource *pAudioSrc = &ap->mDataSource.u.mSource; 554 const SLDataSink *pAudioSnk = &ap->mDataSink.u.mSink; 555 const SLuint32 sourceLocatorType = *(SLuint32 *)pAudioSrc->pLocator; 556 const SLuint32 sinkLocatorType = *(SLuint32 *)pAudioSnk->pLocator; 557 AndroidObject_type type = INVALID_TYPE; 558 559 //-------------------------------------- 560 // Sink / source matching check: 561 // the following source / sink combinations are supported 562 // SL_DATALOCATOR_BUFFERQUEUE / SL_DATALOCATOR_OUTPUTMIX 563 // SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE / SL_DATALOCATOR_OUTPUTMIX 564 // SL_DATALOCATOR_URI / SL_DATALOCATOR_OUTPUTMIX 565 // SL_DATALOCATOR_ANDROIDFD / SL_DATALOCATOR_OUTPUTMIX 566 // SL_DATALOCATOR_ANDROIDBUFFERQUEUE / SL_DATALOCATOR_OUTPUTMIX 567 // SL_DATALOCATOR_URI / SL_DATALOCATOR_BUFFERQUEUE 568 // SL_DATALOCATOR_ANDROIDFD / SL_DATALOCATOR_BUFFERQUEUE 569 // SL_DATALOCATOR_URI / SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE 570 // SL_DATALOCATOR_ANDROIDFD / SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE 571 switch (sinkLocatorType) { 572 573 case SL_DATALOCATOR_OUTPUTMIX: { 574 switch (sourceLocatorType) { 575 576 // Buffer Queue to AudioTrack 577 case SL_DATALOCATOR_BUFFERQUEUE: 578 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 579 type = A_PLR_PCM_BQ; 580 break; 581 582 // URI or FD to MediaPlayer 583 case SL_DATALOCATOR_URI: 584 case SL_DATALOCATOR_ANDROIDFD: 585 type = A_PLR_URIFD; 586 break; 587 588 // Android BufferQueue to MediaPlayer (shared memory streaming) 589 case SL_DATALOCATOR_ANDROIDBUFFERQUEUE: 590 type = A_PLR_TS_ABQ; 591 break; 592 593 default: 594 SL_LOGE("Source data locator 0x%x not supported with SL_DATALOCATOR_OUTPUTMIX sink", 595 (unsigned)sourceLocatorType); 596 break; 597 } 598 } 599 break; 600 601 case SL_DATALOCATOR_BUFFERQUEUE: 602 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 603 switch (sourceLocatorType) { 604 605 // URI or FD decoded to PCM in a buffer queue 606 case SL_DATALOCATOR_URI: 607 case SL_DATALOCATOR_ANDROIDFD: 608 type = A_PLR_URIFD_ASQ; 609 break; 610 611 default: 612 SL_LOGE("Source data locator 0x%x not supported with SL_DATALOCATOR_BUFFERQUEUE sink", 613 (unsigned)sourceLocatorType); 614 break; 615 } 616 break; 617 618 default: 619 SL_LOGE("Sink data locator 0x%x not supported", (unsigned)sinkLocatorType); 620 break; 621 } 622 623 return type; 624} 625 626 627//----------------------------------------------------------------------------- 628static void sfplayer_prepare(CAudioPlayer *ap, bool lockAP) { 629 630 if (lockAP) { object_lock_exclusive(&ap->mObject); } 631 ap->mAndroidObjState = ANDROID_PREPARING; 632 if (lockAP) { object_unlock_exclusive(&ap->mObject); } 633 634 if (ap->mSfPlayer != 0) { 635 ap->mSfPlayer->prepare(); 636 } 637} 638 639//----------------------------------------------------------------------------- 640// Callback associated with an SfPlayer of an SL ES AudioPlayer that gets its data 641// from a URI or FD, for prepare and prefetch events 642static void sfplayer_handlePrefetchEvent(int event, int data1, int data2, void* user) { 643 if (NULL == user) { 644 return; 645 } 646 647 CAudioPlayer *ap = (CAudioPlayer *)user; 648 //SL_LOGV("received event %d, data %d from SfAudioPlayer", event, data1); 649 switch(event) { 650 651 case android::GenericPlayer::kEventPrepared: { 652 653 if (PLAYER_SUCCESS != data1) { 654 object_lock_exclusive(&ap->mObject); 655 656 ap->mAudioTrack = NULL; 657 ap->mNumChannels = 0; 658 ap->mSampleRateMilliHz = 0; 659 ap->mAndroidObjState = ANDROID_UNINITIALIZED; 660 661 object_unlock_exclusive(&ap->mObject); 662 663 // SfPlayer prepare() failed prefetching, there is no event in SLPrefetchStatus to 664 // indicate a prefetch error, so we signal it by sending simulataneously two events: 665 // - SL_PREFETCHEVENT_FILLLEVELCHANGE with a level of 0 666 // - SL_PREFETCHEVENT_STATUSCHANGE with a status of SL_PREFETCHSTATUS_UNDERFLOW 667 SL_LOGE(ERROR_PLAYER_PREFETCH_d, data1); 668 if (!IsInterfaceInitialized(&(ap->mObject), MPH_PREFETCHSTATUS)) { 669 break; 670 } 671 672 slPrefetchCallback callback = NULL; 673 void* callbackPContext = NULL; 674 675 interface_lock_exclusive(&ap->mPrefetchStatus); 676 ap->mPrefetchStatus.mLevel = 0; 677 ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_UNDERFLOW; 678 if ((ap->mPrefetchStatus.mCallbackEventsMask & SL_PREFETCHEVENT_FILLLEVELCHANGE) 679 && (ap->mPrefetchStatus.mCallbackEventsMask & SL_PREFETCHEVENT_STATUSCHANGE)) { 680 callback = ap->mPrefetchStatus.mCallback; 681 callbackPContext = ap->mPrefetchStatus.mContext; 682 } 683 interface_unlock_exclusive(&ap->mPrefetchStatus); 684 685 // callback with no lock held 686 if (NULL != callback) { 687 (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext, 688 SL_PREFETCHEVENT_FILLLEVELCHANGE | SL_PREFETCHEVENT_STATUSCHANGE); 689 } 690 691 692 } else { 693 object_lock_exclusive(&ap->mObject); 694 695 if (A_PLR_URIFD == ap->mAndroidObjType) { 696 ap->mAudioTrack = ap->mSfPlayer->getAudioTrack(); 697 ap->mNumChannels = ap->mSfPlayer->getNumChannels(); 698 ap->mSampleRateMilliHz = 699 android_to_sles_sampleRate(ap->mSfPlayer->getSampleRateHz()); 700 ap->mSfPlayer->startPrefetch_async(); 701 // update the new track with the current settings 702 audioPlayer_auxEffectUpdate(ap); 703 android_audioPlayer_useEventMask(ap); 704 android_audioPlayer_volumeUpdate(ap); 705 android_audioPlayer_setPlayRate(ap, ap->mPlaybackRate.mRate, false /*lockAP*/); 706 } else if (A_PLR_PCM_BQ == ap->mAndroidObjType) { 707 ((android::AudioToCbRenderer*)ap->mAPlayer.get())->startPrefetch_async(); 708 } else if (A_PLR_TS_ABQ == ap->mAndroidObjType) { 709 SL_LOGD("Received SfPlayer::kEventPrepared from AVPlayer for CAudioPlayer %p", ap); 710 } 711 712 ap->mAndroidObjState = ANDROID_READY; 713 714 object_unlock_exclusive(&ap->mObject); 715 } 716 717 } 718 break; 719 720 case android::SfPlayer::kEventNewAudioTrack: { 721 object_lock_exclusive(&ap->mObject); 722#if 1 723 // SfPlayer has a new AudioTrack, update our pointer copy and configure the new one before 724 // starting to use it 725#else 726 // SfPlayer has a new AudioTrack, delete the old one and configure the new one before 727 // starting to use it 728 729 if (NULL != ap->mAudioTrack) { 730 delete ap->mAudioTrack; 731 ap->mAudioTrack = NULL; 732 } 733#endif 734 ap->mAudioTrack = ap->mSfPlayer->getAudioTrack(); 735 ap->mNumChannels = ap->mSfPlayer->getNumChannels(); 736 ap->mSampleRateMilliHz = android_to_sles_sampleRate(ap->mSfPlayer->getSampleRateHz()); 737 738 // update the new track with the current settings 739 audioPlayer_auxEffectUpdate(ap); 740 android_audioPlayer_useEventMask(ap); 741 android_audioPlayer_volumeUpdate(ap); 742 android_audioPlayer_setPlayRate(ap, ap->mPlaybackRate.mRate, false /*lockAP*/); 743 744 object_unlock_exclusive(&ap->mObject); 745 } 746 break; 747 748 case android::SfPlayer::kEventPrefetchFillLevelUpdate : { 749 if (!IsInterfaceInitialized(&(ap->mObject), MPH_PREFETCHSTATUS)) { 750 break; 751 } 752 slPrefetchCallback callback = NULL; 753 void* callbackPContext = NULL; 754 755 // SLPrefetchStatusItf callback or no callback? 756 interface_lock_exclusive(&ap->mPrefetchStatus); 757 if (ap->mPrefetchStatus.mCallbackEventsMask & SL_PREFETCHEVENT_FILLLEVELCHANGE) { 758 callback = ap->mPrefetchStatus.mCallback; 759 callbackPContext = ap->mPrefetchStatus.mContext; 760 } 761 ap->mPrefetchStatus.mLevel = (SLpermille)data1; 762 interface_unlock_exclusive(&ap->mPrefetchStatus); 763 764 // callback with no lock held 765 if (NULL != callback) { 766 (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext, 767 SL_PREFETCHEVENT_FILLLEVELCHANGE); 768 } 769 } 770 break; 771 772 case android::SfPlayer::kEventPrefetchStatusChange: { 773 if (!IsInterfaceInitialized(&(ap->mObject), MPH_PREFETCHSTATUS)) { 774 break; 775 } 776 slPrefetchCallback callback = NULL; 777 void* callbackPContext = NULL; 778 779 // SLPrefetchStatusItf callback or no callback? 780 object_lock_exclusive(&ap->mObject); 781 if (ap->mPrefetchStatus.mCallbackEventsMask & SL_PREFETCHEVENT_STATUSCHANGE) { 782 callback = ap->mPrefetchStatus.mCallback; 783 callbackPContext = ap->mPrefetchStatus.mContext; 784 } 785 if (data1 >= android::SfPlayer::kStatusIntermediate) { 786 ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_SUFFICIENTDATA; 787 // FIXME estimate fill level better? 788 ap->mPrefetchStatus.mLevel = 1000; 789 ap->mAndroidObjState = ANDROID_READY; 790 } else if (data1 < android::SfPlayer::kStatusIntermediate) { 791 ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_UNDERFLOW; 792 // FIXME estimate fill level better? 793 ap->mPrefetchStatus.mLevel = 0; 794 } 795 object_unlock_exclusive(&ap->mObject); 796 797 // callback with no lock held 798 if (NULL != callback) { 799 (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext, SL_PREFETCHEVENT_STATUSCHANGE); 800 } 801 } 802 break; 803 804 case android::SfPlayer::kEventEndOfStream: { 805 audioPlayer_dispatch_headAtEnd_lockPlay(ap, true /*set state to paused?*/, true); 806 if ((NULL != ap->mAudioTrack) && (!ap->mSeek.mLoopEnabled)) { 807 ap->mAudioTrack->stop(); 808 } 809 } 810 break; 811 812 default: 813 break; 814 } 815} 816 817 818//----------------------------------------------------------------------------- 819SLresult android_audioPlayer_checkSourceSink(CAudioPlayer *pAudioPlayer) 820{ 821 // verify that the locator types for the source / sink combination is supported 822 pAudioPlayer->mAndroidObjType = audioPlayer_getAndroidObjectTypeForSourceSink(pAudioPlayer); 823 if (INVALID_TYPE == pAudioPlayer->mAndroidObjType) { 824 return SL_RESULT_PARAMETER_INVALID; 825 } 826 827 const SLDataSource *pAudioSrc = &pAudioPlayer->mDataSource.u.mSource; 828 const SLDataSink *pAudioSnk = &pAudioPlayer->mDataSink.u.mSink; 829 830 // format check: 831 const SLuint32 sourceLocatorType = *(SLuint32 *)pAudioSrc->pLocator; 832 const SLuint32 sinkLocatorType = *(SLuint32 *)pAudioSnk->pLocator; 833 const SLuint32 sourceFormatType = *(SLuint32 *)pAudioSrc->pFormat; 834 const SLuint32 sinkFormatType = *(SLuint32 *)pAudioSnk->pFormat; 835 836 switch (sourceLocatorType) { 837 //------------------ 838 // Buffer Queues 839 case SL_DATALOCATOR_BUFFERQUEUE: 840 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 841 { 842 SLDataLocator_BufferQueue *dl_bq = (SLDataLocator_BufferQueue *) pAudioSrc->pLocator; 843 844 // Buffer format 845 switch (sourceFormatType) { 846 // currently only PCM buffer queues are supported, 847 case SL_DATAFORMAT_PCM: { 848 SLDataFormat_PCM *df_pcm = (SLDataFormat_PCM *) pAudioSrc->pFormat; 849 switch (df_pcm->numChannels) { 850 case 1: 851 case 2: 852 break; 853 default: 854 // this should have already been rejected by checkDataFormat 855 SL_LOGE("Cannot create audio player: unsupported " \ 856 "PCM data source with %u channels", (unsigned) df_pcm->numChannels); 857 return SL_RESULT_CONTENT_UNSUPPORTED; 858 } 859 switch (df_pcm->samplesPerSec) { 860 case SL_SAMPLINGRATE_8: 861 case SL_SAMPLINGRATE_11_025: 862 case SL_SAMPLINGRATE_12: 863 case SL_SAMPLINGRATE_16: 864 case SL_SAMPLINGRATE_22_05: 865 case SL_SAMPLINGRATE_24: 866 case SL_SAMPLINGRATE_32: 867 case SL_SAMPLINGRATE_44_1: 868 case SL_SAMPLINGRATE_48: 869 break; 870 case SL_SAMPLINGRATE_64: 871 case SL_SAMPLINGRATE_88_2: 872 case SL_SAMPLINGRATE_96: 873 case SL_SAMPLINGRATE_192: 874 default: 875 SL_LOGE("Cannot create audio player: unsupported sample rate %u milliHz", 876 (unsigned) df_pcm->samplesPerSec); 877 return SL_RESULT_CONTENT_UNSUPPORTED; 878 } 879 switch (df_pcm->bitsPerSample) { 880 case SL_PCMSAMPLEFORMAT_FIXED_8: 881 // FIXME We should support this 882 //SL_LOGE("Cannot create audio player: unsupported 8-bit data"); 883 //return SL_RESULT_CONTENT_UNSUPPORTED; 884 case SL_PCMSAMPLEFORMAT_FIXED_16: 885 break; 886 // others 887 default: 888 // this should have already been rejected by checkDataFormat 889 SL_LOGE("Cannot create audio player: unsupported sample bit depth %lu", 890 (SLuint32)df_pcm->bitsPerSample); 891 return SL_RESULT_CONTENT_UNSUPPORTED; 892 } 893 switch (df_pcm->containerSize) { 894 case 8: 895 case 16: 896 break; 897 // others 898 default: 899 SL_LOGE("Cannot create audio player: unsupported container size %u", 900 (unsigned) df_pcm->containerSize); 901 return SL_RESULT_CONTENT_UNSUPPORTED; 902 } 903 switch (df_pcm->channelMask) { 904 // FIXME needs work 905 default: 906 break; 907 } 908 switch (df_pcm->endianness) { 909 case SL_BYTEORDER_LITTLEENDIAN: 910 break; 911 case SL_BYTEORDER_BIGENDIAN: 912 SL_LOGE("Cannot create audio player: unsupported big-endian byte order"); 913 return SL_RESULT_CONTENT_UNSUPPORTED; 914 // native is proposed but not yet in spec 915 default: 916 SL_LOGE("Cannot create audio player: unsupported byte order %u", 917 (unsigned) df_pcm->endianness); 918 return SL_RESULT_CONTENT_UNSUPPORTED; 919 } 920 } //case SL_DATAFORMAT_PCM 921 break; 922 case SL_DATAFORMAT_MIME: 923 case XA_DATAFORMAT_RAWIMAGE: 924 SL_LOGE("Cannot create audio player with buffer queue data source " 925 "without SL_DATAFORMAT_PCM format"); 926 return SL_RESULT_CONTENT_UNSUPPORTED; 927 default: 928 // invalid data format is detected earlier 929 assert(false); 930 return SL_RESULT_INTERNAL_ERROR; 931 } // switch (sourceFormatType) 932 } // case SL_DATALOCATOR_BUFFERQUEUE or SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE 933 break; 934 //------------------ 935 // URI 936 case SL_DATALOCATOR_URI: 937 { 938 SLDataLocator_URI *dl_uri = (SLDataLocator_URI *) pAudioSrc->pLocator; 939 if (NULL == dl_uri->URI) { 940 return SL_RESULT_PARAMETER_INVALID; 941 } 942 // URI format 943 switch (sourceFormatType) { 944 case SL_DATAFORMAT_MIME: 945 break; 946 case SL_DATAFORMAT_PCM: 947 case XA_DATAFORMAT_RAWIMAGE: 948 SL_LOGE("Cannot create audio player with SL_DATALOCATOR_URI data source without " 949 "SL_DATAFORMAT_MIME format"); 950 return SL_RESULT_CONTENT_UNSUPPORTED; 951 } // switch (sourceFormatType) 952 // decoding format check 953 if ((sinkLocatorType != SL_DATALOCATOR_OUTPUTMIX) && 954 !audioPlayer_isSupportedNonOutputMixSink(pAudioSnk)) { 955 return SL_RESULT_CONTENT_UNSUPPORTED; 956 } 957 } // case SL_DATALOCATOR_URI 958 break; 959 //------------------ 960 // File Descriptor 961 case SL_DATALOCATOR_ANDROIDFD: 962 { 963 // fd is already non null 964 switch (sourceFormatType) { 965 case SL_DATAFORMAT_MIME: 966 break; 967 case SL_DATAFORMAT_PCM: 968 // FIXME implement 969 SL_LOGD("[ FIXME implement PCM FD data sources ]"); 970 break; 971 case XA_DATAFORMAT_RAWIMAGE: 972 SL_LOGE("Cannot create audio player with SL_DATALOCATOR_ANDROIDFD data source " 973 "without SL_DATAFORMAT_MIME or SL_DATAFORMAT_PCM format"); 974 return SL_RESULT_CONTENT_UNSUPPORTED; 975 default: 976 // invalid data format is detected earlier 977 assert(false); 978 return SL_RESULT_INTERNAL_ERROR; 979 } // switch (sourceFormatType) 980 if ((sinkLocatorType != SL_DATALOCATOR_OUTPUTMIX) && 981 !audioPlayer_isSupportedNonOutputMixSink(pAudioSnk)) { 982 return SL_RESULT_CONTENT_UNSUPPORTED; 983 } 984 } // case SL_DATALOCATOR_ANDROIDFD 985 break; 986 //------------------ 987 // Stream 988 case SL_DATALOCATOR_ANDROIDBUFFERQUEUE: 989 { 990 switch (sourceFormatType) { 991 case SL_DATAFORMAT_MIME: 992 { 993 SLDataFormat_MIME *df_mime = (SLDataFormat_MIME *) pAudioSrc->pFormat; 994 if (SL_CONTAINERTYPE_MPEG_TS != df_mime->containerType) { 995 SL_LOGE("Cannot create player with SL_DATALOCATOR_ANDROIDBUFFERQUEUE data source " 996 "that is not fed MPEG-2 TS data"); 997 return SL_RESULT_CONTENT_UNSUPPORTED; 998 } 999 } 1000 break; 1001 default: 1002 SL_LOGE("Cannot create player with SL_DATALOCATOR_ANDROIDBUFFERQUEUE data source " 1003 "without SL_DATAFORMAT_MIME format"); 1004 return SL_RESULT_CONTENT_UNSUPPORTED; 1005 } 1006 } 1007 break; // case SL_DATALOCATOR_ANDROIDBUFFERQUEUE 1008 //------------------ 1009 // Address 1010 case SL_DATALOCATOR_ADDRESS: 1011 case SL_DATALOCATOR_IODEVICE: 1012 case SL_DATALOCATOR_OUTPUTMIX: 1013 case XA_DATALOCATOR_NATIVEDISPLAY: 1014 case SL_DATALOCATOR_MIDIBUFFERQUEUE: 1015 SL_LOGE("Cannot create audio player with data locator type 0x%x", 1016 (unsigned) sourceLocatorType); 1017 return SL_RESULT_CONTENT_UNSUPPORTED; 1018 default: 1019 SL_LOGE("Cannot create audio player with invalid data locator type 0x%x", 1020 (unsigned) sourceLocatorType); 1021 return SL_RESULT_PARAMETER_INVALID; 1022 }// switch (locatorType) 1023 1024 return SL_RESULT_SUCCESS; 1025} 1026 1027 1028 1029//----------------------------------------------------------------------------- 1030static void audioTrack_callBack_uri(int event, void* user, void *info) { 1031 // EVENT_MORE_DATA needs to be handled with priority over the other events 1032 // because it will be called the most often during playback 1033 1034 if (event == android::AudioTrack::EVENT_MORE_DATA) { 1035 //SL_LOGV("received event EVENT_MORE_DATA from AudioTrack"); 1036 // set size to 0 to signal we're not using the callback to write more data 1037 android::AudioTrack::Buffer* pBuff = (android::AudioTrack::Buffer*)info; 1038 pBuff->size = 0; 1039 } else if (NULL != user) { 1040 CAudioPlayer *ap = (CAudioPlayer *)user; 1041 if (!ap->mAudioTrackProtector->enterCb()) { 1042 // it is not safe to enter the callback (the track is about to go away) 1043 return; 1044 } 1045 switch (event) { 1046 case android::AudioTrack::EVENT_MARKER : 1047 audioTrack_handleMarker_lockPlay(ap); 1048 break; 1049 case android::AudioTrack::EVENT_NEW_POS : 1050 audioTrack_handleNewPos_lockPlay(ap); 1051 break; 1052 case android::AudioTrack::EVENT_UNDERRUN : 1053 audioTrack_handleUnderrun_lockPlay(ap); 1054 break; 1055 case android::AudioTrack::EVENT_BUFFER_END : 1056 case android::AudioTrack::EVENT_LOOP_END : 1057 break; 1058 default: 1059 SL_LOGE("Encountered unknown AudioTrack event %d for CAudioPlayer %p", event, 1060 ap); 1061 break; 1062 } 1063 ap->mAudioTrackProtector->exitCb(); 1064 } 1065} 1066 1067//----------------------------------------------------------------------------- 1068// Callback associated with an AudioTrack of an SL ES AudioPlayer that gets its data 1069// from a buffer queue. This will not be called once the AudioTrack has been destroyed. 1070static void audioTrack_callBack_pullFromBuffQueue(int event, void* user, void *info) { 1071 CAudioPlayer *ap = (CAudioPlayer *)user; 1072 1073 if (!ap->mAudioTrackProtector->enterCb()) { 1074 // it is not safe to enter the callback (the track is about to go away) 1075 return; 1076 } 1077 1078 void * callbackPContext = NULL; 1079 switch(event) { 1080 1081 case android::AudioTrack::EVENT_MORE_DATA: { 1082 //SL_LOGV("received event EVENT_MORE_DATA from AudioTrack TID=%d", gettid()); 1083 slBufferQueueCallback callback = NULL; 1084 android::AudioTrack::Buffer* pBuff = (android::AudioTrack::Buffer*)info; 1085 1086 // retrieve data from the buffer queue 1087 interface_lock_exclusive(&ap->mBufferQueue); 1088 1089 if (ap->mBufferQueue.mState.count != 0) { 1090 //SL_LOGV("nbBuffers in queue = %lu",ap->mBufferQueue.mState.count); 1091 assert(ap->mBufferQueue.mFront != ap->mBufferQueue.mRear); 1092 1093 BufferHeader *oldFront = ap->mBufferQueue.mFront; 1094 BufferHeader *newFront = &oldFront[1]; 1095 1096 // FIXME handle 8bit based on buffer format 1097 short *pSrc = (short*)((char *)oldFront->mBuffer 1098 + ap->mBufferQueue.mSizeConsumed); 1099 if (ap->mBufferQueue.mSizeConsumed + pBuff->size < oldFront->mSize) { 1100 // can't consume the whole or rest of the buffer in one shot 1101 ap->mBufferQueue.mSizeConsumed += pBuff->size; 1102 // leave pBuff->size untouched 1103 // consume data 1104 // FIXME can we avoid holding the lock during the copy? 1105 memcpy (pBuff->i16, pSrc, pBuff->size); 1106 } else { 1107 // finish consuming the buffer or consume the buffer in one shot 1108 pBuff->size = oldFront->mSize - ap->mBufferQueue.mSizeConsumed; 1109 ap->mBufferQueue.mSizeConsumed = 0; 1110 1111 if (newFront == 1112 &ap->mBufferQueue.mArray 1113 [ap->mBufferQueue.mNumBuffers + 1]) 1114 { 1115 newFront = ap->mBufferQueue.mArray; 1116 } 1117 ap->mBufferQueue.mFront = newFront; 1118 1119 ap->mBufferQueue.mState.count--; 1120 ap->mBufferQueue.mState.playIndex++; 1121 1122 // consume data 1123 // FIXME can we avoid holding the lock during the copy? 1124 memcpy (pBuff->i16, pSrc, pBuff->size); 1125 1126 // data has been consumed, and the buffer queue state has been updated 1127 // we will notify the client if applicable 1128 callback = ap->mBufferQueue.mCallback; 1129 // save callback data 1130 callbackPContext = ap->mBufferQueue.mContext; 1131 } 1132 } else { // empty queue 1133 // signal no data available 1134 pBuff->size = 0; 1135 1136 // signal we're at the end of the content, but don't pause (see note in function) 1137 audioPlayer_dispatch_headAtEnd_lockPlay(ap, false /*set state to paused?*/, false); 1138 1139 // signal underflow to prefetch status itf 1140 if (IsInterfaceInitialized(&(ap->mObject), MPH_PREFETCHSTATUS)) { 1141 audioPlayer_dispatch_prefetchStatus_lockPrefetch(ap, SL_PREFETCHSTATUS_UNDERFLOW, 1142 false); 1143 } 1144 1145 // stop the track so it restarts playing faster when new data is enqueued 1146 ap->mAudioTrack->stop(); 1147 } 1148 interface_unlock_exclusive(&ap->mBufferQueue); 1149 1150 // notify client 1151 if (NULL != callback) { 1152 (*callback)(&ap->mBufferQueue.mItf, callbackPContext); 1153 } 1154 } 1155 break; 1156 1157 case android::AudioTrack::EVENT_MARKER: 1158 //SL_LOGI("received event EVENT_MARKER from AudioTrack"); 1159 audioTrack_handleMarker_lockPlay(ap); 1160 break; 1161 1162 case android::AudioTrack::EVENT_NEW_POS: 1163 //SL_LOGI("received event EVENT_NEW_POS from AudioTrack"); 1164 audioTrack_handleNewPos_lockPlay(ap); 1165 break; 1166 1167 case android::AudioTrack::EVENT_UNDERRUN: 1168 //SL_LOGI("received event EVENT_UNDERRUN from AudioTrack"); 1169 audioTrack_handleUnderrun_lockPlay(ap); 1170 break; 1171 1172 default: 1173 // FIXME where does the notification of SL_PLAYEVENT_HEADMOVING fit? 1174 SL_LOGE("Encountered unknown AudioTrack event %d for CAudioPlayer %p", event, 1175 (CAudioPlayer *)user); 1176 break; 1177 } 1178 1179 ap->mAudioTrackProtector->exitCb(); 1180} 1181 1182 1183//----------------------------------------------------------------------------- 1184SLresult android_audioPlayer_create(CAudioPlayer *pAudioPlayer) { 1185 1186 SLresult result = SL_RESULT_SUCCESS; 1187 // pAudioPlayer->mAndroidObjType has been set in audioPlayer_getAndroidObjectTypeForSourceSink() 1188 if (INVALID_TYPE == pAudioPlayer->mAndroidObjType) { 1189 audioPlayer_setInvalid(pAudioPlayer); 1190 result = SL_RESULT_PARAMETER_INVALID; 1191 } else { 1192 1193 pAudioPlayer->mpLock = new android::Mutex(); 1194 pAudioPlayer->mAndroidObjState = ANDROID_UNINITIALIZED; 1195 pAudioPlayer->mStreamType = ANDROID_DEFAULT_OUTPUT_STREAM_TYPE; 1196 pAudioPlayer->mAudioTrack = NULL; 1197 // not needed, as placement new (explicit constructor) already does this 1198 // pAudioPlayer->mSfPlayer.clear(); 1199 1200 pAudioPlayer->mAudioTrackProtector = new android::AudioTrackProtector(); 1201 1202 pAudioPlayer->mSessionId = android::AudioSystem::newAudioSessionId(); 1203 1204 pAudioPlayer->mAmplFromVolLevel = 1.0f; 1205 pAudioPlayer->mAmplFromStereoPos[0] = 1.0f; 1206 pAudioPlayer->mAmplFromStereoPos[1] = 1.0f; 1207 pAudioPlayer->mDirectLevel = 0; // no attenuation 1208 pAudioPlayer->mAmplFromDirectLevel = 1.0f; // matches initial mDirectLevel value 1209 pAudioPlayer->mAuxSendLevel = 0; 1210 1211 // initialize interface-specific fields that can be used regardless of whether the 1212 // interface is exposed on the AudioPlayer or not 1213 // (empty section, as all initializations are the same as the defaults) 1214 } 1215 1216 return result; 1217} 1218 1219 1220//----------------------------------------------------------------------------- 1221SLresult android_audioPlayer_setConfig(CAudioPlayer *ap, const SLchar *configKey, 1222 const void *pConfigValue, SLuint32 valueSize) { 1223 1224 SLresult result = SL_RESULT_SUCCESS; 1225 1226 if (NULL == ap) { 1227 result = SL_RESULT_INTERNAL_ERROR; 1228 } else if (NULL == pConfigValue) { 1229 SL_LOGE(ERROR_CONFIG_NULL_PARAM); 1230 result = SL_RESULT_PARAMETER_INVALID; 1231 1232 } else if(strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_STREAM_TYPE) == 0) { 1233 1234 // stream type 1235 if (KEY_STREAM_TYPE_PARAMSIZE > valueSize) { 1236 SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW); 1237 result = SL_RESULT_PARAMETER_INVALID; 1238 } else { 1239 result = audioPlayer_setStreamType(ap, *(SLuint32*)pConfigValue); 1240 } 1241 1242 } else { 1243 SL_LOGE(ERROR_CONFIG_UNKNOWN_KEY); 1244 result = SL_RESULT_PARAMETER_INVALID; 1245 } 1246 1247 return result; 1248} 1249 1250 1251//----------------------------------------------------------------------------- 1252SLresult android_audioPlayer_getConfig(CAudioPlayer* ap, const SLchar *configKey, 1253 SLuint32* pValueSize, void *pConfigValue) { 1254 1255 SLresult result = SL_RESULT_SUCCESS; 1256 1257 if (NULL == ap) { 1258 return SL_RESULT_INTERNAL_ERROR; 1259 } else if (NULL == pValueSize) { 1260 SL_LOGE(ERROR_CONFIG_NULL_PARAM); 1261 result = SL_RESULT_PARAMETER_INVALID; 1262 1263 } else if(strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_STREAM_TYPE) == 0) { 1264 1265 // stream type 1266 if (KEY_STREAM_TYPE_PARAMSIZE > *pValueSize) { 1267 SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW); 1268 result = SL_RESULT_PARAMETER_INVALID; 1269 } else { 1270 *pValueSize = KEY_STREAM_TYPE_PARAMSIZE; 1271 if (NULL != pConfigValue) { 1272 result = audioPlayer_getStreamType(ap, (SLint32*)pConfigValue); 1273 } 1274 } 1275 1276 } else { 1277 SL_LOGE(ERROR_CONFIG_UNKNOWN_KEY); 1278 result = SL_RESULT_PARAMETER_INVALID; 1279 } 1280 1281 return result; 1282} 1283 1284 1285//----------------------------------------------------------------------------- 1286SLresult android_audioPlayer_realize(CAudioPlayer *pAudioPlayer, SLboolean async) { 1287 1288 SLresult result = SL_RESULT_SUCCESS; 1289 SL_LOGV("Realize pAudioPlayer=%p", pAudioPlayer); 1290 1291 switch (pAudioPlayer->mAndroidObjType) { 1292 //----------------------------------- 1293 // AudioTrack 1294 case A_PLR_PCM_BQ: 1295 { 1296 // initialize platform-specific CAudioPlayer fields 1297 1298 SLDataLocator_BufferQueue *dl_bq = (SLDataLocator_BufferQueue *) 1299 pAudioPlayer->mDynamicSource.mDataSource; 1300 SLDataFormat_PCM *df_pcm = (SLDataFormat_PCM *) 1301 pAudioPlayer->mDynamicSource.mDataSource->pFormat; 1302 1303 uint32_t sampleRate = sles_to_android_sampleRate(df_pcm->samplesPerSec); 1304 1305 pAudioPlayer->mAudioTrack = new android::AudioTrack( 1306 pAudioPlayer->mStreamType, // streamType 1307 sampleRate, // sampleRate 1308 sles_to_android_sampleFormat(df_pcm->bitsPerSample), // format 1309 sles_to_android_channelMaskOut(df_pcm->numChannels, df_pcm->channelMask), 1310 //channel mask 1311 0, // frameCount (here min) 1312 0, // flags 1313 audioTrack_callBack_pullFromBuffQueue, // callback 1314 (void *) pAudioPlayer, // user 1315 0 // FIXME find appropriate frame count // notificationFrame 1316 , pAudioPlayer->mSessionId 1317 ); 1318 android::status_t status = pAudioPlayer->mAudioTrack->initCheck(); 1319 if (status != android::NO_ERROR) { 1320 SL_LOGE("AudioTrack::initCheck status %u", status); 1321 result = SL_RESULT_CONTENT_UNSUPPORTED; 1322 } 1323 1324 // initialize platform-independent CAudioPlayer fields 1325 1326 pAudioPlayer->mNumChannels = df_pcm->numChannels; 1327 pAudioPlayer->mSampleRateMilliHz = df_pcm->samplesPerSec; // Note: bad field name in SL ES 1328 1329 pAudioPlayer->mAndroidObjState = ANDROID_READY; 1330 } 1331 break; 1332 //----------------------------------- 1333 // MediaPlayer 1334 case A_PLR_URIFD: { 1335 object_lock_exclusive(&pAudioPlayer->mObject); 1336 1337 pAudioPlayer->mAndroidObjState = ANDROID_UNINITIALIZED; 1338 pAudioPlayer->mNumChannels = 0; 1339 pAudioPlayer->mSampleRateMilliHz = 0; 1340 pAudioPlayer->mAudioTrack = NULL; 1341 1342 AudioPlayback_Parameters app; 1343 app.sessionId = pAudioPlayer->mSessionId; 1344 app.streamType = pAudioPlayer->mStreamType; 1345 app.trackcb = audioTrack_callBack_uri; 1346 app.trackcbUser = (void *) pAudioPlayer; 1347 1348 pAudioPlayer->mSfPlayer = new android::SfPlayer(&app); 1349 pAudioPlayer->mSfPlayer->setNotifListener(sfplayer_handlePrefetchEvent, 1350 (void*)pAudioPlayer /*notifUSer*/); 1351 pAudioPlayer->mSfPlayer->armLooper(); 1352 1353 object_unlock_exclusive(&pAudioPlayer->mObject); 1354 1355 switch (pAudioPlayer->mDataSource.mLocator.mLocatorType) { 1356 case SL_DATALOCATOR_URI: 1357 pAudioPlayer->mSfPlayer->setDataSource( 1358 (const char*)pAudioPlayer->mDataSource.mLocator.mURI.URI); 1359 break; 1360 case SL_DATALOCATOR_ANDROIDFD: { 1361 int64_t offset = (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.offset; 1362 pAudioPlayer->mSfPlayer->setDataSource( 1363 (int)pAudioPlayer->mDataSource.mLocator.mFD.fd, 1364 offset == SL_DATALOCATOR_ANDROIDFD_USE_FILE_SIZE ? 1365 (int64_t)PLAYER_FD_FIND_FILE_SIZE : offset, 1366 (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.length); 1367 } 1368 break; 1369 default: 1370 SL_LOGE(ERROR_PLAYERREALIZE_UNKNOWN_DATASOURCE_LOCATOR); 1371 break; 1372 } 1373 1374 } 1375 break; 1376 //----------------------------------- 1377 // StreamPlayer 1378 case A_PLR_TS_ABQ: { 1379 object_lock_exclusive(&pAudioPlayer->mObject); 1380 1381 android_StreamPlayer_realize_l(pAudioPlayer, sfplayer_handlePrefetchEvent, 1382 (void*)pAudioPlayer); 1383 1384 object_unlock_exclusive(&pAudioPlayer->mObject); 1385 } 1386 break; 1387 //----------------------------------- 1388 // AudioToCbRenderer 1389 case A_PLR_URIFD_ASQ: { 1390 object_lock_exclusive(&pAudioPlayer->mObject); 1391 1392 AudioPlayback_Parameters app; 1393 app.sessionId = pAudioPlayer->mSessionId; 1394 app.streamType = pAudioPlayer->mStreamType; 1395 1396 android::AudioToCbRenderer* decoder = new android::AudioToCbRenderer(&app); 1397 pAudioPlayer->mAPlayer = decoder; 1398 decoder->setDataPushListener(adecoder_writeToBufferQueue, (void*)pAudioPlayer); 1399 decoder->init(sfplayer_handlePrefetchEvent, (void*)pAudioPlayer); 1400 1401 switch (pAudioPlayer->mDataSource.mLocator.mLocatorType) { 1402 case SL_DATALOCATOR_URI: 1403 decoder->setDataSource( 1404 (const char*)pAudioPlayer->mDataSource.mLocator.mURI.URI); 1405 break; 1406 case SL_DATALOCATOR_ANDROIDFD: { 1407 int64_t offset = (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.offset; 1408 decoder->setDataSource( 1409 (int)pAudioPlayer->mDataSource.mLocator.mFD.fd, 1410 offset == SL_DATALOCATOR_ANDROIDFD_USE_FILE_SIZE ? 1411 (int64_t)PLAYER_FD_FIND_FILE_SIZE : offset, 1412 (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.length); 1413 } 1414 break; 1415 default: 1416 SL_LOGE(ERROR_PLAYERREALIZE_UNKNOWN_DATASOURCE_LOCATOR); 1417 break; 1418 } 1419 1420 object_unlock_exclusive(&pAudioPlayer->mObject); 1421 } 1422 break; 1423 //----------------------------------- 1424 default: 1425 SL_LOGE(ERROR_PLAYERREALIZE_UNEXPECTED_OBJECT_TYPE_D, pAudioPlayer->mAndroidObjType); 1426 result = SL_RESULT_INTERNAL_ERROR; 1427 break; 1428 } 1429 1430 1431 // proceed with effect initialization 1432 // initialize EQ 1433 // FIXME use a table of effect descriptors when adding support for more effects 1434 if (memcmp(SL_IID_EQUALIZER, &pAudioPlayer->mEqualizer.mEqDescriptor.type, 1435 sizeof(effect_uuid_t)) == 0) { 1436 SL_LOGV("Need to initialize EQ for AudioPlayer=%p", pAudioPlayer); 1437 android_eq_init(pAudioPlayer->mSessionId, &pAudioPlayer->mEqualizer); 1438 } 1439 // initialize BassBoost 1440 if (memcmp(SL_IID_BASSBOOST, &pAudioPlayer->mBassBoost.mBassBoostDescriptor.type, 1441 sizeof(effect_uuid_t)) == 0) { 1442 SL_LOGV("Need to initialize BassBoost for AudioPlayer=%p", pAudioPlayer); 1443 android_bb_init(pAudioPlayer->mSessionId, &pAudioPlayer->mBassBoost); 1444 } 1445 // initialize Virtualizer 1446 if (memcmp(SL_IID_VIRTUALIZER, &pAudioPlayer->mVirtualizer.mVirtualizerDescriptor.type, 1447 sizeof(effect_uuid_t)) == 0) { 1448 SL_LOGV("Need to initialize Virtualizer for AudioPlayer=%p", pAudioPlayer); 1449 android_virt_init(pAudioPlayer->mSessionId, &pAudioPlayer->mVirtualizer); 1450 } 1451 1452 // initialize EffectSend 1453 // FIXME initialize EffectSend 1454 1455 return result; 1456} 1457 1458 1459//----------------------------------------------------------------------------- 1460/** 1461 * Called with a lock on AudioPlayer 1462 */ 1463SLresult android_audioPlayer_preDestroy(CAudioPlayer *pAudioPlayer) { 1464 SLresult result = SL_RESULT_SUCCESS; 1465 1466 object_unlock_exclusive(&pAudioPlayer->mObject); 1467 if (pAudioPlayer->mAudioTrackProtector != 0) { 1468 pAudioPlayer->mAudioTrackProtector->requestCbExitAndWait(); 1469 } 1470 object_lock_exclusive(&pAudioPlayer->mObject); 1471 1472 return result; 1473} 1474 1475 1476//----------------------------------------------------------------------------- 1477SLresult android_audioPlayer_destroy(CAudioPlayer *pAudioPlayer) { 1478 SLresult result = SL_RESULT_SUCCESS; 1479 SL_LOGV("android_audioPlayer_destroy(%p)", pAudioPlayer); 1480 switch (pAudioPlayer->mAndroidObjType) { 1481 //----------------------------------- 1482 // AudioTrack 1483 case A_PLR_PCM_BQ: 1484 // We own the audio track for PCM buffer queue players 1485 if (pAudioPlayer->mAudioTrack != NULL) { 1486 pAudioPlayer->mAudioTrack->stop(); 1487 delete pAudioPlayer->mAudioTrack; 1488 pAudioPlayer->mAudioTrack = NULL; 1489 } 1490 break; 1491 //----------------------------------- 1492 // MediaPlayer 1493 case A_PLR_URIFD: 1494 // We don't own this audio track, SfPlayer does 1495 pAudioPlayer->mAudioTrack = NULL; 1496 // FIXME might no longer be needed since we call explicit destructor 1497 pAudioPlayer->mSfPlayer.clear(); 1498 break; 1499 //----------------------------------- 1500 // StreamPlayer 1501 case A_PLR_TS_ABQ: // intended fall-through 1502 //----------------------------------- 1503 // AudioToCbRenderer 1504 case A_PLR_URIFD_ASQ: 1505 pAudioPlayer->mAPlayer.clear(); 1506 break; 1507 //----------------------------------- 1508 default: 1509 SL_LOGE(ERROR_PLAYERDESTROY_UNEXPECTED_OBJECT_TYPE_D, pAudioPlayer->mAndroidObjType); 1510 result = SL_RESULT_INTERNAL_ERROR; 1511 break; 1512 } 1513 1514 pAudioPlayer->mAudioTrackProtector.clear(); 1515 1516 // FIXME might not be needed 1517 pAudioPlayer->mAndroidObjType = INVALID_TYPE; 1518 1519 // explicit destructor 1520 pAudioPlayer->mAudioTrackProtector.~sp(); 1521 pAudioPlayer->mSfPlayer.~sp(); 1522 pAudioPlayer->mAuxEffect.~sp(); 1523 pAudioPlayer->mAPlayer.~sp(); 1524 1525 if (pAudioPlayer->mpLock != NULL) { 1526 delete pAudioPlayer->mpLock; 1527 pAudioPlayer->mpLock = NULL; 1528 } 1529 1530 return result; 1531} 1532 1533 1534//----------------------------------------------------------------------------- 1535SLresult android_audioPlayer_setPlayRate(CAudioPlayer *ap, SLpermille rate, bool lockAP) { 1536 SLresult result = SL_RESULT_SUCCESS; 1537 uint32_t contentRate = 0; 1538 switch(ap->mAndroidObjType) { 1539 case A_PLR_PCM_BQ: 1540 case A_PLR_URIFD: { 1541 // get the content sample rate 1542 if (lockAP) { object_lock_shared(&ap->mObject); } 1543 uint32_t contentRate = sles_to_android_sampleRate(ap->mSampleRateMilliHz); 1544 if (lockAP) { object_unlock_shared(&ap->mObject); } 1545 // apply the SL ES playback rate on the AudioTrack as a factor of its content sample rate 1546 if (ap->mAudioTrack != NULL) { 1547 ap->mAudioTrack->setSampleRate(contentRate * (rate/1000.0f)); 1548 } 1549 } 1550 break; 1551 1552 default: 1553 SL_LOGE("Unexpected object type %d", ap->mAndroidObjType); 1554 result = SL_RESULT_INTERNAL_ERROR; 1555 break; 1556 } 1557 return result; 1558} 1559 1560 1561//----------------------------------------------------------------------------- 1562// called with no lock held 1563SLresult android_audioPlayer_setPlaybackRateBehavior(CAudioPlayer *ap, 1564 SLuint32 constraints) { 1565 SLresult result = SL_RESULT_SUCCESS; 1566 switch(ap->mAndroidObjType) { 1567 case A_PLR_PCM_BQ: 1568 case A_PLR_URIFD: 1569 if (constraints != (constraints & SL_RATEPROP_NOPITCHCORAUDIO)) { 1570 result = SL_RESULT_FEATURE_UNSUPPORTED; 1571 } 1572 break; 1573 default: 1574 SL_LOGE("Unexpected object type %d", ap->mAndroidObjType); 1575 result = SL_RESULT_INTERNAL_ERROR; 1576 break; 1577 } 1578 return result; 1579} 1580 1581 1582//----------------------------------------------------------------------------- 1583// called with no lock held 1584SLresult android_audioPlayer_getCapabilitiesOfRate(CAudioPlayer *ap, 1585 SLuint32 *pCapabilities) { 1586 switch(ap->mAndroidObjType) { 1587 case A_PLR_PCM_BQ: 1588 case A_PLR_URIFD: 1589 *pCapabilities = SL_RATEPROP_NOPITCHCORAUDIO; 1590 break; 1591 default: 1592 *pCapabilities = 0; 1593 break; 1594 } 1595 return SL_RESULT_SUCCESS; 1596} 1597 1598 1599//----------------------------------------------------------------------------- 1600void android_audioPlayer_setPlayState(CAudioPlayer *ap, bool lockAP) { 1601 1602 if (lockAP) { object_lock_shared(&ap->mObject); } 1603 SLuint32 playState = ap->mPlay.mState; 1604 AndroidObject_state objState = ap->mAndroidObjState; 1605 if (lockAP) { object_unlock_shared(&ap->mObject); } 1606 1607 switch(ap->mAndroidObjType) { 1608 case A_PLR_PCM_BQ: 1609 switch (playState) { 1610 case SL_PLAYSTATE_STOPPED: 1611 SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_STOPPED"); 1612 if (NULL != ap->mAudioTrack) { 1613 ap->mAudioTrack->stop(); 1614 } 1615 break; 1616 case SL_PLAYSTATE_PAUSED: 1617 SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_PAUSED"); 1618 if (NULL != ap->mAudioTrack) { 1619 ap->mAudioTrack->pause(); 1620 } 1621 break; 1622 case SL_PLAYSTATE_PLAYING: 1623 SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_PLAYING"); 1624 if (NULL != ap->mAudioTrack) { 1625 ap->mAudioTrack->start(); 1626 } 1627 break; 1628 default: 1629 // checked by caller, should not happen 1630 break; 1631 } 1632 break; 1633 1634 case A_PLR_URIFD: 1635 switch (playState) { 1636 case SL_PLAYSTATE_STOPPED: { 1637 SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_STOPPED"); 1638 if (ap->mSfPlayer != 0) { 1639 ap->mSfPlayer->stop(); 1640 } 1641 } 1642 break; 1643 case SL_PLAYSTATE_PAUSED: { 1644 SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_PAUSED"); 1645 switch(objState) { 1646 case ANDROID_UNINITIALIZED: 1647 sfplayer_prepare(ap, lockAP); 1648 break; 1649 case ANDROID_PREPARING: 1650 break; 1651 case ANDROID_READY: 1652 if (ap->mSfPlayer != 0) { 1653 ap->mSfPlayer->pause(); 1654 } 1655 break; 1656 default: 1657 break; 1658 } 1659 } 1660 break; 1661 case SL_PLAYSTATE_PLAYING: { 1662 SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_PLAYING"); 1663 switch(objState) { 1664 case ANDROID_UNINITIALIZED: 1665 sfplayer_prepare(ap, lockAP); 1666 // fall through 1667 case ANDROID_PREPARING: 1668 case ANDROID_READY: 1669 if (ap->mSfPlayer != 0) { 1670 ap->mSfPlayer->play(); 1671 } 1672 break; 1673 default: 1674 break; 1675 } 1676 } 1677 break; 1678 1679 default: 1680 // checked by caller, should not happen 1681 break; 1682 } 1683 break; 1684 1685 case A_PLR_TS_ABQ: // intended fall-through 1686 case A_PLR_URIFD_ASQ: 1687 // FIXME report and use the return code to the lock mechanism, which is where play state 1688 // changes are updated (see object_unlock_exclusive_attributes()) 1689 aplayer_setPlayState(ap->mAPlayer, playState, &(ap->mAndroidObjState)); 1690 break; 1691 default: 1692 SL_LOGE(ERROR_PLAYERSETPLAYSTATE_UNEXPECTED_OBJECT_TYPE_D, ap->mAndroidObjType); 1693 break; 1694 } 1695} 1696 1697 1698//----------------------------------------------------------------------------- 1699void android_audioPlayer_useEventMask(CAudioPlayer *ap) { 1700 IPlay *pPlayItf = &ap->mPlay; 1701 SLuint32 eventFlags = pPlayItf->mEventFlags; 1702 /*switch(ap->mAndroidObjType) { 1703 case A_PLR_PCM_BQ:*/ 1704 1705 if (NULL == ap->mAudioTrack) { 1706 return; 1707 } 1708 1709 if (eventFlags & SL_PLAYEVENT_HEADATMARKER) { 1710 ap->mAudioTrack->setMarkerPosition((uint32_t)((((int64_t)pPlayItf->mMarkerPosition 1711 * sles_to_android_sampleRate(ap->mSampleRateMilliHz)))/1000)); 1712 } else { 1713 // clear marker 1714 ap->mAudioTrack->setMarkerPosition(0); 1715 } 1716 1717 if (eventFlags & SL_PLAYEVENT_HEADATNEWPOS) { 1718 ap->mAudioTrack->setPositionUpdatePeriod( 1719 (uint32_t)((((int64_t)pPlayItf->mPositionUpdatePeriod 1720 * sles_to_android_sampleRate(ap->mSampleRateMilliHz)))/1000)); 1721 } else { 1722 // clear periodic update 1723 ap->mAudioTrack->setPositionUpdatePeriod(0); 1724 } 1725 1726 if (eventFlags & SL_PLAYEVENT_HEADATEND) { 1727 // nothing to do for SL_PLAYEVENT_HEADATEND, callback event will be checked against mask 1728 } 1729 1730 if (eventFlags & SL_PLAYEVENT_HEADMOVING) { 1731 // FIXME support SL_PLAYEVENT_HEADMOVING 1732 SL_LOGD("[ FIXME: IPlay_SetCallbackEventsMask(SL_PLAYEVENT_HEADMOVING) on an " 1733 "SL_OBJECTID_AUDIOPLAYER to be implemented ]"); 1734 } 1735 if (eventFlags & SL_PLAYEVENT_HEADSTALLED) { 1736 // nothing to do for SL_PLAYEVENT_HEADSTALLED, callback event will be checked against mask 1737 } 1738 1739} 1740 1741 1742//----------------------------------------------------------------------------- 1743SLresult android_audioPlayer_getDuration(IPlay *pPlayItf, SLmillisecond *pDurMsec) { 1744 CAudioPlayer *ap = (CAudioPlayer *)pPlayItf->mThis; 1745 switch(ap->mAndroidObjType) { 1746 case A_PLR_PCM_BQ: 1747 *pDurMsec = SL_TIME_UNKNOWN; 1748 // FIXME if the data source is not a buffer queue, and the audio data is saved in 1749 // shared memory with the mixer process, the duration is the size of the buffer 1750 SL_LOGD("FIXME: android_audioPlayer_getDuration() verify if duration can be retrieved"); 1751 break; 1752 case A_PLR_URIFD: { 1753 int64_t durationUsec = SL_TIME_UNKNOWN; 1754 if (ap->mSfPlayer != 0) { 1755 durationUsec = ap->mSfPlayer->getDurationUsec(); 1756 } 1757 *pDurMsec = durationUsec == -1 ? SL_TIME_UNKNOWN : durationUsec / 1000; 1758 } 1759 break; 1760 case A_PLR_TS_ABQ: // intended fall-through 1761 default: 1762 *pDurMsec = SL_TIME_UNKNOWN; 1763 break; 1764 } 1765 return SL_RESULT_SUCCESS; 1766} 1767 1768 1769//----------------------------------------------------------------------------- 1770void android_audioPlayer_getPosition(IPlay *pPlayItf, SLmillisecond *pPosMsec) { 1771 CAudioPlayer *ap = (CAudioPlayer *)pPlayItf->mThis; 1772 switch(ap->mAndroidObjType) { 1773 case A_PLR_PCM_BQ: 1774 if ((ap->mSampleRateMilliHz == 0) || (NULL == ap->mAudioTrack)) { 1775 *pPosMsec = 0; 1776 } else { 1777 uint32_t positionInFrames; 1778 ap->mAudioTrack->getPosition(&positionInFrames); 1779 *pPosMsec = ((int64_t)positionInFrames * 1000) / 1780 sles_to_android_sampleRate(ap->mSampleRateMilliHz); 1781 } 1782 break; 1783 case A_PLR_URIFD: 1784 if (ap->mSfPlayer != 0) { 1785 *pPosMsec = ap->mSfPlayer->getPositionMsec(); 1786 } else { 1787 *pPosMsec = 0; 1788 } 1789 break; 1790 default: 1791 break; 1792 } 1793} 1794 1795 1796//----------------------------------------------------------------------------- 1797void android_audioPlayer_seek(CAudioPlayer *ap, SLmillisecond posMsec) { 1798 1799 switch(ap->mAndroidObjType) { 1800 case A_PLR_PCM_BQ: 1801 break; 1802 case A_PLR_URIFD: 1803 if (ap->mSfPlayer != 0) { 1804 ap->mSfPlayer->seek(posMsec); 1805 } 1806 break; 1807 default: 1808 break; 1809 } 1810} 1811 1812 1813//----------------------------------------------------------------------------- 1814void android_audioPlayer_loop(CAudioPlayer *ap, SLboolean loopEnable) { 1815 1816 if ((A_PLR_URIFD == ap->mAndroidObjType) && (ap->mSfPlayer != 0)) { 1817 ap->mSfPlayer->loop((bool)loopEnable); 1818 } 1819} 1820 1821 1822//----------------------------------------------------------------------------- 1823/* 1824 * Mutes or unmutes the Android media framework object associated with the CAudioPlayer that carries 1825 * the IVolume interface. 1826 * Pre-condition: 1827 * if ap->mMute is SL_BOOLEAN_FALSE, a call to this function was preceded by a call 1828 * to android_audioPlayer_volumeUpdate() 1829 */ 1830static void android_audioPlayer_setMute(CAudioPlayer* ap) { 1831 android::AudioTrack *t = NULL; 1832 switch(ap->mAndroidObjType) { 1833 case A_PLR_PCM_BQ: 1834 case A_PLR_URIFD: 1835 t = ap->mAudioTrack; 1836 break; 1837 default: 1838 break; 1839 } 1840 // when unmuting: volume levels have already been updated in IVolume_SetMute 1841 if (NULL != t) { 1842 t->mute(ap->mMute); 1843 } 1844} 1845 1846 1847//----------------------------------------------------------------------------- 1848SLresult android_audioPlayer_volumeUpdate(CAudioPlayer* ap) { 1849 android_audioPlayer_updateStereoVolume(ap); 1850 android_audioPlayer_setMute(ap); 1851 return SL_RESULT_SUCCESS; 1852} 1853 1854 1855//----------------------------------------------------------------------------- 1856void android_audioPlayer_bufferQueue_onRefilled_l(CAudioPlayer *ap) { 1857 // the AudioTrack associated with the AudioPlayer receiving audio from a PCM buffer 1858 // queue was stopped when the queue become empty, we restart as soon as a new buffer 1859 // has been enqueued since we're in playing state 1860 if (NULL != ap->mAudioTrack) { 1861 ap->mAudioTrack->start(); 1862 } 1863 1864 // when the queue became empty, an underflow on the prefetch status itf was sent. Now the queue 1865 // has received new data, signal it has sufficient data 1866 if (IsInterfaceInitialized(&(ap->mObject), MPH_PREFETCHSTATUS)) { 1867 audioPlayer_dispatch_prefetchStatus_lockPrefetch(ap, SL_PREFETCHSTATUS_SUFFICIENTDATA, 1868 true); 1869 } 1870} 1871 1872 1873//----------------------------------------------------------------------------- 1874/* 1875 * BufferQueue::Clear 1876 */ 1877SLresult android_audioPlayer_bufferQueue_onClear(CAudioPlayer *ap) { 1878 SLresult result = SL_RESULT_SUCCESS; 1879 1880 switch (ap->mAndroidObjType) { 1881 //----------------------------------- 1882 // AudioTrack 1883 case A_PLR_PCM_BQ: 1884 if (NULL != ap->mAudioTrack) { 1885 ap->mAudioTrack->flush(); 1886 } 1887 break; 1888 default: 1889 result = SL_RESULT_INTERNAL_ERROR; 1890 break; 1891 } 1892 1893 return result; 1894} 1895 1896 1897//----------------------------------------------------------------------------- 1898void android_audioPlayer_androidBufferQueue_registerCallback_l(CAudioPlayer *ap) { 1899 if ((ap->mAndroidObjType == A_PLR_TS_ABQ) && (ap->mAPlayer != 0)) { 1900 android::StreamPlayer* splr = static_cast<android::StreamPlayer*>(ap->mAPlayer.get()); 1901 splr->registerQueueCallback( 1902 (const void*)ap, true /*userIsAudioPlayer*/, 1903 ap->mAndroidBufferQueue.mContext, 1904 (const void*)&(ap->mAndroidBufferQueue.mItf)); 1905 } 1906} 1907 1908//----------------------------------------------------------------------------- 1909void android_audioPlayer_androidBufferQueue_clear_l(CAudioPlayer *ap) { 1910 if ((ap->mAndroidObjType == A_PLR_TS_ABQ) && (ap->mAPlayer != 0)) { 1911 android::StreamPlayer* splr = static_cast<android::StreamPlayer*>(ap->mAPlayer.get()); 1912 splr->appClear_l(); 1913 } 1914} 1915 1916void android_audioPlayer_androidBufferQueue_onRefilled_l(CAudioPlayer *ap) { 1917 if ((ap->mAndroidObjType == A_PLR_TS_ABQ) && (ap->mAPlayer != 0)) { 1918 android::StreamPlayer* splr = static_cast<android::StreamPlayer*>(ap->mAPlayer.get()); 1919 splr->queueRefilled_l(); 1920 } 1921} 1922