2 * Copyright (C) 2010 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "sles_allinclusive.h"
18 #include "utils/RefBase.h"
19 #include "android_prompts.h"
21 template class android::KeyedVector<SLuint32, android::AudioEffect* > ;
23 #define KEY_STREAM_TYPE_PARAMSIZE sizeof(SLint32)
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
28 SLresult 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;
34 case SL_PLAYSTATE_STOPPED:
35 SL_LOGV("setting GenericPlayer to SL_PLAYSTATE_STOPPED");
38 case SL_PLAYSTATE_PAUSED:
39 SL_LOGV("setting GenericPlayer to SL_PLAYSTATE_PAUSED");
41 case ANDROID_UNINITIALIZED:
42 *pObjState = ANDROID_PREPARING;
45 case ANDROID_PREPARING:
51 SL_LOGE(ERROR_PLAYERSETPLAYSTATE_INVALID_OBJECT_STATE_D, playState);
52 result = SL_RESULT_INTERNAL_ERROR;
56 case SL_PLAYSTATE_PLAYING: {
57 SL_LOGV("setting GenericPlayer to SL_PLAYSTATE_PLAYING");
59 case ANDROID_UNINITIALIZED:
60 *pObjState = ANDROID_PREPARING;
62 // intended fall through
63 case ANDROID_PREPARING:
64 // intended fall through
69 SL_LOGE(ERROR_PLAYERSETPLAYSTATE_INVALID_OBJECT_STATE_D, playState);
70 result = SL_RESULT_INTERNAL_ERROR;
76 // checked by caller, should not happen
77 SL_LOGE(ERROR_SHOULDNT_BE_HERE_S, "aplayer_setPlayState");
78 result = SL_RESULT_INTERNAL_ERROR;
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
89 static size_t adecoder_writeToBufferQueue(const uint8_t *data, size_t size, void* user) {
90 size_t sizeConsumed = 0;
94 SL_LOGD("received %d bytes from decoder", size);
95 CAudioPlayer *ap = (CAudioPlayer *)user;
96 slBufferQueueCallback callback = NULL;
97 void * callbackPContext = NULL;
99 // push decoded data to the buffer queue
100 object_lock_exclusive(&ap->mObject);
102 if (ap->mBufferQueue.mState.count != 0) {
103 assert(ap->mBufferQueue.mFront != ap->mBufferQueue.mRear);
105 BufferHeader *oldFront = ap->mBufferQueue.mFront;
106 BufferHeader *newFront = &oldFront[1];
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);
116 // push as much as possible of the decoded data into the buffer queue
117 sizeConsumed = oldFront->mSize - ap->mBufferQueue.mSizeConsumed;
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;
124 ap->mBufferQueue.mFront = newFront;
126 ap->mBufferQueue.mState.count--;
127 ap->mBufferQueue.mState.playIndex++;
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;
138 // no available buffers in the queue to write the decoded data
142 object_unlock_exclusive(&ap->mObject);
144 if (NULL != callback) {
145 (*callback)(&ap->mBufferQueue.mItf, callbackPContext);
151 //-----------------------------------------------------------------------------
152 int android_getMinFrameCount(uint32_t sampleRate) {
154 if (android::AudioSystem::getOutputSamplingRate(&afSampleRate,
155 ANDROID_DEFAULT_OUTPUT_STREAM_TYPE) != android::NO_ERROR) {
156 return ANDROID_DEFAULT_AUDIOTRACK_BUFFER_SIZE;
159 if (android::AudioSystem::getOutputFrameCount(&afFrameCount,
160 ANDROID_DEFAULT_OUTPUT_STREAM_TYPE) != android::NO_ERROR) {
161 return ANDROID_DEFAULT_AUDIOTRACK_BUFFER_SIZE;
164 if (android::AudioSystem::getOutputLatency(&afLatency,
165 ANDROID_DEFAULT_OUTPUT_STREAM_TYPE) != android::NO_ERROR) {
166 return ANDROID_DEFAULT_AUDIOTRACK_BUFFER_SIZE;
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;
176 //-----------------------------------------------------------------------------
177 #define LEFT_CHANNEL_MASK 0x1 << 0
178 #define RIGHT_CHANNEL_MASK 0x1 << 1
180 static void android_audioPlayer_updateStereoVolume(CAudioPlayer* ap) {
181 float leftVol = 1.0f, rightVol = 1.0f;
183 if (NULL == ap->mAudioTrack) {
186 // should not be used when muted
187 if (SL_BOOLEAN_TRUE == ap->mMute) {
191 int channelCount = ap->mNumChannels;
193 // mute has priority over solo
194 int leftAudibilityFactor = 1, rightAudibilityFactor = 1;
196 if (channelCount >= STEREO_CHANNELS) {
197 if (ap->mMuteMask & LEFT_CHANNEL_MASK) {
199 leftAudibilityFactor = 0;
202 if (ap->mSoloMask & LEFT_CHANNEL_MASK) {
204 leftAudibilityFactor = 1;
207 if (ap->mSoloMask & RIGHT_CHANNEL_MASK) {
208 // right solo silences left
209 leftAudibilityFactor = 0;
211 // left and right are not soloed, and left is not muted
212 leftAudibilityFactor = 1;
217 if (ap->mMuteMask & RIGHT_CHANNEL_MASK) {
219 rightAudibilityFactor = 0;
222 if (ap->mSoloMask & RIGHT_CHANNEL_MASK) {
224 rightAudibilityFactor = 1;
227 if (ap->mSoloMask & LEFT_CHANNEL_MASK) {
228 // left solo silences right
229 rightAudibilityFactor = 0;
231 // left and right are not soloed, and right is not muted
232 rightAudibilityFactor = 1;
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;
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) {
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);
255 if (ap->mVolume.mStereoPosition > 0) {
256 ap->mAmplFromStereoPos[0] = (1000-ap->mVolume.mStereoPosition)/1000.0f;
257 ap->mAmplFromStereoPos[1] = 1.0f;
259 ap->mAmplFromStereoPos[0] = 1.0f;
260 ap->mAmplFromStereoPos[1] = (1000+ap->mVolume.mStereoPosition)/1000.0f;
263 leftVol *= ap->mAmplFromStereoPos[0];
264 rightVol *= ap->mAmplFromStereoPos[1];
267 ap->mAudioTrack->setVolume(leftVol * leftAudibilityFactor, rightVol * rightAudibilityFactor);
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.
282 } else if (NULL != ap->mAndroidEffectSend.mItf) {
283 android_fxSend_setSendLevel(ap, ap->mAndroidEffectSend.mSendLevel + ap->mVolume.mLevel);
287 //-----------------------------------------------------------------------------
288 void audioTrack_handleMarker_lockPlay(CAudioPlayer* ap) {
289 //SL_LOGV("received event EVENT_MARKER from AudioTrack");
290 slPlayCallback callback = NULL;
291 void* callbackPContext = NULL;
293 interface_lock_shared(&ap->mPlay);
294 callback = ap->mPlay.mCallback;
295 callbackPContext = ap->mPlay.mContext;
296 interface_unlock_shared(&ap->mPlay);
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);
304 //-----------------------------------------------------------------------------
305 void audioTrack_handleNewPos_lockPlay(CAudioPlayer* ap) {
306 //SL_LOGV("received event EVENT_NEW_POS from AudioTrack");
307 slPlayCallback callback = NULL;
308 void* callbackPContext = NULL;
310 interface_lock_shared(&ap->mPlay);
311 callback = ap->mPlay.mCallback;
312 callbackPContext = ap->mPlay.mContext;
313 interface_unlock_shared(&ap->mPlay);
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);
322 //-----------------------------------------------------------------------------
323 void audioTrack_handleUnderrun_lockPlay(CAudioPlayer* ap) {
324 slPlayCallback callback = NULL;
325 void* callbackPContext = NULL;
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);
333 if ((NULL != callback) && headStalled) {
334 (*callback)(&ap->mPlay.mItf, callbackPContext, SL_PLAYEVENT_HEADSTALLED);
339 //-----------------------------------------------------------------------------
341 * post-condition: play state of AudioPlayer is SL_PLAYSTATE_PAUSED if setPlayStateToPaused is true
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."
353 void audioPlayer_dispatch_headAtEnd_lockPlay(CAudioPlayer *ap, bool setPlayStateToPaused,
355 //SL_LOGV("ap=%p, setPlayStateToPaused=%d, needToLock=%d", ap, setPlayStateToPaused,
357 slPlayCallback playCallback = NULL;
358 void * playContext = NULL;
359 // SLPlayItf callback or no callback?
361 interface_lock_exclusive(&ap->mPlay);
363 if (ap->mPlay.mEventFlags & SL_PLAYEVENT_HEADATEND) {
364 playCallback = ap->mPlay.mCallback;
365 playContext = ap->mPlay.mContext;
367 if (setPlayStateToPaused) {
368 ap->mPlay.mState = SL_PLAYSTATE_PAUSED;
371 interface_unlock_exclusive(&ap->mPlay);
373 // callback with no lock held
374 if (NULL != playCallback) {
375 (*playCallback)(&ap->mPlay.mItf, playContext, SL_PLAYEVENT_HEADATEND);
381 //-----------------------------------------------------------------------------
383 * pre-condition: AudioPlayer has SLPrefetchStatusItf initialized
385 * - ap->mPrefetchStatus.mStatus == status
386 * - the prefetch status callback, if any, has been notified if a change occurred
389 void audioPlayer_dispatch_prefetchStatus_lockPrefetch(CAudioPlayer *ap, SLuint32 status,
391 slPrefetchCallback prefetchCallback = NULL;
392 void * prefetchContext = NULL;
395 interface_lock_exclusive(&ap->mPrefetchStatus);
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;
407 interface_unlock_exclusive(&ap->mPrefetchStatus);
410 // callback with no lock held
411 if (NULL != prefetchCallback) {
412 (*prefetchCallback)(&ap->mPrefetchStatus.mItf, prefetchContext, status);
417 //-----------------------------------------------------------------------------
418 SLresult audioPlayer_setStreamType(CAudioPlayer* ap, SLint32 type) {
419 SLresult result = SL_RESULT_SUCCESS;
420 SL_LOGV("type %ld", type);
422 int newStreamType = ANDROID_DEFAULT_OUTPUT_STREAM_TYPE;
424 case SL_ANDROID_STREAM_VOICE:
425 newStreamType = android::AudioSystem::VOICE_CALL;
427 case SL_ANDROID_STREAM_SYSTEM:
428 newStreamType = android::AudioSystem::SYSTEM;
430 case SL_ANDROID_STREAM_RING:
431 newStreamType = android::AudioSystem::RING;
433 case SL_ANDROID_STREAM_MEDIA:
434 newStreamType = android::AudioSystem::MUSIC;
436 case SL_ANDROID_STREAM_ALARM:
437 newStreamType = android::AudioSystem::ALARM;
439 case SL_ANDROID_STREAM_NOTIFICATION:
440 newStreamType = android::AudioSystem::NOTIFICATION;
443 SL_LOGE(ERROR_PLAYERSTREAMTYPE_SET_UNKNOWN_TYPE);
444 result = SL_RESULT_PARAMETER_INVALID;
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;
454 ap->mStreamType = newStreamType;
461 //-----------------------------------------------------------------------------
462 SLresult audioPlayer_getStreamType(CAudioPlayer* ap, SLint32 *pType) {
463 SLresult result = SL_RESULT_SUCCESS;
465 switch(ap->mStreamType) {
466 case android::AudioSystem::VOICE_CALL:
467 *pType = SL_ANDROID_STREAM_VOICE;
469 case android::AudioSystem::SYSTEM:
470 *pType = SL_ANDROID_STREAM_SYSTEM;
472 case android::AudioSystem::RING:
473 *pType = SL_ANDROID_STREAM_RING;
475 case android::AudioSystem::DEFAULT:
476 case android::AudioSystem::MUSIC:
477 *pType = SL_ANDROID_STREAM_MEDIA;
479 case android::AudioSystem::ALARM:
480 *pType = SL_ANDROID_STREAM_ALARM;
482 case android::AudioSystem::NOTIFICATION:
483 *pType = SL_ANDROID_STREAM_NOTIFICATION;
486 result = SL_RESULT_INTERNAL_ERROR;
487 *pType = SL_ANDROID_STREAM_MEDIA;
495 //-----------------------------------------------------------------------------
496 void 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);
503 //-----------------------------------------------------------------------------
504 void audioPlayer_setInvalid(CAudioPlayer* ap) {
505 ap->mAndroidObjType = INVALID_TYPE;
507 ap->mPlaybackRate.mCapabilities = 0;
511 //-----------------------------------------------------------------------------
513 * returns true if the given data sink is supported by AudioPlayer that don't
514 * play to an OutputMix object, false otherwise
516 * pre-condition: the locator of the audio sink is not SL_DATALOCATOR_OUTPUTMIX
518 bool audioPlayer_isSupportedNonOutputMixSink(const SLDataSink* pAudioSink) {
520 const SLuint32 sinkLocatorType = *(SLuint32 *)pAudioSink->pLocator;
521 const SLuint32 sinkFormatType = *(SLuint32 *)pAudioSink->pFormat;
523 switch (sinkLocatorType) {
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);
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
537 SL_LOGE("Unsupported sink locator type 0x%x", (unsigned)sinkLocatorType);
546 //-----------------------------------------------------------------------------
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
551 AndroidObject_type audioPlayer_getAndroidObjectTypeForSourceSink(CAudioPlayer *ap) {
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;
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) {
573 case SL_DATALOCATOR_OUTPUTMIX: {
574 switch (sourceLocatorType) {
576 // Buffer Queue to AudioTrack
577 case SL_DATALOCATOR_BUFFERQUEUE:
578 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
582 // URI or FD to MediaPlayer
583 case SL_DATALOCATOR_URI:
584 case SL_DATALOCATOR_ANDROIDFD:
588 // Android BufferQueue to MediaPlayer (shared memory streaming)
589 case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
594 SL_LOGE("Source data locator 0x%x not supported with SL_DATALOCATOR_OUTPUTMIX sink",
595 (unsigned)sourceLocatorType);
601 case SL_DATALOCATOR_BUFFERQUEUE:
602 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
603 switch (sourceLocatorType) {
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;
612 SL_LOGE("Source data locator 0x%x not supported with SL_DATALOCATOR_BUFFERQUEUE sink",
613 (unsigned)sourceLocatorType);
619 SL_LOGE("Sink data locator 0x%x not supported", (unsigned)sinkLocatorType);
627 //-----------------------------------------------------------------------------
628 static void sfplayer_prepare(CAudioPlayer *ap, bool lockAP) {
630 if (lockAP) { object_lock_exclusive(&ap->mObject); }
631 ap->mAndroidObjState = ANDROID_PREPARING;
632 if (lockAP) { object_unlock_exclusive(&ap->mObject); }
634 if (ap->mSfPlayer != 0) {
635 ap->mSfPlayer->prepare();
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
642 static void sfplayer_handlePrefetchEvent(int event, int data1, int data2, void* user) {
647 CAudioPlayer *ap = (CAudioPlayer *)user;
648 //SL_LOGV("received event %d, data %d from SfAudioPlayer", event, data1);
651 case android::GenericPlayer::kEventPrepared: {
653 if (PLAYER_SUCCESS != data1) {
654 object_lock_exclusive(&ap->mObject);
656 ap->mAudioTrack = NULL;
657 ap->mNumChannels = 0;
658 ap->mSampleRateMilliHz = 0;
659 ap->mAndroidObjState = ANDROID_UNINITIALIZED;
661 object_unlock_exclusive(&ap->mObject);
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)) {
672 slPrefetchCallback callback = NULL;
673 void* callbackPContext = NULL;
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;
683 interface_unlock_exclusive(&ap->mPrefetchStatus);
685 // callback with no lock held
686 if (NULL != callback) {
687 (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext,
688 SL_PREFETCHEVENT_FILLLEVELCHANGE | SL_PREFETCHEVENT_STATUSCHANGE);
693 object_lock_exclusive(&ap->mObject);
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);
712 ap->mAndroidObjState = ANDROID_READY;
714 object_unlock_exclusive(&ap->mObject);
720 case android::SfPlayer::kEventNewAudioTrack: {
721 object_lock_exclusive(&ap->mObject);
723 // SfPlayer has a new AudioTrack, update our pointer copy and configure the new one before
724 // starting to use it
726 // SfPlayer has a new AudioTrack, delete the old one and configure the new one before
727 // starting to use it
729 if (NULL != ap->mAudioTrack) {
730 delete ap->mAudioTrack;
731 ap->mAudioTrack = NULL;
734 ap->mAudioTrack = ap->mSfPlayer->getAudioTrack();
735 ap->mNumChannels = ap->mSfPlayer->getNumChannels();
736 ap->mSampleRateMilliHz = android_to_sles_sampleRate(ap->mSfPlayer->getSampleRateHz());
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*/);
744 object_unlock_exclusive(&ap->mObject);
748 case android::SfPlayer::kEventPrefetchFillLevelUpdate : {
749 if (!IsInterfaceInitialized(&(ap->mObject), MPH_PREFETCHSTATUS)) {
752 slPrefetchCallback callback = NULL;
753 void* callbackPContext = NULL;
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;
761 ap->mPrefetchStatus.mLevel = (SLpermille)data1;
762 interface_unlock_exclusive(&ap->mPrefetchStatus);
764 // callback with no lock held
765 if (NULL != callback) {
766 (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext,
767 SL_PREFETCHEVENT_FILLLEVELCHANGE);
772 case android::SfPlayer::kEventPrefetchStatusChange: {
773 if (!IsInterfaceInitialized(&(ap->mObject), MPH_PREFETCHSTATUS)) {
776 slPrefetchCallback callback = NULL;
777 void* callbackPContext = NULL;
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;
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;
795 object_unlock_exclusive(&ap->mObject);
797 // callback with no lock held
798 if (NULL != callback) {
799 (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext, SL_PREFETCHEVENT_STATUSCHANGE);
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();
818 //-----------------------------------------------------------------------------
819 SLresult android_audioPlayer_checkSourceSink(CAudioPlayer *pAudioPlayer)
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;
827 const SLDataSource *pAudioSrc = &pAudioPlayer->mDataSource.u.mSource;
828 const SLDataSink *pAudioSnk = &pAudioPlayer->mDataSink.u.mSink;
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;
836 switch (sourceLocatorType) {
839 case SL_DATALOCATOR_BUFFERQUEUE:
840 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
842 SLDataLocator_BufferQueue *dl_bq = (SLDataLocator_BufferQueue *) pAudioSrc->pLocator;
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) {
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;
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:
870 case SL_SAMPLINGRATE_64:
871 case SL_SAMPLINGRATE_88_2:
872 case SL_SAMPLINGRATE_96:
873 case SL_SAMPLINGRATE_192:
875 SL_LOGE("Cannot create audio player: unsupported sample rate %u milliHz",
876 (unsigned) df_pcm->samplesPerSec);
877 return SL_RESULT_CONTENT_UNSUPPORTED;
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:
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;
893 switch (df_pcm->containerSize) {
899 SL_LOGE("Cannot create audio player: unsupported container size %u",
900 (unsigned) df_pcm->containerSize);
901 return SL_RESULT_CONTENT_UNSUPPORTED;
903 switch (df_pcm->channelMask) {
908 switch (df_pcm->endianness) {
909 case SL_BYTEORDER_LITTLEENDIAN:
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
916 SL_LOGE("Cannot create audio player: unsupported byte order %u",
917 (unsigned) df_pcm->endianness);
918 return SL_RESULT_CONTENT_UNSUPPORTED;
920 } //case SL_DATAFORMAT_PCM
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;
928 // invalid data format is detected earlier
930 return SL_RESULT_INTERNAL_ERROR;
931 } // switch (sourceFormatType)
932 } // case SL_DATALOCATOR_BUFFERQUEUE or SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE
936 case SL_DATALOCATOR_URI:
938 SLDataLocator_URI *dl_uri = (SLDataLocator_URI *) pAudioSrc->pLocator;
939 if (NULL == dl_uri->URI) {
940 return SL_RESULT_PARAMETER_INVALID;
943 switch (sourceFormatType) {
944 case SL_DATAFORMAT_MIME:
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;
957 } // case SL_DATALOCATOR_URI
961 case SL_DATALOCATOR_ANDROIDFD:
963 // fd is already non null
964 switch (sourceFormatType) {
965 case SL_DATAFORMAT_MIME:
967 case SL_DATAFORMAT_PCM:
969 SL_LOGD("[ FIXME implement PCM FD data sources ]");
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;
976 // invalid data format is detected earlier
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;
984 } // case SL_DATALOCATOR_ANDROIDFD
988 case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
990 switch (sourceFormatType) {
991 case SL_DATAFORMAT_MIME:
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;
1002 SL_LOGE("Cannot create player with SL_DATALOCATOR_ANDROIDBUFFERQUEUE data source "
1003 "without SL_DATAFORMAT_MIME format");
1004 return SL_RESULT_CONTENT_UNSUPPORTED;
1007 break; // case SL_DATALOCATOR_ANDROIDBUFFERQUEUE
1008 //------------------
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;
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)
1024 return SL_RESULT_SUCCESS;
1029 //-----------------------------------------------------------------------------
1030 static 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 if (event == android::AudioTrack::EVENT_MORE_DATA) {
1034 //SL_LOGV("received event EVENT_MORE_DATA from AudioTrack");
1035 // set size to 0 to signal we're not using the callback to write more data
1036 android::AudioTrack::Buffer* pBuff = (android::AudioTrack::Buffer*)info;
1038 } else if (NULL != user) {
1040 case android::AudioTrack::EVENT_MARKER :
1041 audioTrack_handleMarker_lockPlay((CAudioPlayer *)user);
1043 case android::AudioTrack::EVENT_NEW_POS :
1044 audioTrack_handleNewPos_lockPlay((CAudioPlayer *)user);
1046 case android::AudioTrack::EVENT_UNDERRUN :
1047 audioTrack_handleUnderrun_lockPlay((CAudioPlayer *)user);
1049 case android::AudioTrack::EVENT_BUFFER_END :
1050 case android::AudioTrack::EVENT_LOOP_END :
1053 SL_LOGE("Encountered unknown AudioTrack event %d for CAudioPlayer %p", event,
1054 (CAudioPlayer *)user);
1060 //-----------------------------------------------------------------------------
1061 // Callback associated with an AudioTrack of an SL ES AudioPlayer that gets its data
1062 // from a buffer queue.
1063 static void audioTrack_callBack_pullFromBuffQueue(int event, void* user, void *info) {
1064 CAudioPlayer *ap = (CAudioPlayer *)user;
1065 void * callbackPContext = NULL;
1068 case android::AudioTrack::EVENT_MORE_DATA: {
1069 //SL_LOGV("received event EVENT_MORE_DATA from AudioTrack");
1070 slBufferQueueCallback callback = NULL;
1071 android::AudioTrack::Buffer* pBuff = (android::AudioTrack::Buffer*)info;
1072 // retrieve data from the buffer queue
1073 interface_lock_exclusive(&ap->mBufferQueue);
1074 if (ap->mBufferQueue.mState.count != 0) {
1075 //SL_LOGV("nbBuffers in queue = %lu",ap->mBufferQueue.mState.count);
1076 assert(ap->mBufferQueue.mFront != ap->mBufferQueue.mRear);
1078 BufferHeader *oldFront = ap->mBufferQueue.mFront;
1079 BufferHeader *newFront = &oldFront[1];
1081 // FIXME handle 8bit based on buffer format
1082 short *pSrc = (short*)((char *)oldFront->mBuffer
1083 + ap->mBufferQueue.mSizeConsumed);
1084 if (ap->mBufferQueue.mSizeConsumed + pBuff->size < oldFront->mSize) {
1085 // can't consume the whole or rest of the buffer in one shot
1086 ap->mBufferQueue.mSizeConsumed += pBuff->size;
1087 // leave pBuff->size untouched
1089 // FIXME can we avoid holding the lock during the copy?
1090 memcpy (pBuff->i16, pSrc, pBuff->size);
1092 // finish consuming the buffer or consume the buffer in one shot
1093 pBuff->size = oldFront->mSize - ap->mBufferQueue.mSizeConsumed;
1094 ap->mBufferQueue.mSizeConsumed = 0;
1097 &ap->mBufferQueue.mArray
1098 [ap->mBufferQueue.mNumBuffers + 1])
1100 newFront = ap->mBufferQueue.mArray;
1102 ap->mBufferQueue.mFront = newFront;
1104 ap->mBufferQueue.mState.count--;
1105 ap->mBufferQueue.mState.playIndex++;
1108 // FIXME can we avoid holding the lock during the copy?
1109 memcpy (pBuff->i16, pSrc, pBuff->size);
1111 // data has been consumed, and the buffer queue state has been updated
1112 // we will notify the client if applicable
1113 callback = ap->mBufferQueue.mCallback;
1114 // save callback data
1115 callbackPContext = ap->mBufferQueue.mContext;
1117 } else { // empty queue
1118 // signal no data available
1121 // signal we're at the end of the content, but don't pause (see note in function)
1122 audioPlayer_dispatch_headAtEnd_lockPlay(ap, false /*set state to paused?*/, false);
1124 // signal underflow to prefetch status itf
1125 if (IsInterfaceInitialized(&(ap->mObject), MPH_PREFETCHSTATUS)) {
1126 audioPlayer_dispatch_prefetchStatus_lockPrefetch(ap, SL_PREFETCHSTATUS_UNDERFLOW,
1130 // stop the track so it restarts playing faster when new data is enqueued
1131 ap->mAudioTrack->stop();
1133 interface_unlock_exclusive(&ap->mBufferQueue);
1135 if (NULL != callback) {
1136 (*callback)(&ap->mBufferQueue.mItf, callbackPContext);
1141 case android::AudioTrack::EVENT_MARKER:
1142 audioTrack_handleMarker_lockPlay(ap);
1145 case android::AudioTrack::EVENT_NEW_POS:
1146 audioTrack_handleNewPos_lockPlay(ap);
1149 case android::AudioTrack::EVENT_UNDERRUN:
1150 audioTrack_handleUnderrun_lockPlay(ap);
1154 // FIXME where does the notification of SL_PLAYEVENT_HEADMOVING fit?
1155 SL_LOGE("Encountered unknown AudioTrack event %d for CAudioPlayer %p", event,
1156 (CAudioPlayer *)user);
1162 //-----------------------------------------------------------------------------
1163 SLresult android_audioPlayer_create(CAudioPlayer *pAudioPlayer) {
1165 SLresult result = SL_RESULT_SUCCESS;
1166 // pAudioPlayer->mAndroidObjType has been set in audioPlayer_getAndroidObjectTypeForSourceSink()
1167 if (INVALID_TYPE == pAudioPlayer->mAndroidObjType) {
1168 audioPlayer_setInvalid(pAudioPlayer);
1169 result = SL_RESULT_PARAMETER_INVALID;
1172 pAudioPlayer->mpLock = new android::Mutex();
1173 pAudioPlayer->mAndroidObjState = ANDROID_UNINITIALIZED;
1174 pAudioPlayer->mStreamType = ANDROID_DEFAULT_OUTPUT_STREAM_TYPE;
1175 pAudioPlayer->mAudioTrack = NULL;
1176 // not needed, as placement new (explicit constructor) already does this
1177 // pAudioPlayer->mSfPlayer.clear();
1179 pAudioPlayer->mSessionId = android::AudioSystem::newAudioSessionId();
1181 pAudioPlayer->mAmplFromVolLevel = 1.0f;
1182 pAudioPlayer->mAmplFromStereoPos[0] = 1.0f;
1183 pAudioPlayer->mAmplFromStereoPos[1] = 1.0f;
1184 pAudioPlayer->mDirectLevel = 0; // no attenuation
1185 pAudioPlayer->mAmplFromDirectLevel = 1.0f; // matches initial mDirectLevel value
1186 pAudioPlayer->mAuxSendLevel = 0;
1188 // initialize interface-specific fields that can be used regardless of whether the
1189 // interface is exposed on the AudioPlayer or not
1190 // (empty section, as all initializations are the same as the defaults)
1197 //-----------------------------------------------------------------------------
1198 SLresult android_audioPlayer_setConfig(CAudioPlayer *ap, const SLchar *configKey,
1199 const void *pConfigValue, SLuint32 valueSize) {
1201 SLresult result = SL_RESULT_SUCCESS;
1204 result = SL_RESULT_INTERNAL_ERROR;
1205 } else if (NULL == pConfigValue) {
1206 SL_LOGE(ERROR_CONFIG_NULL_PARAM);
1207 result = SL_RESULT_PARAMETER_INVALID;
1209 } else if(strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_STREAM_TYPE) == 0) {
1212 if (KEY_STREAM_TYPE_PARAMSIZE > valueSize) {
1213 SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW);
1214 result = SL_RESULT_PARAMETER_INVALID;
1216 result = audioPlayer_setStreamType(ap, *(SLuint32*)pConfigValue);
1220 SL_LOGE(ERROR_CONFIG_UNKNOWN_KEY);
1221 result = SL_RESULT_PARAMETER_INVALID;
1228 //-----------------------------------------------------------------------------
1229 SLresult android_audioPlayer_getConfig(CAudioPlayer* ap, const SLchar *configKey,
1230 SLuint32* pValueSize, void *pConfigValue) {
1232 SLresult result = SL_RESULT_SUCCESS;
1235 return SL_RESULT_INTERNAL_ERROR;
1236 } else if (NULL == pValueSize) {
1237 SL_LOGE(ERROR_CONFIG_NULL_PARAM);
1238 result = SL_RESULT_PARAMETER_INVALID;
1240 } else if(strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_STREAM_TYPE) == 0) {
1243 if (KEY_STREAM_TYPE_PARAMSIZE > *pValueSize) {
1244 SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW);
1245 result = SL_RESULT_PARAMETER_INVALID;
1247 *pValueSize = KEY_STREAM_TYPE_PARAMSIZE;
1248 if (NULL != pConfigValue) {
1249 result = audioPlayer_getStreamType(ap, (SLint32*)pConfigValue);
1254 SL_LOGE(ERROR_CONFIG_UNKNOWN_KEY);
1255 result = SL_RESULT_PARAMETER_INVALID;
1262 //-----------------------------------------------------------------------------
1263 SLresult android_audioPlayer_realize(CAudioPlayer *pAudioPlayer, SLboolean async) {
1265 SLresult result = SL_RESULT_SUCCESS;
1266 SL_LOGV("Realize pAudioPlayer=%p", pAudioPlayer);
1268 switch (pAudioPlayer->mAndroidObjType) {
1269 //-----------------------------------
1273 // initialize platform-specific CAudioPlayer fields
1275 SLDataLocator_BufferQueue *dl_bq = (SLDataLocator_BufferQueue *)
1276 pAudioPlayer->mDynamicSource.mDataSource;
1277 SLDataFormat_PCM *df_pcm = (SLDataFormat_PCM *)
1278 pAudioPlayer->mDynamicSource.mDataSource->pFormat;
1280 uint32_t sampleRate = sles_to_android_sampleRate(df_pcm->samplesPerSec);
1282 pAudioPlayer->mAudioTrack = new android::AudioTrack(
1283 pAudioPlayer->mStreamType, // streamType
1284 sampleRate, // sampleRate
1285 sles_to_android_sampleFormat(df_pcm->bitsPerSample), // format
1286 sles_to_android_channelMaskOut(df_pcm->numChannels, df_pcm->channelMask),
1288 0, // frameCount (here min)
1290 audioTrack_callBack_pullFromBuffQueue, // callback
1291 (void *) pAudioPlayer, // user
1292 0 // FIXME find appropriate frame count // notificationFrame
1293 , pAudioPlayer->mSessionId
1295 android::status_t status = pAudioPlayer->mAudioTrack->initCheck();
1296 if (status != android::NO_ERROR) {
1297 SL_LOGE("AudioTrack::initCheck status %u", status);
1298 result = SL_RESULT_CONTENT_UNSUPPORTED;
1301 // initialize platform-independent CAudioPlayer fields
1303 pAudioPlayer->mNumChannels = df_pcm->numChannels;
1304 pAudioPlayer->mSampleRateMilliHz = df_pcm->samplesPerSec; // Note: bad field name in SL ES
1306 pAudioPlayer->mAndroidObjState = ANDROID_READY;
1309 //-----------------------------------
1312 object_lock_exclusive(&pAudioPlayer->mObject);
1314 pAudioPlayer->mAndroidObjState = ANDROID_UNINITIALIZED;
1315 pAudioPlayer->mNumChannels = 0;
1316 pAudioPlayer->mSampleRateMilliHz = 0;
1317 pAudioPlayer->mAudioTrack = NULL;
1319 AudioPlayback_Parameters app;
1320 app.sessionId = pAudioPlayer->mSessionId;
1321 app.streamType = pAudioPlayer->mStreamType;
1322 app.trackcb = audioTrack_callBack_uri;
1323 app.trackcbUser = (void *) pAudioPlayer;
1325 pAudioPlayer->mSfPlayer = new android::SfPlayer(&app);
1326 pAudioPlayer->mSfPlayer->setNotifListener(sfplayer_handlePrefetchEvent,
1327 (void*)pAudioPlayer /*notifUSer*/);
1328 pAudioPlayer->mSfPlayer->armLooper();
1330 object_unlock_exclusive(&pAudioPlayer->mObject);
1332 switch (pAudioPlayer->mDataSource.mLocator.mLocatorType) {
1333 case SL_DATALOCATOR_URI:
1334 pAudioPlayer->mSfPlayer->setDataSource(
1335 (const char*)pAudioPlayer->mDataSource.mLocator.mURI.URI);
1337 case SL_DATALOCATOR_ANDROIDFD: {
1338 int64_t offset = (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.offset;
1339 pAudioPlayer->mSfPlayer->setDataSource(
1340 (int)pAudioPlayer->mDataSource.mLocator.mFD.fd,
1341 offset == SL_DATALOCATOR_ANDROIDFD_USE_FILE_SIZE ?
1342 (int64_t)PLAYER_FD_FIND_FILE_SIZE : offset,
1343 (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.length);
1347 SL_LOGE(ERROR_PLAYERREALIZE_UNKNOWN_DATASOURCE_LOCATOR);
1353 //-----------------------------------
1355 case A_PLR_TS_ABQ: {
1356 object_lock_exclusive(&pAudioPlayer->mObject);
1358 android_StreamPlayer_realize_l(pAudioPlayer, sfplayer_handlePrefetchEvent,
1359 (void*)pAudioPlayer);
1361 object_unlock_exclusive(&pAudioPlayer->mObject);
1364 //-----------------------------------
1365 // AudioToCbRenderer
1366 case A_PLR_URIFD_ASQ: {
1367 object_lock_exclusive(&pAudioPlayer->mObject);
1369 AudioPlayback_Parameters app;
1370 app.sessionId = pAudioPlayer->mSessionId;
1371 app.streamType = pAudioPlayer->mStreamType;
1373 android::AudioToCbRenderer* decoder = new android::AudioToCbRenderer(&app);
1374 pAudioPlayer->mAPlayer = decoder;
1375 decoder->setDataPushListener(adecoder_writeToBufferQueue, (void*)pAudioPlayer);
1376 decoder->init(sfplayer_handlePrefetchEvent, (void*)pAudioPlayer);
1378 switch (pAudioPlayer->mDataSource.mLocator.mLocatorType) {
1379 case SL_DATALOCATOR_URI:
1380 decoder->setDataSource(
1381 (const char*)pAudioPlayer->mDataSource.mLocator.mURI.URI);
1383 case SL_DATALOCATOR_ANDROIDFD: {
1384 int64_t offset = (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.offset;
1385 decoder->setDataSource(
1386 (int)pAudioPlayer->mDataSource.mLocator.mFD.fd,
1387 offset == SL_DATALOCATOR_ANDROIDFD_USE_FILE_SIZE ?
1388 (int64_t)PLAYER_FD_FIND_FILE_SIZE : offset,
1389 (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.length);
1393 SL_LOGE(ERROR_PLAYERREALIZE_UNKNOWN_DATASOURCE_LOCATOR);
1397 object_unlock_exclusive(&pAudioPlayer->mObject);
1400 //-----------------------------------
1402 SL_LOGE(ERROR_PLAYERREALIZE_UNEXPECTED_OBJECT_TYPE_D, pAudioPlayer->mAndroidObjType);
1403 result = SL_RESULT_INTERNAL_ERROR;
1408 // proceed with effect initialization
1410 // FIXME use a table of effect descriptors when adding support for more effects
1411 if (memcmp(SL_IID_EQUALIZER, &pAudioPlayer->mEqualizer.mEqDescriptor.type,
1412 sizeof(effect_uuid_t)) == 0) {
1413 SL_LOGV("Need to initialize EQ for AudioPlayer=%p", pAudioPlayer);
1414 android_eq_init(pAudioPlayer->mSessionId, &pAudioPlayer->mEqualizer);
1416 // initialize BassBoost
1417 if (memcmp(SL_IID_BASSBOOST, &pAudioPlayer->mBassBoost.mBassBoostDescriptor.type,
1418 sizeof(effect_uuid_t)) == 0) {
1419 SL_LOGV("Need to initialize BassBoost for AudioPlayer=%p", pAudioPlayer);
1420 android_bb_init(pAudioPlayer->mSessionId, &pAudioPlayer->mBassBoost);
1422 // initialize Virtualizer
1423 if (memcmp(SL_IID_VIRTUALIZER, &pAudioPlayer->mVirtualizer.mVirtualizerDescriptor.type,
1424 sizeof(effect_uuid_t)) == 0) {
1425 SL_LOGV("Need to initialize Virtualizer for AudioPlayer=%p", pAudioPlayer);
1426 android_virt_init(pAudioPlayer->mSessionId, &pAudioPlayer->mVirtualizer);
1429 // initialize EffectSend
1430 // FIXME initialize EffectSend
1436 //-----------------------------------------------------------------------------
1437 SLresult android_audioPlayer_destroy(CAudioPlayer *pAudioPlayer) {
1438 SLresult result = SL_RESULT_SUCCESS;
1439 SL_LOGV("android_audioPlayer_destroy(%p)", pAudioPlayer);
1440 switch (pAudioPlayer->mAndroidObjType) {
1441 //-----------------------------------
1444 // We own the audio track for PCM buffer queue players
1445 if (pAudioPlayer->mAudioTrack != NULL) {
1446 pAudioPlayer->mAudioTrack->stop();
1447 delete pAudioPlayer->mAudioTrack;
1448 pAudioPlayer->mAudioTrack = NULL;
1451 //-----------------------------------
1454 // We don't own this audio track, SfPlayer does
1455 pAudioPlayer->mAudioTrack = NULL;
1456 // FIXME might no longer be needed since we call explicit destructor
1457 pAudioPlayer->mSfPlayer.clear();
1459 //-----------------------------------
1461 case A_PLR_TS_ABQ: // intended fall-through
1462 //-----------------------------------
1463 // AudioToCbRenderer
1464 case A_PLR_URIFD_ASQ:
1465 pAudioPlayer->mAPlayer.clear();
1467 //-----------------------------------
1469 SL_LOGE(ERROR_PLAYERDESTROY_UNEXPECTED_OBJECT_TYPE_D, pAudioPlayer->mAndroidObjType);
1470 result = SL_RESULT_INTERNAL_ERROR;
1474 // FIXME might not be needed
1475 pAudioPlayer->mAndroidObjType = INVALID_TYPE;
1477 // explicit destructor
1478 pAudioPlayer->mSfPlayer.~sp();
1479 pAudioPlayer->mAuxEffect.~sp();
1480 pAudioPlayer->mAPlayer.~sp();
1482 if (pAudioPlayer->mpLock != NULL) {
1483 delete pAudioPlayer->mpLock;
1484 pAudioPlayer->mpLock = NULL;
1491 //-----------------------------------------------------------------------------
1492 SLresult android_audioPlayer_setPlayRate(CAudioPlayer *ap, SLpermille rate, bool lockAP) {
1493 SLresult result = SL_RESULT_SUCCESS;
1494 uint32_t contentRate = 0;
1495 switch(ap->mAndroidObjType) {
1498 // get the content sample rate
1499 if (lockAP) { object_lock_shared(&ap->mObject); }
1500 uint32_t contentRate = sles_to_android_sampleRate(ap->mSampleRateMilliHz);
1501 if (lockAP) { object_unlock_shared(&ap->mObject); }
1502 // apply the SL ES playback rate on the AudioTrack as a factor of its content sample rate
1503 if (ap->mAudioTrack != NULL) {
1504 ap->mAudioTrack->setSampleRate(contentRate * (rate/1000.0f));
1510 SL_LOGE("Unexpected object type %d", ap->mAndroidObjType);
1511 result = SL_RESULT_INTERNAL_ERROR;
1518 //-----------------------------------------------------------------------------
1519 // called with no lock held
1520 SLresult android_audioPlayer_setPlaybackRateBehavior(CAudioPlayer *ap,
1521 SLuint32 constraints) {
1522 SLresult result = SL_RESULT_SUCCESS;
1523 switch(ap->mAndroidObjType) {
1526 if (constraints != (constraints & SL_RATEPROP_NOPITCHCORAUDIO)) {
1527 result = SL_RESULT_FEATURE_UNSUPPORTED;
1531 SL_LOGE("Unexpected object type %d", ap->mAndroidObjType);
1532 result = SL_RESULT_INTERNAL_ERROR;
1539 //-----------------------------------------------------------------------------
1540 // called with no lock held
1541 SLresult android_audioPlayer_getCapabilitiesOfRate(CAudioPlayer *ap,
1542 SLuint32 *pCapabilities) {
1543 switch(ap->mAndroidObjType) {
1546 *pCapabilities = SL_RATEPROP_NOPITCHCORAUDIO;
1552 return SL_RESULT_SUCCESS;
1556 //-----------------------------------------------------------------------------
1557 void android_audioPlayer_setPlayState(CAudioPlayer *ap, bool lockAP) {
1559 if (lockAP) { object_lock_shared(&ap->mObject); }
1560 SLuint32 playState = ap->mPlay.mState;
1561 AndroidObject_state objState = ap->mAndroidObjState;
1562 if (lockAP) { object_unlock_shared(&ap->mObject); }
1564 switch(ap->mAndroidObjType) {
1566 switch (playState) {
1567 case SL_PLAYSTATE_STOPPED:
1568 SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_STOPPED");
1569 if (NULL != ap->mAudioTrack) {
1570 ap->mAudioTrack->stop();
1573 case SL_PLAYSTATE_PAUSED:
1574 SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_PAUSED");
1575 if (NULL != ap->mAudioTrack) {
1576 ap->mAudioTrack->pause();
1579 case SL_PLAYSTATE_PLAYING:
1580 SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_PLAYING");
1581 if (NULL != ap->mAudioTrack) {
1582 ap->mAudioTrack->start();
1586 // checked by caller, should not happen
1592 switch (playState) {
1593 case SL_PLAYSTATE_STOPPED: {
1594 SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_STOPPED");
1595 if (ap->mSfPlayer != 0) {
1596 ap->mSfPlayer->stop();
1600 case SL_PLAYSTATE_PAUSED: {
1601 SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_PAUSED");
1603 case ANDROID_UNINITIALIZED:
1604 sfplayer_prepare(ap, lockAP);
1606 case ANDROID_PREPARING:
1609 if (ap->mSfPlayer != 0) {
1610 ap->mSfPlayer->pause();
1618 case SL_PLAYSTATE_PLAYING: {
1619 SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_PLAYING");
1621 case ANDROID_UNINITIALIZED:
1622 sfplayer_prepare(ap, lockAP);
1624 case ANDROID_PREPARING:
1626 if (ap->mSfPlayer != 0) {
1627 ap->mSfPlayer->play();
1637 // checked by caller, should not happen
1642 case A_PLR_TS_ABQ: // intended fall-through
1643 case A_PLR_URIFD_ASQ:
1644 // FIXME report and use the return code to the lock mechanism, which is where play state
1645 // changes are updated (see object_unlock_exclusive_attributes())
1646 aplayer_setPlayState(ap->mAPlayer, playState, &(ap->mAndroidObjState));
1649 SL_LOGE(ERROR_PLAYERSETPLAYSTATE_UNEXPECTED_OBJECT_TYPE_D, ap->mAndroidObjType);
1655 //-----------------------------------------------------------------------------
1656 void android_audioPlayer_useEventMask(CAudioPlayer *ap) {
1657 IPlay *pPlayItf = &ap->mPlay;
1658 SLuint32 eventFlags = pPlayItf->mEventFlags;
1659 /*switch(ap->mAndroidObjType) {
1660 case A_PLR_PCM_BQ:*/
1662 if (NULL == ap->mAudioTrack) {
1666 if (eventFlags & SL_PLAYEVENT_HEADATMARKER) {
1667 ap->mAudioTrack->setMarkerPosition((uint32_t)((((int64_t)pPlayItf->mMarkerPosition
1668 * sles_to_android_sampleRate(ap->mSampleRateMilliHz)))/1000));
1671 ap->mAudioTrack->setMarkerPosition(0);
1674 if (eventFlags & SL_PLAYEVENT_HEADATNEWPOS) {
1675 ap->mAudioTrack->setPositionUpdatePeriod(
1676 (uint32_t)((((int64_t)pPlayItf->mPositionUpdatePeriod
1677 * sles_to_android_sampleRate(ap->mSampleRateMilliHz)))/1000));
1679 // clear periodic update
1680 ap->mAudioTrack->setPositionUpdatePeriod(0);
1683 if (eventFlags & SL_PLAYEVENT_HEADATEND) {
1684 // nothing to do for SL_PLAYEVENT_HEADATEND, callback event will be checked against mask
1687 if (eventFlags & SL_PLAYEVENT_HEADMOVING) {
1688 // FIXME support SL_PLAYEVENT_HEADMOVING
1689 SL_LOGD("[ FIXME: IPlay_SetCallbackEventsMask(SL_PLAYEVENT_HEADMOVING) on an "
1690 "SL_OBJECTID_AUDIOPLAYER to be implemented ]");
1692 if (eventFlags & SL_PLAYEVENT_HEADSTALLED) {
1693 // nothing to do for SL_PLAYEVENT_HEADSTALLED, callback event will be checked against mask
1699 //-----------------------------------------------------------------------------
1700 SLresult android_audioPlayer_getDuration(IPlay *pPlayItf, SLmillisecond *pDurMsec) {
1701 CAudioPlayer *ap = (CAudioPlayer *)pPlayItf->mThis;
1702 switch(ap->mAndroidObjType) {
1704 *pDurMsec = SL_TIME_UNKNOWN;
1705 // FIXME if the data source is not a buffer queue, and the audio data is saved in
1706 // shared memory with the mixer process, the duration is the size of the buffer
1707 SL_LOGD("FIXME: android_audioPlayer_getDuration() verify if duration can be retrieved");
1710 int64_t durationUsec = SL_TIME_UNKNOWN;
1711 if (ap->mSfPlayer != 0) {
1712 durationUsec = ap->mSfPlayer->getDurationUsec();
1714 *pDurMsec = durationUsec == -1 ? SL_TIME_UNKNOWN : durationUsec / 1000;
1717 case A_PLR_TS_ABQ: // intended fall-through
1719 *pDurMsec = SL_TIME_UNKNOWN;
1722 return SL_RESULT_SUCCESS;
1726 //-----------------------------------------------------------------------------
1727 void android_audioPlayer_getPosition(IPlay *pPlayItf, SLmillisecond *pPosMsec) {
1728 CAudioPlayer *ap = (CAudioPlayer *)pPlayItf->mThis;
1729 switch(ap->mAndroidObjType) {
1731 if ((ap->mSampleRateMilliHz == 0) || (NULL == ap->mAudioTrack)) {
1734 uint32_t positionInFrames;
1735 ap->mAudioTrack->getPosition(&positionInFrames);
1736 *pPosMsec = ((int64_t)positionInFrames * 1000) /
1737 sles_to_android_sampleRate(ap->mSampleRateMilliHz);
1741 if (ap->mSfPlayer != 0) {
1742 *pPosMsec = ap->mSfPlayer->getPositionMsec();
1753 //-----------------------------------------------------------------------------
1754 void android_audioPlayer_seek(CAudioPlayer *ap, SLmillisecond posMsec) {
1756 switch(ap->mAndroidObjType) {
1760 if (ap->mSfPlayer != 0) {
1761 ap->mSfPlayer->seek(posMsec);
1770 //-----------------------------------------------------------------------------
1771 void android_audioPlayer_loop(CAudioPlayer *ap, SLboolean loopEnable) {
1773 if ((A_PLR_URIFD == ap->mAndroidObjType) && (ap->mSfPlayer != 0)) {
1774 ap->mSfPlayer->loop((bool)loopEnable);
1779 //-----------------------------------------------------------------------------
1781 * Mutes or unmutes the Android media framework object associated with the CAudioPlayer that carries
1782 * the IVolume interface.
1784 * if ap->mMute is SL_BOOLEAN_FALSE, a call to this function was preceded by a call
1785 * to android_audioPlayer_volumeUpdate()
1787 static void android_audioPlayer_setMute(CAudioPlayer* ap) {
1788 android::AudioTrack *t = NULL;
1789 switch(ap->mAndroidObjType) {
1792 t = ap->mAudioTrack;
1797 // when unmuting: volume levels have already been updated in IVolume_SetMute
1804 //-----------------------------------------------------------------------------
1805 SLresult android_audioPlayer_volumeUpdate(CAudioPlayer* ap) {
1806 android_audioPlayer_updateStereoVolume(ap);
1807 android_audioPlayer_setMute(ap);
1808 return SL_RESULT_SUCCESS;
1812 //-----------------------------------------------------------------------------
1813 void android_audioPlayer_bufferQueue_onRefilled_l(CAudioPlayer *ap) {
1814 // the AudioTrack associated with the AudioPlayer receiving audio from a PCM buffer
1815 // queue was stopped when the queue become empty, we restart as soon as a new buffer
1816 // has been enqueued since we're in playing state
1817 if (NULL != ap->mAudioTrack) {
1818 ap->mAudioTrack->start();
1821 // when the queue became empty, an underflow on the prefetch status itf was sent. Now the queue
1822 // has received new data, signal it has sufficient data
1823 if (IsInterfaceInitialized(&(ap->mObject), MPH_PREFETCHSTATUS)) {
1824 audioPlayer_dispatch_prefetchStatus_lockPrefetch(ap, SL_PREFETCHSTATUS_SUFFICIENTDATA,
1830 //-----------------------------------------------------------------------------
1832 * BufferQueue::Clear
1834 SLresult android_audioPlayer_bufferQueue_onClear(CAudioPlayer *ap) {
1835 SLresult result = SL_RESULT_SUCCESS;
1837 switch (ap->mAndroidObjType) {
1838 //-----------------------------------
1841 if (NULL != ap->mAudioTrack) {
1842 ap->mAudioTrack->flush();
1846 result = SL_RESULT_INTERNAL_ERROR;
1854 //-----------------------------------------------------------------------------
1855 void android_audioPlayer_androidBufferQueue_registerCallback_l(CAudioPlayer *ap) {
1856 if ((ap->mAndroidObjType == A_PLR_TS_ABQ) && (ap->mAPlayer != 0)) {
1857 android::StreamPlayer* splr = static_cast<android::StreamPlayer*>(ap->mAPlayer.get());
1858 splr->registerQueueCallback(
1859 (const void*)ap, true /*userIsAudioPlayer*/,
1860 ap->mAndroidBufferQueue.mContext,
1861 (const void*)&(ap->mAndroidBufferQueue.mItf));
1865 //-----------------------------------------------------------------------------
1866 void android_audioPlayer_androidBufferQueue_clear_l(CAudioPlayer *ap) {
1867 if ((ap->mAndroidObjType == A_PLR_TS_ABQ) && (ap->mAPlayer != 0)) {
1868 android::StreamPlayer* splr = static_cast<android::StreamPlayer*>(ap->mAPlayer.get());
1873 void android_audioPlayer_androidBufferQueue_onRefilled_l(CAudioPlayer *ap) {
1874 if ((ap->mAndroidObjType == A_PLR_TS_ABQ) && (ap->mAPlayer != 0)) {
1875 android::StreamPlayer* splr = static_cast<android::StreamPlayer*>(ap->mAPlayer.get());
1876 splr->queueRefilled_l();