AudioPlayer_to_android.cpp revision 143c8939640425ce28aaac46732fb604fba1f5c8
1773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi/*
2773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * Copyright (C) 2010 The Android Open Source Project
3773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi *
4773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License");
5773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * you may not use this file except in compliance with the License.
6773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * You may obtain a copy of the License at
7773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi *
8773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi *      http://www.apache.org/licenses/LICENSE-2.0
9773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi *
10773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * Unless required by applicable law or agreed to in writing, software
11773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS,
12773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * See the License for the specific language governing permissions and
14773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi * limitations under the License.
15773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi */
16773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi
17daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten#include "sles_allinclusive.h"
1875e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi#include "android_prompts.h"
192b06e20ae32388f6e1dfd088d9773c34e6b1cb45Jean-Michel Trivi#include "android/android_AudioToCbRenderer.h"
202b06e20ae32388f6e1dfd088d9773c34e6b1cb45Jean-Michel Trivi#include "android/android_StreamPlayer.h"
212b06e20ae32388f6e1dfd088d9773c34e6b1cb45Jean-Michel Trivi#include "android/android_LocAVPlayer.h"
22bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi#include "android/include/AacBqToPcmCbRenderer.h"
23ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten#include "android/channels.h"
24773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi
2515f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean#include <android_runtime/AndroidRuntime.h>
26143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi#include <binder/IServiceManager.h>
27143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi#include <utils/StrongPointer.h>
28143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi#include <audiomanager/AudioManager.h>
29143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi#include <audiomanager/IAudioManager.h>
3015f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean
31833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten#include <fcntl.h>
32833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten#include <sys/stat.h>
33143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi#include <unistd.h>
34833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten
3510a3840407ac3ed61e7873ee7b86d664ccc6149fDima Zavin#include <system/audio.h>
364e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean#include <SLES/OpenSLES_Android.h>
37ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin
38aa08cb01d58f1da2d0a2b208aed3bf1730f8f63dEric Laurenttemplate class android::KeyedVector<SLuint32,
39aa08cb01d58f1da2d0a2b208aed3bf1730f8f63dEric Laurent                                    android::sp<android::AudioEffect> > ;
40a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten
4175e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi#define KEY_STREAM_TYPE_PARAMSIZE  sizeof(SLint32)
428c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent#define KEY_PERFORMANCE_MODE_PARAMSIZE  sizeof(SLint32)
431ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
446d78c9bfb68f8a0db1855bc28c087c39a7eb6f2cGlenn Kasten#define AUDIOTRACK_MIN_PLAYBACKRATE_PERMILLE  500
456d78c9bfb68f8a0db1855bc28c087c39a7eb6f2cGlenn Kasten#define AUDIOTRACK_MAX_PLAYBACKRATE_PERMILLE 2000
466d78c9bfb68f8a0db1855bc28c087c39a7eb6f2cGlenn Kasten
4791145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi#define MEDIAPLAYER_MIN_PLAYBACKRATE_PERMILLE AUDIOTRACK_MIN_PLAYBACKRATE_PERMILLE
4891145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi#define MEDIAPLAYER_MAX_PLAYBACKRATE_PERMILLE AUDIOTRACK_MAX_PLAYBACKRATE_PERMILLE
4991145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi
5005ccff2aaa3e1507cdc7ab3b244c973c6708e009Jean-Michel Trivi//-----------------------------------------------------------------------------
51143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi// Inline functions to communicate with AudioService through the native AudioManager interface
52143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Triviinline void audioManagerPlayerEvent(CAudioPlayer* ap, int event) {
53143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi    if (ap->mObject.mEngine->mAudioManager != 0) {
54143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        ap->mObject.mEngine->mAudioManager->playerEvent(ap->mPIId, event);
55143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi    }
56143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi}
57143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi
58143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Triviinline void audioManagerReleasePlayer(CAudioPlayer* ap) {
59143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi    if (ap->mObject.mEngine->mAudioManager != 0) {
60143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        ap->mObject.mEngine->mAudioManager->releasePlayer(ap->mPIId);
61143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi    }
62143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi}
63143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi
64143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi//-----------------------------------------------------------------------------
65143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi// get an audio attributes usage for a stream type, but only consider stream types
66143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi// that can successfully be set through SLAndroidConfigurationItf. It is invalid to call
67143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi// this function with other stream types.
68143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Triviaudio_usage_t usageForStreamType(audio_stream_type_t streamType) {
69143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi    switch (streamType) {
70143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi    case AUDIO_STREAM_MUSIC:
71143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        return AUDIO_USAGE_MEDIA;
72143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi    case AUDIO_STREAM_VOICE_CALL:
73143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        return AUDIO_USAGE_VOICE_COMMUNICATION;
74143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi    case AUDIO_STREAM_SYSTEM:
75143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        return AUDIO_USAGE_ASSISTANCE_SONIFICATION;
76143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi    case AUDIO_STREAM_RING:
77143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        return AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE;
78143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi    case AUDIO_STREAM_ALARM:
79143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        return AUDIO_USAGE_ALARM;
80143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi    case AUDIO_STREAM_NOTIFICATION:
81143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        return AUDIO_USAGE_NOTIFICATION;
82143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi    default:
83143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        // shouldn't happen, stream types on AudioPlayer have been sanitized by now.
84143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        SL_LOGE("invalid stream type %d when converting to usage", streamType);
85143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        return usageForStreamType(ANDROID_DEFAULT_OUTPUT_STREAM_TYPE);
86143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi    }
87143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi}
88143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi//-----------------------------------------------------------------------------
8913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi// FIXME this method will be absorbed into android_audioPlayer_setPlayState() once
9013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi//       bufferqueue and uri/fd playback are moved under the GenericPlayer C++ object
9113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel TriviSLresult aplayer_setPlayState(const android::sp<android::GenericPlayer> &ap, SLuint32 playState,
92b05ea38e5131001884aa226f90fd50cf594a23f3Jean-Michel Trivi        AndroidObjectState* pObjState) {
9313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
94b05ea38e5131001884aa226f90fd50cf594a23f3Jean-Michel Trivi    AndroidObjectState objState = *pObjState;
9513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
9613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    switch (playState) {
9713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi     case SL_PLAYSTATE_STOPPED:
9813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         SL_LOGV("setting GenericPlayer to SL_PLAYSTATE_STOPPED");
9913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         ap->stop();
10013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         break;
10113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi     case SL_PLAYSTATE_PAUSED:
10213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         SL_LOGV("setting GenericPlayer to SL_PLAYSTATE_PAUSED");
103ac28eca1df49f581d952ffbda5d3019f7e3b7be6Glenn Kasten         switch (objState) {
10413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         case ANDROID_UNINITIALIZED:
10513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi             *pObjState = ANDROID_PREPARING;
10613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi             ap->prepare();
10713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi             break;
10813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         case ANDROID_PREPARING:
10913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi             break;
11013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         case ANDROID_READY:
11113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi             ap->pause();
11213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi             break;
11313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         default:
11413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi             SL_LOGE(ERROR_PLAYERSETPLAYSTATE_INVALID_OBJECT_STATE_D, playState);
11513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi             result = SL_RESULT_INTERNAL_ERROR;
11613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi             break;
11713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         }
11813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         break;
11913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi     case SL_PLAYSTATE_PLAYING: {
12013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         SL_LOGV("setting GenericPlayer to SL_PLAYSTATE_PLAYING");
121ac28eca1df49f581d952ffbda5d3019f7e3b7be6Glenn Kasten         switch (objState) {
12213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         case ANDROID_UNINITIALIZED:
12313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi             *pObjState = ANDROID_PREPARING;
12413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi             ap->prepare();
12513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi             // intended fall through
12613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         case ANDROID_PREPARING:
12713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi             // intended fall through
12813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         case ANDROID_READY:
12913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi             ap->play();
13013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi             break;
13113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         default:
13213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi             SL_LOGE(ERROR_PLAYERSETPLAYSTATE_INVALID_OBJECT_STATE_D, playState);
13313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi             result = SL_RESULT_INTERNAL_ERROR;
13413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi             break;
13513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         }
13613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         }
13713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         break;
13813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi     default:
13913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         // checked by caller, should not happen
14013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         SL_LOGE(ERROR_SHOULDNT_BE_HERE_S, "aplayer_setPlayState");
14113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         result = SL_RESULT_INTERNAL_ERROR;
14213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi         break;
14313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi     }
14413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
14513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    return result;
14613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi}
14713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
14813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
14913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi//-----------------------------------------------------------------------------
15013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi// Callback associated with a AudioToCbRenderer of an SL ES AudioPlayer that gets its data
15113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi// from a URI or FD, to write the decoded audio data to a buffer queue
152f4b45a37248899ae2d27bb172f8387fbf1edff8eGlenn Kastenstatic size_t adecoder_writeToBufferQueue(const uint8_t *data, size_t size, CAudioPlayer* ap) {
153f4b45a37248899ae2d27bb172f8387fbf1edff8eGlenn Kasten    if (!android::CallbackProtector::enterCbIfOk(ap->mCallbackProtector)) {
154f4b45a37248899ae2d27bb172f8387fbf1edff8eGlenn Kasten        // it is not safe to enter the callback (the player is about to go away)
155f4b45a37248899ae2d27bb172f8387fbf1edff8eGlenn Kasten        return 0;
15613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    }
157f4b45a37248899ae2d27bb172f8387fbf1edff8eGlenn Kasten    size_t sizeConsumed = 0;
1584e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean    SL_LOGD("received %zu bytes from decoder", size);
15913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    slBufferQueueCallback callback = NULL;
16013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    void * callbackPContext = NULL;
16113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
16213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    // push decoded data to the buffer queue
16313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    object_lock_exclusive(&ap->mObject);
16413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
16513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    if (ap->mBufferQueue.mState.count != 0) {
16613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        assert(ap->mBufferQueue.mFront != ap->mBufferQueue.mRear);
16713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
16813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        BufferHeader *oldFront = ap->mBufferQueue.mFront;
16913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        BufferHeader *newFront = &oldFront[1];
17013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
17113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        uint8_t *pDest = (uint8_t *)oldFront->mBuffer + ap->mBufferQueue.mSizeConsumed;
17213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        if (ap->mBufferQueue.mSizeConsumed + size < oldFront->mSize) {
17313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            // room to consume the whole or rest of the decoded data in one shot
17413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            ap->mBufferQueue.mSizeConsumed += size;
17513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            // consume data but no callback to the BufferQueue interface here
17664c3fe7bd86951eeac27adca2219ce16eabff58cGlenn Kasten            memcpy(pDest, data, size);
17713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            sizeConsumed = size;
17813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        } else {
17913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            // push as much as possible of the decoded data into the buffer queue
18013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            sizeConsumed = oldFront->mSize - ap->mBufferQueue.mSizeConsumed;
18113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
18213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            // the buffer at the head of the buffer queue is full, update the state
18313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            ap->mBufferQueue.mSizeConsumed = 0;
18422ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten            if (newFront == &ap->mBufferQueue.mArray[ap->mBufferQueue.mNumBuffers + 1]) {
18513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                newFront = ap->mBufferQueue.mArray;
18613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            }
18713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            ap->mBufferQueue.mFront = newFront;
18813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
18913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            ap->mBufferQueue.mState.count--;
19013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            ap->mBufferQueue.mState.playIndex++;
19113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            // consume data
19264c3fe7bd86951eeac27adca2219ce16eabff58cGlenn Kasten            memcpy(pDest, data, sizeConsumed);
19313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            // data has been copied to the buffer, and the buffer queue state has been updated
19413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            // we will notify the client if applicable
19513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            callback = ap->mBufferQueue.mCallback;
19613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            // save callback data
19713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            callbackPContext = ap->mBufferQueue.mContext;
19813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        }
19913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
20013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    } else {
20113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        // no available buffers in the queue to write the decoded data
20213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        sizeConsumed = 0;
20313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    }
20413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
20513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    object_unlock_exclusive(&ap->mObject);
20613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    // notify client
20713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    if (NULL != callback) {
20813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        (*callback)(&ap->mBufferQueue.mItf, callbackPContext);
20913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    }
21013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
211f4b45a37248899ae2d27bb172f8387fbf1edff8eGlenn Kasten    ap->mCallbackProtector->exitCb();
21213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    return sizeConsumed;
21313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi}
21413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
215712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi
216712b490060e4164fbe47986be1d2584d1610d8ddJean-Michel Trivi//-----------------------------------------------------------------------------
217ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten#define LEFT_CHANNEL_MASK  AUDIO_CHANNEL_OUT_FRONT_LEFT
218ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten#define RIGHT_CHANNEL_MASK AUDIO_CHANNEL_OUT_FRONT_RIGHT
2196a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
220fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kastenvoid android_audioPlayer_volumeUpdate(CAudioPlayer* ap)
221fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten{
222fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    assert(ap != NULL);
2234614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
224fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    // the source's channel count, where zero means unknown
22599b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    SLuint8 channelCount = ap->mNumChannels;
2261fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi
227fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    // whether each channel is audible
228fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    bool leftAudibilityFactor, rightAudibilityFactor;
2291fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi
230fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    // mute has priority over solo
231e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    if (channelCount >= STEREO_CHANNELS) {
232b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten        if (ap->mMuteMask & LEFT_CHANNEL_MASK) {
2331fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            // left muted
234fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten            leftAudibilityFactor = false;
2351fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        } else {
2361fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            // left not muted
237b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten            if (ap->mSoloMask & LEFT_CHANNEL_MASK) {
2381fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                // left soloed
239fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten                leftAudibilityFactor = true;
2401fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            } else {
2411fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                // left not soloed
242b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten                if (ap->mSoloMask & RIGHT_CHANNEL_MASK) {
2431fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                    // right solo silences left
244fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten                    leftAudibilityFactor = false;
2451fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                } else {
2461fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                    // left and right are not soloed, and left is not muted
247fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten                    leftAudibilityFactor = true;
2481fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                }
2491fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            }
2501fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        }
2511fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi
252b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten        if (ap->mMuteMask & RIGHT_CHANNEL_MASK) {
2531fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            // right muted
254fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten            rightAudibilityFactor = false;
2551fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        } else {
2561fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            // right not muted
257b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten            if (ap->mSoloMask & RIGHT_CHANNEL_MASK) {
2581fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                // right soloed
259fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten                rightAudibilityFactor = true;
2601fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            } else {
2611fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                // right not soloed
262b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten                if (ap->mSoloMask & LEFT_CHANNEL_MASK) {
2631fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                    // left solo silences right
264fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten                    rightAudibilityFactor = false;
2651fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                } else {
2661fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                    // left and right are not soloed, and right is not muted
267fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten                    rightAudibilityFactor = true;
2681fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi                }
2691fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi            }
2701fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        }
271fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten
272fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    // channel mute and solo are ignored for mono and unknown channel count sources
273fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    } else {
274fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten        leftAudibilityFactor = true;
275fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten        rightAudibilityFactor = true;
276fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    }
277fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten
27899b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    // compute volumes without setting
27999b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    const bool audibilityFactors[2] = {leftAudibilityFactor, rightAudibilityFactor};
28099b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    float volumes[2];
28199b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    android_player_volumeUpdate(volumes, &ap->mVolume, channelCount, ap->mAmplFromDirectLevel,
28299b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten            audibilityFactors);
28399b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    float leftVol = volumes[0], rightVol = volumes[1];
28499b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten
28599b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    // set volume on the underlying media player or audio track
28699b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    if (ap->mAPlayer != 0) {
28799b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        ap->mAPlayer->setVolume(leftVol, rightVol);
28899b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    } else if (ap->mAudioTrack != 0) {
28999b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        ap->mAudioTrack->setVolume(leftVol, rightVol);
29099b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    }
29199b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten
29299b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    // changes in the AudioPlayer volume must be reflected in the send level:
29399b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    //  in SLEffectSendItf or in SLAndroidEffectSendItf?
29499b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    // FIXME replace interface test by an internal API once we have one.
29599b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    if (NULL != ap->mEffectSend.mItf) {
29699b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        for (unsigned int i=0 ; i<AUX_MAX ; i++) {
29799b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten            if (ap->mEffectSend.mEnableLevels[i].mEnable) {
29899b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten                android_fxSend_setSendLevel(ap,
29999b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten                        ap->mEffectSend.mEnableLevels[i].mSendLevel + ap->mVolume.mLevel);
30099b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten                // there's a single aux bus on Android, so we can stop looking once the first
30199b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten                // aux effect is found.
30299b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten                break;
30399b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten            }
30499b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        }
30599b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    } else if (NULL != ap->mAndroidEffectSend.mItf) {
30699b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        android_fxSend_setSendLevel(ap, ap->mAndroidEffectSend.mSendLevel + ap->mVolume.mLevel);
30799b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    }
30899b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten}
30999b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten
31099b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten// Called by android_audioPlayer_volumeUpdate and android_mediaPlayer_volumeUpdate to compute
31199b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten// volumes, but setting volumes is handled by the caller.
31299b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten
31399b927751677abfb60a388d65dfeed1fed1db12cGlenn Kastenvoid android_player_volumeUpdate(float *pVolumes /*[2]*/, const IVolume *volumeItf, unsigned
31499b927751677abfb60a388d65dfeed1fed1db12cGlenn KastenchannelCount, float amplFromDirectLevel, const bool *audibilityFactors /*[2]*/)
31599b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten{
31699b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    assert(pVolumes != NULL);
31799b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    assert(volumeItf != NULL);
31899b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    // OK for audibilityFactors to be NULL
31999b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten
32099b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    bool leftAudibilityFactor, rightAudibilityFactor;
32199b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten
322fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    // apply player mute factor
323fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    // note that AudioTrack has mute() but not MediaPlayer, so it's easier to use volume
32499b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    // to mute for both rather than calling mute() for AudioTrack
32599b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten
32699b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    // player is muted
32799b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    if (volumeItf->mMute) {
328fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten        leftAudibilityFactor = false;
329fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten        rightAudibilityFactor = false;
33099b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    // player isn't muted, and channel mute/solo audibility factors are available (AudioPlayer)
33199b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    } else if (audibilityFactors != NULL) {
33299b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        leftAudibilityFactor = audibilityFactors[0];
33399b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        rightAudibilityFactor = audibilityFactors[1];
33499b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    // player isn't muted, and channel mute/solo audibility factors aren't available (MediaPlayer)
33599b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    } else {
33699b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        leftAudibilityFactor = true;
33799b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        rightAudibilityFactor = true;
3381fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi    }
3396a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
3406a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    // compute amplification as the combination of volume level and stereo position
34199b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    //   amplification (or attenuation) from volume level
34299b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    float amplFromVolLevel = sles_to_android_amplification(volumeItf->mLevel);
343ca325fa86f9e52d8300490eee102a3c1188f6bdcJean-Michel Trivi    //   amplification from direct level (changed in SLEffectSendtItf and SLAndroidEffectSendItf)
34499b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    float leftVol  = amplFromVolLevel * amplFromDirectLevel;
34599b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    float rightVol = leftVol;
346a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
347f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi    // amplification from stereo position
34899b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    if (volumeItf->mEnableStereoPosition) {
34999b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        // Left/right amplification (can be attenuations) factors derived for the StereoPosition
35099b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        float amplFromStereoPos[STEREO_CHANNELS];
35199b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        // panning law depends on content channel count: mono to stereo panning vs stereo balance
35299b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        if (1 == channelCount) {
35399b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten            // mono to stereo panning
35499b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten            double theta = (1000+volumeItf->mStereoPosition)*M_PI_4/1000.0f; // 0 <= theta <= Pi/2
35599b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten            amplFromStereoPos[0] = cos(theta);
35699b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten            amplFromStereoPos[1] = sin(theta);
357fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten        // channel count is 0 (unknown), 2 (stereo), or > 2 (multi-channel)
358f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi        } else {
359f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi            // stereo balance
36099b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten            if (volumeItf->mStereoPosition > 0) {
36199b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten                amplFromStereoPos[0] = (1000-volumeItf->mStereoPosition)/1000.0f;
36299b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten                amplFromStereoPos[1] = 1.0f;
3636a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            } else {
36499b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten                amplFromStereoPos[0] = 1.0f;
36599b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten                amplFromStereoPos[1] = (1000+volumeItf->mStereoPosition)/1000.0f;
3666a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            }
3676a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        }
36899b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        leftVol  *= amplFromStereoPos[0];
36999b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        rightVol *= amplFromStereoPos[1];
370f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi    }
371f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi
372fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    // apply audibility factors
373fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    if (!leftAudibilityFactor) {
374fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten        leftVol = 0.0;
375fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    }
376fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    if (!rightAudibilityFactor) {
377fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten        rightVol = 0.0;
378fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    }
379fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten
38099b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    // return the computed volumes
38199b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    pVolumes[0] = leftVol;
38299b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    pVolumes[1] = rightVol;
3834614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi}
3844614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
3854614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi//-----------------------------------------------------------------------------
386e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivivoid audioTrack_handleMarker_lockPlay(CAudioPlayer* ap) {
38749e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten    //SL_LOGV("received event EVENT_MARKER from AudioTrack");
3884614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    slPlayCallback callback = NULL;
3894614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    void* callbackPContext = NULL;
3904614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
3914614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    interface_lock_shared(&ap->mPlay);
3924614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    callback = ap->mPlay.mCallback;
3934614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    callbackPContext = ap->mPlay.mContext;
3944614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    interface_unlock_shared(&ap->mPlay);
3954614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
3964614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (NULL != callback) {
3974614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        // getting this event implies SL_PLAYEVENT_HEADATMARKER was set in the event mask
3984614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        (*callback)(&ap->mPlay.mItf, callbackPContext, SL_PLAYEVENT_HEADATMARKER);
3994614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
4004614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi}
4014614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
4024614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi//-----------------------------------------------------------------------------
403e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivivoid audioTrack_handleNewPos_lockPlay(CAudioPlayer* ap) {
40449e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten    //SL_LOGV("received event EVENT_NEW_POS from AudioTrack");
4054614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    slPlayCallback callback = NULL;
4064614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    void* callbackPContext = NULL;
4074614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
4084614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    interface_lock_shared(&ap->mPlay);
4094614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    callback = ap->mPlay.mCallback;
4104614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    callbackPContext = ap->mPlay.mContext;
4114614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    interface_unlock_shared(&ap->mPlay);
4124614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
4134614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (NULL != callback) {
4144614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        // getting this event implies SL_PLAYEVENT_HEADATNEWPOS was set in the event mask
4154614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        (*callback)(&ap->mPlay.mItf, callbackPContext, SL_PLAYEVENT_HEADATNEWPOS);
4164614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
4174614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi}
4184614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
4194614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
4204614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi//-----------------------------------------------------------------------------
421e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivivoid audioTrack_handleUnderrun_lockPlay(CAudioPlayer* ap) {
4224614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    slPlayCallback callback = NULL;
4234614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    void* callbackPContext = NULL;
4244614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
4254614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    interface_lock_shared(&ap->mPlay);
4264614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    callback = ap->mPlay.mCallback;
4274614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    callbackPContext = ap->mPlay.mContext;
4284614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    bool headStalled = (ap->mPlay.mEventFlags & SL_PLAYEVENT_HEADSTALLED) != 0;
4294614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    interface_unlock_shared(&ap->mPlay);
4304614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
4314614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if ((NULL != callback) && headStalled) {
4324614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        (*callback)(&ap->mPlay.mItf, callbackPContext, SL_PLAYEVENT_HEADSTALLED);
433f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi    }
434f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi}
435f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi
43624430c9070298f12e68b84c921add38da6ad0490Jean-Michel Trivi
437e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi//-----------------------------------------------------------------------------
438e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi/**
439e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi * post-condition: play state of AudioPlayer is SL_PLAYSTATE_PAUSED if setPlayStateToPaused is true
440e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi *
441e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi * note: a conditional flag, setPlayStateToPaused, is used here to specify whether the play state
442e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi *       needs to be changed when the player reaches the end of the content to play. This is
443e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi *       relative to what the specification describes for buffer queues vs the
444e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi *       SL_PLAYEVENT_HEADATEND event. In the OpenSL ES specification 1.0.1:
445e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi *        - section 8.12 SLBufferQueueItf states "In the case of starvation due to insufficient
446e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi *          buffers in the queue, the playing of audio data stops. The player remains in the
447e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi *          SL_PLAYSTATE_PLAYING state."
448e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi *        - section 9.2.31 SL_PLAYEVENT states "SL_PLAYEVENT_HEADATEND Playback head is at the end
449e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi *          of the current content and the player has paused."
450e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi */
451fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kastenvoid audioPlayer_dispatch_headAtEnd_lockPlay(CAudioPlayer *ap, bool setPlayStateToPaused,
452fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten        bool needToLock) {
45325d7efb86cd78b868afef12a30ef557f91d97552Jean-Michel Trivi    //SL_LOGV("ap=%p, setPlayStateToPaused=%d, needToLock=%d", ap, setPlayStateToPaused,
45425d7efb86cd78b868afef12a30ef557f91d97552Jean-Michel Trivi    //        needToLock);
455e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi    slPlayCallback playCallback = NULL;
456e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi    void * playContext = NULL;
457e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi    // SLPlayItf callback or no callback?
458fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten    if (needToLock) {
459ca98a6831e18865542985b7cc97da25708b54b9cJean-Michel Trivi        interface_lock_exclusive(&ap->mPlay);
460fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten    }
461e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi    if (ap->mPlay.mEventFlags & SL_PLAYEVENT_HEADATEND) {
462e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        playCallback = ap->mPlay.mCallback;
463e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        playContext = ap->mPlay.mContext;
464e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi    }
46525d7efb86cd78b868afef12a30ef557f91d97552Jean-Michel Trivi    if (setPlayStateToPaused) {
466ca98a6831e18865542985b7cc97da25708b54b9cJean-Michel Trivi        ap->mPlay.mState = SL_PLAYSTATE_PAUSED;
467ca98a6831e18865542985b7cc97da25708b54b9cJean-Michel Trivi    }
468ca98a6831e18865542985b7cc97da25708b54b9cJean-Michel Trivi    if (needToLock) {
469ca98a6831e18865542985b7cc97da25708b54b9cJean-Michel Trivi        interface_unlock_exclusive(&ap->mPlay);
470fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten    }
471377aa54ce344adcbc8bac731c6db9e7e39b432c5Glenn Kasten    // enqueue callback with no lock held
472e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi    if (NULL != playCallback) {
473dd177e2d3923d4653eaa4226f07b89a999907970Glenn Kasten#ifndef USE_ASYNCHRONOUS_PLAY_CALLBACK
474dd177e2d3923d4653eaa4226f07b89a999907970Glenn Kasten        (*playCallback)(&ap->mPlay.mItf, playContext, SL_PLAYEVENT_HEADATEND);
475dd177e2d3923d4653eaa4226f07b89a999907970Glenn Kasten#else
476377aa54ce344adcbc8bac731c6db9e7e39b432c5Glenn Kasten        SLresult result = EnqueueAsyncCallback_ppi(ap, playCallback, &ap->mPlay.mItf, playContext,
477377aa54ce344adcbc8bac731c6db9e7e39b432c5Glenn Kasten                SL_PLAYEVENT_HEADATEND);
478377aa54ce344adcbc8bac731c6db9e7e39b432c5Glenn Kasten        if (SL_RESULT_SUCCESS != result) {
479a6c69c7e1665b38da8d6784e65210acbe501b92cSteve Block            ALOGW("Callback %p(%p, %p, SL_PLAYEVENT_HEADATEND) dropped", playCallback,
480377aa54ce344adcbc8bac731c6db9e7e39b432c5Glenn Kasten                    &ap->mPlay.mItf, playContext);
481377aa54ce344adcbc8bac731c6db9e7e39b432c5Glenn Kasten        }
482dd177e2d3923d4653eaa4226f07b89a999907970Glenn Kasten#endif
483e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi    }
48425d7efb86cd78b868afef12a30ef557f91d97552Jean-Michel Trivi
485e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi}
486e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi
487a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi
488a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi//-----------------------------------------------------------------------------
48975e22870e41386cdc597bd29c76744d74d4c22adJean-Michel TriviSLresult audioPlayer_setStreamType(CAudioPlayer* ap, SLint32 type) {
49075e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
491a8179ea15c4ff78db589d742b135649f0eda7ef2Glenn Kasten    SL_LOGV("type %d", type);
49275e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
4930bfed90f3b312f7c8f2b744efcf62f1992661d6cGlenn Kasten    audio_stream_type_t newStreamType = ANDROID_DEFAULT_OUTPUT_STREAM_TYPE;
494ac28eca1df49f581d952ffbda5d3019f7e3b7be6Glenn Kasten    switch (type) {
49575e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    case SL_ANDROID_STREAM_VOICE:
496ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin        newStreamType = AUDIO_STREAM_VOICE_CALL;
49775e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        break;
49875e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    case SL_ANDROID_STREAM_SYSTEM:
499ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin        newStreamType = AUDIO_STREAM_SYSTEM;
50075e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        break;
50175e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    case SL_ANDROID_STREAM_RING:
502ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin        newStreamType = AUDIO_STREAM_RING;
50375e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        break;
50475e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    case SL_ANDROID_STREAM_MEDIA:
505ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin        newStreamType = AUDIO_STREAM_MUSIC;
50675e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        break;
50775e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    case SL_ANDROID_STREAM_ALARM:
508ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin        newStreamType = AUDIO_STREAM_ALARM;
50975e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        break;
51075e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    case SL_ANDROID_STREAM_NOTIFICATION:
511ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin        newStreamType = AUDIO_STREAM_NOTIFICATION;
51275e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        break;
51375e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    default:
51475e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        SL_LOGE(ERROR_PLAYERSTREAMTYPE_SET_UNKNOWN_TYPE);
51575e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        result = SL_RESULT_PARAMETER_INVALID;
51675e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        break;
51775e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    }
51875e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
51975e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    // stream type needs to be set before the object is realized
52075e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    // (ap->mAudioTrack is supposed to be NULL until then)
5215f71e35da153d194d805e030ab38935599e065d2Jean-Michel Trivi    if (SL_OBJECT_STATE_UNREALIZED != ap->mObject.mState) {
52275e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        SL_LOGE(ERROR_PLAYERSTREAMTYPE_REALIZED);
52375e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        result = SL_RESULT_PRECONDITIONS_VIOLATED;
52475e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    } else {
52575e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        ap->mStreamType = newStreamType;
52675e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    }
52775e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
52875e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    return result;
52975e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi}
53075e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
5318c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent//-----------------------------------------------------------------------------
5328c9071f491393fadf767b6164a17b0795eba3fdaEric LaurentSLresult audioPlayer_setPerformanceMode(CAudioPlayer* ap, SLuint32 mode) {
5338c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    SLresult result = SL_RESULT_SUCCESS;
5348c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    SL_LOGV("performance mode set to %d", mode);
5358c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent
5368c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    SLuint32 perfMode = ANDROID_PERFORMANCE_MODE_DEFAULT;
5378c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    switch (mode) {
5388c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    case SL_ANDROID_PERFORMANCE_LATENCY:
5398c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        perfMode = ANDROID_PERFORMANCE_MODE_LATENCY;
5408c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        break;
5418c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    case SL_ANDROID_PERFORMANCE_LATENCY_EFFECTS:
5428c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        perfMode = ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS;
5438c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        break;
5448c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    case SL_ANDROID_PERFORMANCE_NONE:
5458c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        perfMode = ANDROID_PERFORMANCE_MODE_NONE;
5468c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        break;
5478c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    case SL_ANDROID_PERFORMANCE_POWER_SAVING:
5488c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        perfMode = ANDROID_PERFORMANCE_MODE_POWER_SAVING;
5498c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        break;
5508c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    default:
5518c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        SL_LOGE(ERROR_CONFIG_PERF_MODE_UNKNOWN);
5528c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        result = SL_RESULT_PARAMETER_INVALID;
5538c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        break;
5548c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    }
5558c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent
5568c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    // performance mode needs to be set before the object is realized
5578c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    // (ap->mAudioTrack is supposed to be NULL until then)
5588c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    if (SL_OBJECT_STATE_UNREALIZED != ap->mObject.mState) {
5598c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        SL_LOGE(ERROR_CONFIG_PERF_MODE_REALIZED);
5608c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        result = SL_RESULT_PRECONDITIONS_VIOLATED;
5618c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    } else {
5628c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        ap->mPerformanceMode = perfMode;
5638c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    }
5648c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent
5658c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    return result;
5668c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent}
56775e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
56875e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi//-----------------------------------------------------------------------------
56975e22870e41386cdc597bd29c76744d74d4c22adJean-Michel TriviSLresult audioPlayer_getStreamType(CAudioPlayer* ap, SLint32 *pType) {
57075e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
57175e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
572ac28eca1df49f581d952ffbda5d3019f7e3b7be6Glenn Kasten    switch (ap->mStreamType) {
573ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin    case AUDIO_STREAM_VOICE_CALL:
57475e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        *pType = SL_ANDROID_STREAM_VOICE;
57575e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        break;
576ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin    case AUDIO_STREAM_SYSTEM:
57775e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        *pType = SL_ANDROID_STREAM_SYSTEM;
57875e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        break;
579ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin    case AUDIO_STREAM_RING:
58075e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        *pType = SL_ANDROID_STREAM_RING;
58175e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        break;
582ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin    case AUDIO_STREAM_DEFAULT:
583ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin    case AUDIO_STREAM_MUSIC:
58475e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        *pType = SL_ANDROID_STREAM_MEDIA;
58575e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        break;
586ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin    case AUDIO_STREAM_ALARM:
58775e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        *pType = SL_ANDROID_STREAM_ALARM;
58875e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        break;
589ca39f4b4dbeb920a5b97bd65be73f2f7cac77431Dima Zavin    case AUDIO_STREAM_NOTIFICATION:
59075e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        *pType = SL_ANDROID_STREAM_NOTIFICATION;
59175e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        break;
59275e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    default:
59375e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        result = SL_RESULT_INTERNAL_ERROR;
59475e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        *pType = SL_ANDROID_STREAM_MEDIA;
59575e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        break;
59675e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    }
59775e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
59875e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    return result;
59975e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi}
60075e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
6018c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent//-----------------------------------------------------------------------------
6028c9071f491393fadf767b6164a17b0795eba3fdaEric LaurentSLresult audioPlayer_getPerformanceMode(CAudioPlayer* ap, SLuint32 *pMode) {
6038c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    SLresult result = SL_RESULT_SUCCESS;
6048c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent
6058c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    switch (ap->mPerformanceMode) {
6068c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    case ANDROID_PERFORMANCE_MODE_LATENCY:
6078c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        *pMode = SL_ANDROID_PERFORMANCE_LATENCY;
6088c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        break;
6098c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    case ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS:
6108c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        *pMode = SL_ANDROID_PERFORMANCE_LATENCY_EFFECTS;
6118c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        break;
6128c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    case ANDROID_PERFORMANCE_MODE_NONE:
6138c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        *pMode = SL_ANDROID_PERFORMANCE_NONE;
6148c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        break;
6158c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    case ANDROID_PERFORMANCE_MODE_POWER_SAVING:
6168c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        *pMode = SL_ANDROID_PERFORMANCE_POWER_SAVING;
6178c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        break;
6188c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    default:
6198c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        result = SL_RESULT_INTERNAL_ERROR;
6208c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        *pMode = SL_ANDROID_PERFORMANCE_LATENCY;
6218c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        break;
6228c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    }
6238c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent
6248c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    return result;
6258c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent}
62675e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
62775e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi//-----------------------------------------------------------------------------
628f7b852d914faa49d3e4b7d02bb5d9d254762c0b7Jean-Michel Trivivoid audioPlayer_auxEffectUpdate(CAudioPlayer* ap) {
62947550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten    if ((ap->mAudioTrack != 0) && (ap->mAuxEffect != 0)) {
630f7b852d914faa49d3e4b7d02bb5d9d254762c0b7Jean-Michel Trivi        android_fxSend_attach(ap, true, ap->mAuxEffect, ap->mVolume.mLevel + ap->mAuxSendLevel);
631f7b852d914faa49d3e4b7d02bb5d9d254762c0b7Jean-Michel Trivi    }
632f7b852d914faa49d3e4b7d02bb5d9d254762c0b7Jean-Michel Trivi}
633f7b852d914faa49d3e4b7d02bb5d9d254762c0b7Jean-Michel Trivi
634f7b852d914faa49d3e4b7d02bb5d9d254762c0b7Jean-Michel Trivi
635f7b852d914faa49d3e4b7d02bb5d9d254762c0b7Jean-Michel Trivi//-----------------------------------------------------------------------------
63613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi/*
6377965455f86c21d6e1f788b284f5fc829e82ff2b5Glenn Kasten * returns true if the given data sink is supported by AudioPlayer that doesn't
63813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi *   play to an OutputMix object, false otherwise
63913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi *
64013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi * pre-condition: the locator of the audio sink is not SL_DATALOCATOR_OUTPUTMIX
64113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi */
64213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivibool audioPlayer_isSupportedNonOutputMixSink(const SLDataSink* pAudioSink) {
64313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    bool result = true;
64413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    const SLuint32 sinkLocatorType = *(SLuint32 *)pAudioSink->pLocator;
64513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    const SLuint32 sinkFormatType = *(SLuint32 *)pAudioSink->pFormat;
64613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
64713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    switch (sinkLocatorType) {
64813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
64913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    case SL_DATALOCATOR_BUFFERQUEUE:
65013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
65113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        if (SL_DATAFORMAT_PCM != sinkFormatType) {
65213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            SL_LOGE("Unsupported sink format 0x%x, expected SL_DATAFORMAT_PCM",
65313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                    (unsigned)sinkFormatType);
65413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            result = false;
65513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        }
65613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        // it's no use checking the PCM format fields because additional characteristics
65713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        // such as the number of channels, or sample size are unknown to the player at this stage
65813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        break;
65913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
66013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    default:
66113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        SL_LOGE("Unsupported sink locator type 0x%x", (unsigned)sinkLocatorType);
66213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        result = false;
66313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        break;
66413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    }
66513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
66613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    return result;
66713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi}
66813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
66913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
67013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi//-----------------------------------------------------------------------------
67113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi/*
67213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi * returns the Android object type if the locator type combinations for the source and sinks
67313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi *   are supported by this implementation, INVALID_TYPE otherwise
67413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi */
67504e38178473bb0ffdb4759956db60dd86aa7e732Glenn Kastenstatic
676e05f49175a60182d29d0e38ee2a214854c279d95Glenn KastenAndroidObjectType audioPlayer_getAndroidObjectTypeForSourceSink(const CAudioPlayer *ap) {
67713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
67813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    const SLDataSource *pAudioSrc = &ap->mDataSource.u.mSource;
67913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    const SLDataSink *pAudioSnk = &ap->mDataSink.u.mSink;
68013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    const SLuint32 sourceLocatorType = *(SLuint32 *)pAudioSrc->pLocator;
68113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    const SLuint32 sinkLocatorType = *(SLuint32 *)pAudioSnk->pLocator;
682b05ea38e5131001884aa226f90fd50cf594a23f3Jean-Michel Trivi    AndroidObjectType type = INVALID_TYPE;
68313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
68413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    //--------------------------------------
68513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    // Sink / source matching check:
68613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    // the following source / sink combinations are supported
68713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    //     SL_DATALOCATOR_BUFFERQUEUE                / SL_DATALOCATOR_OUTPUTMIX
68813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    //     SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE   / SL_DATALOCATOR_OUTPUTMIX
68913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    //     SL_DATALOCATOR_URI                        / SL_DATALOCATOR_OUTPUTMIX
69013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    //     SL_DATALOCATOR_ANDROIDFD                  / SL_DATALOCATOR_OUTPUTMIX
69113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    //     SL_DATALOCATOR_ANDROIDBUFFERQUEUE         / SL_DATALOCATOR_OUTPUTMIX
692bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi    //     SL_DATALOCATOR_ANDROIDBUFFERQUEUE         / SL_DATALOCATOR_BUFFERQUEUE
69313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    //     SL_DATALOCATOR_URI                        / SL_DATALOCATOR_BUFFERQUEUE
69413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    //     SL_DATALOCATOR_ANDROIDFD                  / SL_DATALOCATOR_BUFFERQUEUE
69513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    //     SL_DATALOCATOR_URI                        / SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE
69613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    //     SL_DATALOCATOR_ANDROIDFD                  / SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE
69713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    switch (sinkLocatorType) {
69813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
69913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    case SL_DATALOCATOR_OUTPUTMIX: {
70013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        switch (sourceLocatorType) {
70113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
70213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        //   Buffer Queue to AudioTrack
70313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        case SL_DATALOCATOR_BUFFERQUEUE:
70413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
7054ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            type = AUDIOPLAYER_FROM_PCM_BUFFERQUEUE;
70613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            break;
70713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
70813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        //   URI or FD to MediaPlayer
70913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        case SL_DATALOCATOR_URI:
71013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        case SL_DATALOCATOR_ANDROIDFD:
7114ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            type = AUDIOPLAYER_FROM_URIFD;
71213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            break;
71313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
71413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        //   Android BufferQueue to MediaPlayer (shared memory streaming)
71513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
7164ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            type = AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE;
71713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            break;
71813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
71913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        default:
72013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            SL_LOGE("Source data locator 0x%x not supported with SL_DATALOCATOR_OUTPUTMIX sink",
72113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                    (unsigned)sourceLocatorType);
72213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            break;
72313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        }
72413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        }
72513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        break;
72613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
72713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    case SL_DATALOCATOR_BUFFERQUEUE:
72813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
72913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        switch (sourceLocatorType) {
73013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
73113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        //   URI or FD decoded to PCM in a buffer queue
73213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        case SL_DATALOCATOR_URI:
73313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        case SL_DATALOCATOR_ANDROIDFD:
7344ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            type = AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE;
73513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            break;
73613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
737bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi        //   AAC ADTS Android buffer queue decoded to PCM in a buffer queue
738bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi        case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
739bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi            type = AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE;
740bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi            break;
741bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi
74213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        default:
74313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            SL_LOGE("Source data locator 0x%x not supported with SL_DATALOCATOR_BUFFERQUEUE sink",
74413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                    (unsigned)sourceLocatorType);
74513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            break;
74613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        }
74713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        break;
74813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
74913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    default:
75013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        SL_LOGE("Sink data locator 0x%x not supported", (unsigned)sinkLocatorType);
75113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        break;
75213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    }
75313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
75413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    return type;
75513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi}
75613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
75713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
75813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi//-----------------------------------------------------------------------------
7597f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi/*
7607f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi * Callback associated with an SfPlayer of an SL ES AudioPlayer that gets its data
7615933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten * from a URI or FD, for prepare, prefetch, and play events
7627f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi */
76337dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivistatic void sfplayer_handlePrefetchEvent(int event, int data1, int data2, void* user) {
764c623c89c0a32c5fc77c998f1742d58e7be69e8c1Glenn Kasten
765c623c89c0a32c5fc77c998f1742d58e7be69e8c1Glenn Kasten    // FIXME see similar code and comment in player_handleMediaPlayerEventNotifications
766c623c89c0a32c5fc77c998f1742d58e7be69e8c1Glenn Kasten
767de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    if (NULL == user) {
768de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        return;
769de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    }
770f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi
771de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi    CAudioPlayer *ap = (CAudioPlayer *)user;
7726cce136651f6fd2c7aecd45bc553270152d75462Jean-Michel Trivi    if (!android::CallbackProtector::enterCbIfOk(ap->mCallbackProtector)) {
7736cce136651f6fd2c7aecd45bc553270152d75462Jean-Michel Trivi        // it is not safe to enter the callback (the track is about to go away)
7746cce136651f6fd2c7aecd45bc553270152d75462Jean-Michel Trivi        return;
7756cce136651f6fd2c7aecd45bc553270152d75462Jean-Michel Trivi    }
776b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten    union {
777b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten        char c[sizeof(int)];
778b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten        int i;
779b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten    } u;
780b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten    u.i = event;
781b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten    SL_LOGV("sfplayer_handlePrefetchEvent(event='%c%c%c%c' (%d), data1=%d, data2=%d, user=%p) from "
782b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten            "SfAudioPlayer", u.c[3], u.c[2], u.c[1], u.c[0], event, data1, data2, user);
783ac28eca1df49f581d952ffbda5d3019f7e3b7be6Glenn Kasten    switch (event) {
784f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi
78568d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi    case android::GenericPlayer::kEventPrepared: {
786796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten        SL_LOGV("Received GenericPlayer::kEventPrepared for CAudioPlayer %p", ap);
7873ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi
788796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten        // assume no callback
789796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten        slPrefetchCallback callback = NULL;
790796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten        void* callbackPContext;
791796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten        SLuint32 events;
792f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi
793796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten        object_lock_exclusive(&ap->mObject);
7943ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi
795796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten        // mark object as prepared; same state is used for successful or unsuccessful prepare
796796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten        assert(ap->mAndroidObjState == ANDROID_PREPARING);
797796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten        ap->mAndroidObjState = ANDROID_READY;
798f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi
799796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten        if (PLAYER_SUCCESS == data1) {
8007f250a17c145382b866d5d4d7ef23d65fada6236Glenn Kasten            // Most of successful prepare completion for ap->mAPlayer
8017f250a17c145382b866d5d4d7ef23d65fada6236Glenn Kasten            // is handled by GenericPlayer and its subclasses.
802796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten        } else {
803f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi            // SfPlayer prepare() failed prefetching, there is no event in SLPrefetchStatus to
804796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten            //  indicate a prefetch error, so we signal it by sending simultaneously two events:
805f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi            //  - SL_PREFETCHEVENT_FILLLEVELCHANGE with a level of 0
806f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi            //  - SL_PREFETCHEVENT_STATUSCHANGE with a status of SL_PREFETCHSTATUS_UNDERFLOW
807f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi            SL_LOGE(ERROR_PLAYER_PREFETCH_d, data1);
808b8fe327b1505778e82db76de930dd3f62ec99158Glenn Kasten            if (IsInterfaceInitialized(&ap->mObject, MPH_PREFETCHSTATUS)) {
809796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten                ap->mPrefetchStatus.mLevel = 0;
810796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten                ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_UNDERFLOW;
811796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten                if (!(~ap->mPrefetchStatus.mCallbackEventsMask &
812796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten                        (SL_PREFETCHEVENT_FILLLEVELCHANGE | SL_PREFETCHEVENT_STATUSCHANGE))) {
813796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten                    callback = ap->mPrefetchStatus.mCallback;
814796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten                    callbackPContext = ap->mPrefetchStatus.mContext;
815796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten                    events = SL_PREFETCHEVENT_FILLLEVELCHANGE | SL_PREFETCHEVENT_STATUSCHANGE;
816796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten                }
817f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi            }
818796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten        }
819f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi
820796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten        object_unlock_exclusive(&ap->mObject);
821f536948a85be5e3f3731b64b01cfacdf90ed1157Jean-Michel Trivi
822796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten        // callback with no lock held
823796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten        if (NULL != callback) {
824796eb075da9c84c5479bdd4dedd9c46c632e8e60Glenn Kasten            (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext, events);
8253ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi        }
8263ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi
82713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    }
82813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    break;
8293ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi
8304ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    case android::GenericPlayer::kEventPrefetchFillLevelUpdate : {
831b8fe327b1505778e82db76de930dd3f62ec99158Glenn Kasten        if (!IsInterfaceInitialized(&ap->mObject, MPH_PREFETCHSTATUS)) {
832a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi            break;
833a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi        }
834ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi        slPrefetchCallback callback = NULL;
835ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi        void* callbackPContext = NULL;
8368a1b7f28c1c3de212a302182022310ab7b227788Jean-Michel Trivi
837ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi        // SLPrefetchStatusItf callback or no callback?
838ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi        interface_lock_exclusive(&ap->mPrefetchStatus);
839ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi        if (ap->mPrefetchStatus.mCallbackEventsMask & SL_PREFETCHEVENT_FILLLEVELCHANGE) {
840ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi            callback = ap->mPrefetchStatus.mCallback;
841ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi            callbackPContext = ap->mPrefetchStatus.mContext;
842ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi        }
843ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi        ap->mPrefetchStatus.mLevel = (SLpermille)data1;
844ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi        interface_unlock_exclusive(&ap->mPrefetchStatus);
8458a1b7f28c1c3de212a302182022310ab7b227788Jean-Michel Trivi
846ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi        // callback with no lock held
847ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi        if (NULL != callback) {
848ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi            (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext,
849ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi                    SL_PREFETCHEVENT_FILLLEVELCHANGE);
850ff037a1f697a15fb4249e62fe783f22398572cbeJean-Michel Trivi        }
85113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    }
85213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    break;
853de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi
8544ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    case android::GenericPlayer::kEventPrefetchStatusChange: {
855b8fe327b1505778e82db76de930dd3f62ec99158Glenn Kasten        if (!IsInterfaceInitialized(&ap->mObject, MPH_PREFETCHSTATUS)) {
856a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi            break;
857a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi        }
85806a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        slPrefetchCallback callback = NULL;
859de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        void* callbackPContext = NULL;
8608a1b7f28c1c3de212a302182022310ab7b227788Jean-Michel Trivi
861de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        // SLPrefetchStatusItf callback or no callback?
8628a1b7f28c1c3de212a302182022310ab7b227788Jean-Michel Trivi        object_lock_exclusive(&ap->mObject);
863de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        if (ap->mPrefetchStatus.mCallbackEventsMask & SL_PREFETCHEVENT_STATUSCHANGE) {
864de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            callback = ap->mPrefetchStatus.mCallback;
865de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            callbackPContext = ap->mPrefetchStatus.mContext;
866de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        }
8674ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        if (data1 >= android::kStatusIntermediate) {
868de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_SUFFICIENTDATA;
8694ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        } else if (data1 < android::kStatusIntermediate) {
870de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_UNDERFLOW;
871de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        }
8728a1b7f28c1c3de212a302182022310ab7b227788Jean-Michel Trivi        object_unlock_exclusive(&ap->mObject);
8738a1b7f28c1c3de212a302182022310ab7b227788Jean-Michel Trivi
874de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi        // callback with no lock held
87506a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        if (NULL != callback) {
876de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi            (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext, SL_PREFETCHEVENT_STATUSCHANGE);
87706a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        }
87813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        }
87913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        break;
880de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi
8814ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    case android::GenericPlayer::kEventEndOfStream: {
882fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten        audioPlayer_dispatch_headAtEnd_lockPlay(ap, true /*set state to paused?*/, true);
88347550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten        if ((ap->mAudioTrack != 0) && (!ap->mSeek.mLoopEnabled)) {
8843ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi            ap->mAudioTrack->stop();
8853ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi        }
886143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        audioManagerPlayerEvent(ap, android::PLAYER_STATE_STOPPED);
88713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        }
88813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        break;
889de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi
890fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    case android::GenericPlayer::kEventChannelCount: {
891fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten        object_lock_exclusive(&ap->mObject);
892fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten        if (UNKNOWN_NUMCHANNELS == ap->mNumChannels && UNKNOWN_NUMCHANNELS != data1) {
893fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten            ap->mNumChannels = data1;
894fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten            android_audioPlayer_volumeUpdate(ap);
895fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten        }
896fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten        object_unlock_exclusive(&ap->mObject);
897fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten        }
898fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten        break;
899fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten
9005933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten    case android::GenericPlayer::kEventPlay: {
9015933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten        slPlayCallback callback = NULL;
9025933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten        void* callbackPContext = NULL;
9035933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten
9045933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten        interface_lock_shared(&ap->mPlay);
9055933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten        callback = ap->mPlay.mCallback;
9065933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten        callbackPContext = ap->mPlay.mContext;
9075933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten        interface_unlock_shared(&ap->mPlay);
9085933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten
9095933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten        if (NULL != callback) {
9105933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten            SLuint32 event = (SLuint32) data1;  // SL_PLAYEVENT_HEAD*
9115933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten#ifndef USE_ASYNCHRONOUS_PLAY_CALLBACK
9125933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten            // synchronous callback requires a synchronous GetPosition implementation
9135933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten            (*callback)(&ap->mPlay.mItf, callbackPContext, event);
9145933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten#else
9155933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten            // asynchronous callback works with any GetPosition implementation
9165933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten            SLresult result = EnqueueAsyncCallback_ppi(ap, callback, &ap->mPlay.mItf,
9175933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten                    callbackPContext, event);
9185933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten            if (SL_RESULT_SUCCESS != result) {
919a6c69c7e1665b38da8d6784e65210acbe501b92cSteve Block                ALOGW("Callback %p(%p, %p, 0x%x) dropped", callback,
9205933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten                        &ap->mPlay.mItf, callbackPContext, event);
9215933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten            }
9225933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten#endif
9235933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten        }
9245933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten        }
9255933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten        break;
9265933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten
9275e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten      case android::GenericPlayer::kEventErrorAfterPrepare: {
928513222822545c3e954176476b263df52a47f43a4Glenn Kasten        SL_LOGV("kEventErrorAfterPrepare");
9295e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten
9305e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten        // assume no callback
9315e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten        slPrefetchCallback callback = NULL;
9325e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten        void* callbackPContext = NULL;
9335e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten
9345e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten        object_lock_exclusive(&ap->mObject);
9355e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten        if (IsInterfaceInitialized(&ap->mObject, MPH_PREFETCHSTATUS)) {
9365e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten            ap->mPrefetchStatus.mLevel = 0;
9375e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten            ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_UNDERFLOW;
9385e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten            if (!(~ap->mPrefetchStatus.mCallbackEventsMask &
9395e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten                    (SL_PREFETCHEVENT_FILLLEVELCHANGE | SL_PREFETCHEVENT_STATUSCHANGE))) {
9405e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten                callback = ap->mPrefetchStatus.mCallback;
9415e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten                callbackPContext = ap->mPrefetchStatus.mContext;
9425e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten            }
9435e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten        }
9445e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten        object_unlock_exclusive(&ap->mObject);
9455e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten
9465e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten        // FIXME there's interesting information in data1, but no API to convey it to client
9475e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten        SL_LOGE("Error after prepare: %d", data1);
9485e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten
9495e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten        // callback with no lock held
9505e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten        if (NULL != callback) {
9515e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten            (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext,
9525e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten                    SL_PREFETCHEVENT_FILLLEVELCHANGE | SL_PREFETCHEVENT_STATUSCHANGE);
9535e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten        }
9545e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten
9555e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten      }
9565e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten      break;
9575e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten
958e2e8fa36bd7448b59fbcdf141e0b6d21e5401d91Glenn Kasten    case android::GenericPlayer::kEventHasVideoSize:
959e2e8fa36bd7448b59fbcdf141e0b6d21e5401d91Glenn Kasten        //SL_LOGW("Unexpected kEventHasVideoSize");
960e2e8fa36bd7448b59fbcdf141e0b6d21e5401d91Glenn Kasten        break;
9615e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten
9626a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    default:
9636a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
9646a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
9656cce136651f6fd2c7aecd45bc553270152d75462Jean-Michel Trivi
9666cce136651f6fd2c7aecd45bc553270152d75462Jean-Michel Trivi    ap->mCallbackProtector->exitCb();
967a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi}
968a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
969bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean// From EffectDownmix.h
970ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kastenstatic
971bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLeanconst uint32_t kSides = AUDIO_CHANNEL_OUT_SIDE_LEFT | AUDIO_CHANNEL_OUT_SIDE_RIGHT;
972ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kastenstatic
973bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLeanconst uint32_t kBacks = AUDIO_CHANNEL_OUT_BACK_LEFT | AUDIO_CHANNEL_OUT_BACK_RIGHT;
974ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kastenstatic
975bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLeanconst uint32_t kUnsupported =
976bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean        AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER | AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER |
977bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean        AUDIO_CHANNEL_OUT_TOP_CENTER |
978bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean        AUDIO_CHANNEL_OUT_TOP_FRONT_LEFT |
979bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean        AUDIO_CHANNEL_OUT_TOP_FRONT_CENTER |
980bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean        AUDIO_CHANNEL_OUT_TOP_FRONT_RIGHT |
981bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean        AUDIO_CHANNEL_OUT_TOP_BACK_LEFT |
982bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean        AUDIO_CHANNEL_OUT_TOP_BACK_CENTER |
983bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean        AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT;
984bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean
985ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kastenstatic
986ff25010cb77455a46357d6dd012631a2599d7bf4Glenn KastenSLresult android_audioPlayer_validateChannelMask(uint32_t mask, uint32_t numChans) {
987bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean    // Check that the number of channels falls within bounds.
988ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten    if (numChans == 0 || numChans > FCC_8) {
9894e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean        SL_LOGE("Number of channels %u must be between one and %u inclusive", numChans, FCC_8);
990bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean        return SL_RESULT_CONTENT_UNSUPPORTED;
991bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean    }
992bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean    // Are there the right number of channels in the mask?
9934e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean    if (sles_channel_count_from_mask(mask) != numChans) {
9944e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean        SL_LOGE("Channel mask %#x does not match channel count %u", mask, numChans);
995bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean        return SL_RESULT_CONTENT_UNSUPPORTED;
996bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean    }
9974e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean
9984e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean    audio_channel_representation_t representation =
9994e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean            sles_to_audio_channel_mask_representation(mask);
10004e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean
10014e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean    if (representation == AUDIO_CHANNEL_REPRESENTATION_INDEX) {
10024e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean        return SL_RESULT_SUCCESS;
1003bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean    }
10044e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean
10054e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean    // If audio is positional we need to run a set of checks to make sure
10064e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean    // the positions can be handled by our HDMI-compliant downmixer. Compare with
10074e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean    // android.media.AudioTrack.isMultichannelConfigSupported
10084e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean    // and Downmix_foldGeneric (in libeffects).
10094e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean    if (representation == AUDIO_CHANNEL_REPRESENTATION_POSITION) {
10104e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean        // check against unsupported channels
10114e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean        if (mask & kUnsupported) {
10124e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean            SL_LOGE("Mask %#x is invalid: Unsupported channels (top or front left/right of center)",
10134e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean                    mask);
1014bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean            return SL_RESULT_CONTENT_UNSUPPORTED;
1015bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean        }
10164e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean        // verify that mask has FL/FR if more than one channel specified
10174e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean        if (numChans > 1 && (mask & AUDIO_CHANNEL_OUT_STEREO) != AUDIO_CHANNEL_OUT_STEREO) {
10184e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean            SL_LOGE("Mask %#x is invalid: Front channels must be present", mask);
1019bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean            return SL_RESULT_CONTENT_UNSUPPORTED;
1020bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean        }
10214e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean        // verify that SIDE is used as a pair (ok if not using SIDE at all)
10224e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean        if ((mask & kSides) != 0 && (mask & kSides) != kSides) {
10234e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean                SL_LOGE("Mask %#x is invalid: Side channels must be used as a pair", mask);
10244e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean                return SL_RESULT_CONTENT_UNSUPPORTED;
10254e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean        }
10264e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean        // verify that BACK is used as a pair (ok if not using BACK at all)
10274e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean        if ((mask & kBacks) != 0 && (mask & kBacks) != kBacks) {
10284e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean            SL_LOGE("Mask %#x is invalid: Back channels must be used as a pair", mask);
10294e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean            return SL_RESULT_CONTENT_UNSUPPORTED;
10304e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean        }
10314e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean        return SL_RESULT_SUCCESS;
1032bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean    }
1033bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean
10344e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean    SL_LOGE("Unrecognized channel mask representation %#x", representation);
10354e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean    return SL_RESULT_CONTENT_UNSUPPORTED;
1036bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean}
103775e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
1038a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi//-----------------------------------------------------------------------------
1039d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel TriviSLresult android_audioPlayer_checkSourceSink(CAudioPlayer *pAudioPlayer)
1040c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi{
104113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    // verify that the locator types for the source / sink combination is supported
104213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    pAudioPlayer->mAndroidObjType = audioPlayer_getAndroidObjectTypeForSourceSink(pAudioPlayer);
104313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    if (INVALID_TYPE == pAudioPlayer->mAndroidObjType) {
1044c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        return SL_RESULT_PARAMETER_INVALID;
1045c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    }
1046c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
104713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    const SLDataSource *pAudioSrc = &pAudioPlayer->mDataSource.u.mSource;
104813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    const SLDataSink *pAudioSnk = &pAudioPlayer->mDataSink.u.mSink;
10494b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten
105013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    // format check:
105113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    const SLuint32 sourceLocatorType = *(SLuint32 *)pAudioSrc->pLocator;
105213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    const SLuint32 sinkLocatorType = *(SLuint32 *)pAudioSnk->pLocator;
105313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    const SLuint32 sourceFormatType = *(SLuint32 *)pAudioSrc->pFormat;
105413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
1055e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung    const SLuint32 *df_representation = NULL; // pointer to representation field, if it exists
1056e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung
105713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    switch (sourceLocatorType) {
1058c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //------------------
1059c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //   Buffer Queues
106001e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten    case SL_DATALOCATOR_BUFFERQUEUE:
106101e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten    case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
106201e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten        {
1063c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        // Buffer format
106413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        switch (sourceFormatType) {
1065a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        //     currently only PCM buffer queues are supported,
1066e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung        case SL_ANDROID_DATAFORMAT_PCM_EX: {
1067e05f49175a60182d29d0e38ee2a214854c279d95Glenn Kasten            const SLAndroidDataFormat_PCM_EX *df_pcm =
1068e05f49175a60182d29d0e38ee2a214854c279d95Glenn Kasten                    (const SLAndroidDataFormat_PCM_EX *) pAudioSrc->pFormat;
1069df9b397f73d8f063ff66e0fbf86ced075fe6d5aaGlenn Kasten            // checkDataFormat() already checked representation
1070df9b397f73d8f063ff66e0fbf86ced075fe6d5aaGlenn Kasten            df_representation = &df_pcm->representation;
107103d4a5ae486538839d02ae8a18e2a5c38bf1e2fbGlenn Kasten            } // SL_ANDROID_DATAFORMAT_PCM_EX - fall through to next test.
1072c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        case SL_DATAFORMAT_PCM: {
107371065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten            // checkDataFormat() already did generic checks, now do the Android-specific checks
1074e05f49175a60182d29d0e38ee2a214854c279d95Glenn Kasten            const SLDataFormat_PCM *df_pcm = (const SLDataFormat_PCM *) pAudioSrc->pFormat;
1075bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean            SLresult result = android_audioPlayer_validateChannelMask(df_pcm->channelMask,
1076bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean                                                                      df_pcm->numChannels);
1077bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean            if (result != SL_RESULT_SUCCESS) {
1078bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean                SL_LOGE("Cannot create audio player: unsupported PCM data source with %u channels",
1079bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean                        (unsigned) df_pcm->numChannels);
1080bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean                return result;
1081c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            }
1082bb74f23cd3dc877c7eaf4db2132f724d11aeeb8fPaul McLean
1083df9b397f73d8f063ff66e0fbf86ced075fe6d5aaGlenn Kasten            // checkDataFormat() already checked sample rate
1084df9b397f73d8f063ff66e0fbf86ced075fe6d5aaGlenn Kasten
1085df9b397f73d8f063ff66e0fbf86ced075fe6d5aaGlenn Kasten            // checkDataFormat() already checked bits per sample, container size, and representation
1086ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten
1087ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten            // FIXME confirm the following
10881452b38f9f4a8a0d76c936c393c794f3995526b6Glenn Kasten            // df_pcm->channelMask: the earlier platform-independent check and the
10891452b38f9f4a8a0d76c936c393c794f3995526b6Glenn Kasten            //     upcoming check by sles_to_android_channelMaskOut are sufficient
1090a80a6ff9a1f80792478c9d43578afa24a07eb2f0Glenn Kasten
1091a80a6ff9a1f80792478c9d43578afa24a07eb2f0Glenn Kasten            if (df_pcm->endianness != pAudioPlayer->mObject.mEngine->mEngine.mNativeEndianness) {
109271065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten                SL_LOGE("Cannot create audio player: unsupported byte order %u",
109371065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten                        df_pcm->endianness);
1094c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi                return SL_RESULT_CONTENT_UNSUPPORTED;
1095c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            }
109671065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten
109771065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten            // we don't support container size != sample depth
109871065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten            if (df_pcm->containerSize != df_pcm->bitsPerSample) {
109971065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten                SL_LOGE("Cannot create audio player: unsupported container size %u bits for "
110071065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten                        "sample depth %u bits",
110171065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten                        df_pcm->containerSize, (SLuint32)df_pcm->bitsPerSample);
110271065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten                return SL_RESULT_CONTENT_UNSUPPORTED;
110371065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten            }
110471065fbf12abafd4c2a0dc85c81f13b564ff69fbGlenn Kasten
1105c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            } //case SL_DATAFORMAT_PCM
1106c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            break;
1107c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        case SL_DATAFORMAT_MIME:
11088b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten        case XA_DATAFORMAT_RAWIMAGE:
110901e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten            SL_LOGE("Cannot create audio player with buffer queue data source "
111049e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten                "without SL_DATAFORMAT_PCM format");
1111c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi            return SL_RESULT_CONTENT_UNSUPPORTED;
1112c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        default:
11138b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten            // invalid data format is detected earlier
11148b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten            assert(false);
11158b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten            return SL_RESULT_INTERNAL_ERROR;
111613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        } // switch (sourceFormatType)
111701e9f5fa4698856f92bcfd88188ee4c8397b22dbGlenn Kasten        } // case SL_DATALOCATOR_BUFFERQUEUE or SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE
1118c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        break;
1119c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //------------------
11206fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi    //   URI
11216fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi    case SL_DATALOCATOR_URI:
11226fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        {
112322ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten        SLDataLocator_URI *dl_uri = (SLDataLocator_URI *) pAudioSrc->pLocator;
1124989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        if (NULL == dl_uri->URI) {
1125989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi            return SL_RESULT_PARAMETER_INVALID;
1126989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        }
1127989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        // URI format
112813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        switch (sourceFormatType) {
1129989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        case SL_DATAFORMAT_MIME:
1130989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi            break;
113109aeff183fa1353298c47fcb18ff33b0d08a990dGlenn Kasten        default:
1132337aff43154e6f8e2f94e569d33a5b135de70f2bGlenn Kasten            SL_LOGE("Cannot create audio player with SL_DATALOCATOR_URI data source without "
113349e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten                "SL_DATAFORMAT_MIME format");
1134989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi            return SL_RESULT_CONTENT_UNSUPPORTED;
113513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        } // switch (sourceFormatType)
113613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        // decoding format check
113713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        if ((sinkLocatorType != SL_DATALOCATOR_OUTPUTMIX) &&
113813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                !audioPlayer_isSupportedNonOutputMixSink(pAudioSnk)) {
113913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            return SL_RESULT_CONTENT_UNSUPPORTED;
114013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        }
11416fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        } // case SL_DATALOCATOR_URI
11426fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi        break;
11436fff2c605cdc46a10037e011d8fb47702ae70c37Jean-Michel Trivi    //------------------
1144989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi    //   File Descriptor
1145989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi    case SL_DATALOCATOR_ANDROIDFD:
1146989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        {
1147989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        // fd is already non null
114813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        switch (sourceFormatType) {
1149989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        case SL_DATAFORMAT_MIME:
1150989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi            break;
115109aeff183fa1353298c47fcb18ff33b0d08a990dGlenn Kasten        default:
1152337aff43154e6f8e2f94e569d33a5b135de70f2bGlenn Kasten            SL_LOGE("Cannot create audio player with SL_DATALOCATOR_ANDROIDFD data source "
115309aeff183fa1353298c47fcb18ff33b0d08a990dGlenn Kasten                "without SL_DATAFORMAT_MIME format");
1154989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi            return SL_RESULT_CONTENT_UNSUPPORTED;
115513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        } // switch (sourceFormatType)
115613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        if ((sinkLocatorType != SL_DATALOCATOR_OUTPUTMIX) &&
115713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                !audioPlayer_isSupportedNonOutputMixSink(pAudioSnk)) {
115813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            return SL_RESULT_CONTENT_UNSUPPORTED;
115913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        }
1160989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        } // case SL_DATALOCATOR_ANDROIDFD
1161989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        break;
1162989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi    //------------------
1163fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    //   Stream
1164fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi    case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
1165d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    {
1166d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        switch (sourceFormatType) {
1167d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        case SL_DATAFORMAT_MIME:
1168fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi        {
1169d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            SLDataFormat_MIME *df_mime = (SLDataFormat_MIME *) pAudioSrc->pFormat;
1170bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi            if (NULL == df_mime) {
1171bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi                SL_LOGE("MIME type null invalid");
1172bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi                return SL_RESULT_CONTENT_UNSUPPORTED;
1173bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi            }
1174bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi            SL_LOGD("source MIME is %s", (char*)df_mime->mimeType);
1175ac28eca1df49f581d952ffbda5d3019f7e3b7be6Glenn Kasten            switch (df_mime->containerType) {
1176bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi            case SL_CONTAINERTYPE_MPEG_TS:
1177c3b82a293ed06001ba6d50f111608160c6065ef2Glenn Kasten                if (strcasecmp((char*)df_mime->mimeType, (const char *)XA_ANDROID_MIME_MP2TS)) {
1178bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi                    SL_LOGE("Invalid MIME (%s) for container SL_CONTAINERTYPE_MPEG_TS, expects %s",
1179c3b82a293ed06001ba6d50f111608160c6065ef2Glenn Kasten                            (char*)df_mime->mimeType, XA_ANDROID_MIME_MP2TS);
1180bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi                    return SL_RESULT_CONTENT_UNSUPPORTED;
1181bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi                }
118236c0711b6919c2185a4d6e514d7f421b0d9c7bc6Martin Storsjo                if (pAudioPlayer->mAndroidObjType != AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE) {
118336c0711b6919c2185a4d6e514d7f421b0d9c7bc6Martin Storsjo                    SL_LOGE("Invalid sink for container SL_CONTAINERTYPE_MPEG_TS");
118436c0711b6919c2185a4d6e514d7f421b0d9c7bc6Martin Storsjo                    return SL_RESULT_PARAMETER_INVALID;
118536c0711b6919c2185a4d6e514d7f421b0d9c7bc6Martin Storsjo                }
1186bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi                break;
1187bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi            case SL_CONTAINERTYPE_RAW:
1188bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi            case SL_CONTAINERTYPE_AAC:
1189c3b82a293ed06001ba6d50f111608160c6065ef2Glenn Kasten                if (strcasecmp((char*)df_mime->mimeType, (const char *)SL_ANDROID_MIME_AACADTS) &&
1190bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi                        strcasecmp((char*)df_mime->mimeType,
1191bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi                                ANDROID_MIME_AACADTS_ANDROID_FRAMEWORK)) {
1192bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi                    SL_LOGE("Invalid MIME (%s) for container type %d, expects %s",
1193bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi                            (char*)df_mime->mimeType, df_mime->containerType,
1194c3b82a293ed06001ba6d50f111608160c6065ef2Glenn Kasten                            SL_ANDROID_MIME_AACADTS);
1195bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi                    return SL_RESULT_CONTENT_UNSUPPORTED;
1196bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi                }
119736c0711b6919c2185a4d6e514d7f421b0d9c7bc6Martin Storsjo                if (pAudioPlayer->mAndroidObjType != AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE) {
119836c0711b6919c2185a4d6e514d7f421b0d9c7bc6Martin Storsjo                    SL_LOGE("Invalid sink for container SL_CONTAINERTYPE_AAC");
119936c0711b6919c2185a4d6e514d7f421b0d9c7bc6Martin Storsjo                    return SL_RESULT_PARAMETER_INVALID;
120036c0711b6919c2185a4d6e514d7f421b0d9c7bc6Martin Storsjo                }
1201bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi                break;
1202bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi            default:
1203d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi                SL_LOGE("Cannot create player with SL_DATALOCATOR_ANDROIDBUFFERQUEUE data source "
1204bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi                                        "that is not fed MPEG-2 TS data or AAC ADTS data");
1205d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi                return SL_RESULT_CONTENT_UNSUPPORTED;
1206d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            }
1207d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        }
1208fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi        break;
1209d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        default:
1210d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            SL_LOGE("Cannot create player with SL_DATALOCATOR_ANDROIDBUFFERQUEUE data source "
1211d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi                    "without SL_DATAFORMAT_MIME format");
1212d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            return SL_RESULT_CONTENT_UNSUPPORTED;
1213d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        }
1214d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    }
1215d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    break; // case SL_DATALOCATOR_ANDROIDBUFFERQUEUE
1216fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    //------------------
1217c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    //   Address
1218c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_ADDRESS:
1219c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_IODEVICE:
1220c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_OUTPUTMIX:
12218b8875067dd02b79361abb00c5d65b02a8ae72b0Glenn Kasten    case XA_DATALOCATOR_NATIVEDISPLAY:
1222c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    case SL_DATALOCATOR_MIDIBUFFERQUEUE:
122313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        SL_LOGE("Cannot create audio player with data locator type 0x%x",
122413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                (unsigned) sourceLocatorType);
1225c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        return SL_RESULT_CONTENT_UNSUPPORTED;
1226c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    default:
1227fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi        SL_LOGE("Cannot create audio player with invalid data locator type 0x%x",
122813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                (unsigned) sourceLocatorType);
1229c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi        return SL_RESULT_PARAMETER_INVALID;
1230c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    }// switch (locatorType)
1231c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
1232c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi    return SL_RESULT_SUCCESS;
1233c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi}
1234c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
1235773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi
1236a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi//-----------------------------------------------------------------------------
12371ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi// Callback associated with an AudioTrack of an SL ES AudioPlayer that gets its data
123883ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi// from a buffer queue. This will not be called once the AudioTrack has been destroyed.
1239a84c5e20d9884d7ec7e4b1377a328c1d1a552b70Glenn Kastenstatic void audioTrack_callBack_pullFromBuffQueue(int event, void* user, void *info) {
1240e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi    CAudioPlayer *ap = (CAudioPlayer *)user;
124183ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi
12426cce136651f6fd2c7aecd45bc553270152d75462Jean-Michel Trivi    if (!android::CallbackProtector::enterCbIfOk(ap->mCallbackProtector)) {
124383ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi        // it is not safe to enter the callback (the track is about to go away)
124483ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi        return;
124583ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi    }
124683ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi
12478f4f78fd27806e013065e675a7cf056172d9b6dcJean-Michel Trivi    void * callbackPContext = NULL;
1248ac28eca1df49f581d952ffbda5d3019f7e3b7be6Glenn Kasten    switch (event) {
12496a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
125013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    case android::AudioTrack::EVENT_MORE_DATA: {
125183ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi        //SL_LOGV("received event EVENT_MORE_DATA from AudioTrack TID=%d", gettid());
1252a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten        slPrefetchCallback prefetchCallback = NULL;
1253a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten        void *prefetchContext = NULL;
1254a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten        SLuint32 prefetchEvents = SL_PREFETCHEVENT_NONE;
12551ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi        android::AudioTrack::Buffer* pBuff = (android::AudioTrack::Buffer*)info;
125683ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi
12571ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi        // retrieve data from the buffer queue
1258e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        interface_lock_exclusive(&ap->mBufferQueue);
125983ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi
12600f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien        if (ap->mBufferQueue.mCallbackPending) {
12610f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien            // call callback with lock not held
12620f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien            slBufferQueueCallback callback = ap->mBufferQueue.mCallback;
12630f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien            if (NULL != callback) {
12640f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien                callbackPContext = ap->mBufferQueue.mContext;
12650f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien                interface_unlock_exclusive(&ap->mBufferQueue);
12660f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien                (*callback)(&ap->mBufferQueue.mItf, callbackPContext);
12670f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien                interface_lock_exclusive(&ap->mBufferQueue);
12680f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien                ap->mBufferQueue.mCallbackPending = false;
12690f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien            }
12700f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien        }
12710f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien
1272e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        if (ap->mBufferQueue.mState.count != 0) {
1273a8179ea15c4ff78db589d742b135649f0eda7ef2Glenn Kasten            //SL_LOGV("nbBuffers in queue = %u",ap->mBufferQueue.mState.count);
1274e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi            assert(ap->mBufferQueue.mFront != ap->mBufferQueue.mRear);
12751ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
1276e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi            BufferHeader *oldFront = ap->mBufferQueue.mFront;
1277d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten            BufferHeader *newFront = &oldFront[1];
12781ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
12790f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien            size_t availSource = oldFront->mSize - ap->mBufferQueue.mSizeConsumed;
12800f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien            size_t availSink = pBuff->size;
12810f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien            size_t bytesToCopy = availSource < availSink ? availSource : availSink;
12821452b38f9f4a8a0d76c936c393c794f3995526b6Glenn Kasten            void *pSrc = (char *)oldFront->mBuffer + ap->mBufferQueue.mSizeConsumed;
12830f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien            memcpy(pBuff->raw, pSrc, bytesToCopy);
12840f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien
12850f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien            if (bytesToCopy < availSource) {
12860f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien                ap->mBufferQueue.mSizeConsumed += bytesToCopy;
12870f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien                // pBuff->size is already equal to bytesToCopy in this case
12881ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            } else {
12890f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien                // consumed an entire buffer, dequeue
12900f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien                pBuff->size = bytesToCopy;
1291e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi                ap->mBufferQueue.mSizeConsumed = 0;
12921ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                if (newFront ==
1293e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi                        &ap->mBufferQueue.mArray
1294e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi                            [ap->mBufferQueue.mNumBuffers + 1])
12951ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                {
1296e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi                    newFront = ap->mBufferQueue.mArray;
12971ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi                }
1298e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi                ap->mBufferQueue.mFront = newFront;
12991ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
1300e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi                ap->mBufferQueue.mState.count--;
1301e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi                ap->mBufferQueue.mState.playIndex++;
13020f6da1a299c8dd924d19714ee69d343915c32d2cRaph Levien                ap->mBufferQueue.mCallbackPending = true;
13031ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            }
1304e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        } else { // empty queue
1305e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi            // signal no data available
13061ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi            pBuff->size = 0;
1307e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi
1308e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi            // signal we're at the end of the content, but don't pause (see note in function)
1309fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten            audioPlayer_dispatch_headAtEnd_lockPlay(ap, false /*set state to paused?*/, false);
1310e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi
1311a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi            // signal underflow to prefetch status itf
1312b8fe327b1505778e82db76de930dd3f62ec99158Glenn Kasten            if (IsInterfaceInitialized(&ap->mObject, MPH_PREFETCHSTATUS)) {
1313a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten                ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_UNDERFLOW;
1314a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten                ap->mPrefetchStatus.mLevel = 0;
1315a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten                // callback or no callback?
1316a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten                prefetchEvents = ap->mPrefetchStatus.mCallbackEventsMask &
1317a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten                        (SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE);
1318a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten                if (SL_PREFETCHEVENT_NONE != prefetchEvents) {
1319a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten                    prefetchCallback = ap->mPrefetchStatus.mCallback;
1320a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten                    prefetchContext  = ap->mPrefetchStatus.mContext;
1321a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten                }
1322a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi            }
1323a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi
1324e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi            // stop the track so it restarts playing faster when new data is enqueued
1325e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi            ap->mAudioTrack->stop();
1326143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi            audioManagerPlayerEvent(ap, android::PLAYER_STATE_STOPPED);
13271ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi        }
1328e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        interface_unlock_exclusive(&ap->mBufferQueue);
132983ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi
133006a1b91fb42d3ecc9da725e673b56ca849b9b9a4Jean-Michel Trivi        // notify client
1331a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten        if (NULL != prefetchCallback) {
1332a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten            assert(SL_PREFETCHEVENT_NONE != prefetchEvents);
1333a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten            // spec requires separate callbacks for each event
1334a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten            if (prefetchEvents & SL_PREFETCHEVENT_STATUSCHANGE) {
1335a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten                (*prefetchCallback)(&ap->mPrefetchStatus.mItf, prefetchContext,
1336a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten                        SL_PREFETCHEVENT_STATUSCHANGE);
1337a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten            }
1338a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten            if (prefetchEvents & SL_PREFETCHEVENT_FILLLEVELCHANGE) {
1339a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten                (*prefetchCallback)(&ap->mPrefetchStatus.mItf, prefetchContext,
1340a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten                        SL_PREFETCHEVENT_FILLLEVELCHANGE);
1341a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten            }
1342a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten        }
13436a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
13446a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    break;
13451ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
134613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    case android::AudioTrack::EVENT_MARKER:
134783ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi        //SL_LOGI("received event EVENT_MARKER from AudioTrack");
1348e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        audioTrack_handleMarker_lockPlay(ap);
13494614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        break;
13506a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
135113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    case android::AudioTrack::EVENT_NEW_POS:
135283ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi        //SL_LOGI("received event EVENT_NEW_POS from AudioTrack");
1353e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        audioTrack_handleNewPos_lockPlay(ap);
13544614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        break;
13556a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
135613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    case android::AudioTrack::EVENT_UNDERRUN:
135783ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi        //SL_LOGI("received event EVENT_UNDERRUN from AudioTrack");
1358e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        audioTrack_handleUnderrun_lockPlay(ap);
13594614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        break;
13606a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
13619f3ac83aa036a780ca901f9ff75e47a5a7cbba1fGlenn Kasten    case android::AudioTrack::EVENT_NEW_IAUDIOTRACK:
13629f3ac83aa036a780ca901f9ff75e47a5a7cbba1fGlenn Kasten        // ignore for now
13639f3ac83aa036a780ca901f9ff75e47a5a7cbba1fGlenn Kasten        break;
13649f3ac83aa036a780ca901f9ff75e47a5a7cbba1fGlenn Kasten
1365e2e8fa36bd7448b59fbcdf141e0b6d21e5401d91Glenn Kasten    case android::AudioTrack::EVENT_BUFFER_END:
1366e2e8fa36bd7448b59fbcdf141e0b6d21e5401d91Glenn Kasten    case android::AudioTrack::EVENT_LOOP_END:
13679f3ac83aa036a780ca901f9ff75e47a5a7cbba1fGlenn Kasten    case android::AudioTrack::EVENT_STREAM_END:
1368e2e8fa36bd7448b59fbcdf141e0b6d21e5401d91Glenn Kasten        // These are unexpected so fall through
13696a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    default:
1370e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        // FIXME where does the notification of SL_PLAYEVENT_HEADMOVING fit?
1371b44084fdb096a2662085af0199b69ccb0dce5c30Jean-Michel Trivi        SL_LOGE("Encountered unknown AudioTrack event %d for CAudioPlayer %p", event,
1372b44084fdb096a2662085af0199b69ccb0dce5c30Jean-Michel Trivi                (CAudioPlayer *)user);
13736a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
13741ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi    }
137583ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi
13766cce136651f6fd2c7aecd45bc553270152d75462Jean-Michel Trivi    ap->mCallbackProtector->exitCb();
13771ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi}
13781ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
13791ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi
13801ae30e37f39fcfe7937a707b789e49a7d68112baJean-Michel Trivi//-----------------------------------------------------------------------------
138172042d4448cee63528c619537321ba73944c6382Glenn Kastenvoid android_audioPlayer_create(CAudioPlayer *pAudioPlayer) {
1382773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi
138372042d4448cee63528c619537321ba73944c6382Glenn Kasten    // pAudioPlayer->mAndroidObjType has been set in android_audioPlayer_checkSourceSink()
138472042d4448cee63528c619537321ba73944c6382Glenn Kasten    // and if it was == INVALID_TYPE, then IEngine_CreateAudioPlayer would never call us
138572042d4448cee63528c619537321ba73944c6382Glenn Kasten    assert(INVALID_TYPE != pAudioPlayer->mAndroidObjType);
1386c116ab2a033ee7dc78cfd458defe38d4528383a8Jean-Michel Trivi
138772042d4448cee63528c619537321ba73944c6382Glenn Kasten    // These initializations are in the same order as the field declarations in classes.h
138847550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten
138972042d4448cee63528c619537321ba73944c6382Glenn Kasten    // FIXME Consolidate initializations (many of these already in IEngine_CreateAudioPlayer)
139072042d4448cee63528c619537321ba73944c6382Glenn Kasten    // mAndroidObjType: see above comment
139172042d4448cee63528c619537321ba73944c6382Glenn Kasten    pAudioPlayer->mAndroidObjState = ANDROID_UNINITIALIZED;
1392213c31153b9bda7b5a091f2996da7b655c8ed451Glenn Kasten    pAudioPlayer->mSessionId = (audio_session_t) android::AudioSystem::newAudioUniqueId(
1393213c31153b9bda7b5a091f2996da7b655c8ed451Glenn Kasten            AUDIO_UNIQUE_ID_USE_SESSION);
1394143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi    pAudioPlayer->mPIId = PLAYER_PIID_INVALID;
1395de16b4c2bc71c163c7c821a475a53a3b567789b2Jean-Michel Trivi
139672042d4448cee63528c619537321ba73944c6382Glenn Kasten    // placeholder: not necessary yet as session ID lifetime doesn't extend beyond player
139772042d4448cee63528c619537321ba73944c6382Glenn Kasten    // android::AudioSystem::acquireAudioSessionId(pAudioPlayer->mSessionId);
139883ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi
139972042d4448cee63528c619537321ba73944c6382Glenn Kasten    pAudioPlayer->mStreamType = ANDROID_DEFAULT_OUTPUT_STREAM_TYPE;
14008c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    pAudioPlayer->mPerformanceMode = ANDROID_PERFORMANCE_MODE_DEFAULT;
1401a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten
140272042d4448cee63528c619537321ba73944c6382Glenn Kasten    // mAudioTrack
140372042d4448cee63528c619537321ba73944c6382Glenn Kasten    pAudioPlayer->mCallbackProtector = new android::CallbackProtector();
140472042d4448cee63528c619537321ba73944c6382Glenn Kasten    // mAPLayer
140572042d4448cee63528c619537321ba73944c6382Glenn Kasten    // mAuxEffect
1406e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten
140772042d4448cee63528c619537321ba73944c6382Glenn Kasten    pAudioPlayer->mAuxSendLevel = 0;
140872042d4448cee63528c619537321ba73944c6382Glenn Kasten    pAudioPlayer->mAmplFromDirectLevel = 1.0f; // matches initial mDirectLevel value
140972042d4448cee63528c619537321ba73944c6382Glenn Kasten    pAudioPlayer->mDeferredStart = false;
14106d78c9bfb68f8a0db1855bc28c087c39a7eb6f2cGlenn Kasten
141172042d4448cee63528c619537321ba73944c6382Glenn Kasten    // This section re-initializes interface-specific fields that
141272042d4448cee63528c619537321ba73944c6382Glenn Kasten    // can be set or used regardless of whether the interface is
141372042d4448cee63528c619537321ba73944c6382Glenn Kasten    // exposed on the AudioPlayer or not
14146d78c9bfb68f8a0db1855bc28c087c39a7eb6f2cGlenn Kasten
141572042d4448cee63528c619537321ba73944c6382Glenn Kasten    switch (pAudioPlayer->mAndroidObjType) {
141672042d4448cee63528c619537321ba73944c6382Glenn Kasten    case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
141772042d4448cee63528c619537321ba73944c6382Glenn Kasten        pAudioPlayer->mPlaybackRate.mMinRate = AUDIOTRACK_MIN_PLAYBACKRATE_PERMILLE;
141872042d4448cee63528c619537321ba73944c6382Glenn Kasten        pAudioPlayer->mPlaybackRate.mMaxRate = AUDIOTRACK_MAX_PLAYBACKRATE_PERMILLE;
141972042d4448cee63528c619537321ba73944c6382Glenn Kasten        break;
142091145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi    case AUDIOPLAYER_FROM_URIFD:
142191145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi        pAudioPlayer->mPlaybackRate.mMinRate = MEDIAPLAYER_MIN_PLAYBACKRATE_PERMILLE;
142291145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi        pAudioPlayer->mPlaybackRate.mMaxRate = MEDIAPLAYER_MAX_PLAYBACKRATE_PERMILLE;
142391145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi        break;
142472042d4448cee63528c619537321ba73944c6382Glenn Kasten    default:
142572042d4448cee63528c619537321ba73944c6382Glenn Kasten        // use the default range
142672042d4448cee63528c619537321ba73944c6382Glenn Kasten        break;
142713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    }
142824430c9070298f12e68b84c921add38da6ad0490Jean-Michel Trivi
1429773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi}
1430773e0429cbb9e85b4f1c6eb5a095ccd7b57f5ba4Jean-Michel Trivi
1431a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
1432a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi//-----------------------------------------------------------------------------
143375e22870e41386cdc597bd29c76744d74d4c22adJean-Michel TriviSLresult android_audioPlayer_setConfig(CAudioPlayer *ap, const SLchar *configKey,
143475e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        const void *pConfigValue, SLuint32 valueSize) {
143575e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
1436c2a325746469c4c7625ec78a169b65a11dbe1e30Glenn Kasten    SLresult result;
143775e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
1438c2a325746469c4c7625ec78a169b65a11dbe1e30Glenn Kasten    assert(NULL != ap && NULL != configKey && NULL != pConfigValue);
1439ca426f63e9c900ecbd28f8e3037aaf47ef739dd4Glenn Kasten    if (strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_STREAM_TYPE) == 0) {
144075e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
144175e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        // stream type
144275e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        if (KEY_STREAM_TYPE_PARAMSIZE > valueSize) {
144375e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi            SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW);
1444c2a325746469c4c7625ec78a169b65a11dbe1e30Glenn Kasten            result = SL_RESULT_BUFFER_INSUFFICIENT;
144575e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        } else {
144675e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi            result = audioPlayer_setStreamType(ap, *(SLuint32*)pConfigValue);
144775e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        }
14488c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    } else if (strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_PERFORMANCE_MODE) == 0) {
14498c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent
14508c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        // performance mode
14518c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        if (KEY_PERFORMANCE_MODE_PARAMSIZE > valueSize) {
14528c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW);
14538c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            result = SL_RESULT_BUFFER_INSUFFICIENT;
14548c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        } else {
14558c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            result = audioPlayer_setPerformanceMode(ap, *(SLuint32*)pConfigValue);
14568c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        }
145775e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
145875e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    } else {
145975e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        SL_LOGE(ERROR_CONFIG_UNKNOWN_KEY);
146075e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        result = SL_RESULT_PARAMETER_INVALID;
146175e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    }
146275e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
146375e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    return result;
146475e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi}
146575e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
146675e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
146775e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi//-----------------------------------------------------------------------------
146875e22870e41386cdc597bd29c76744d74d4c22adJean-Michel TriviSLresult android_audioPlayer_getConfig(CAudioPlayer* ap, const SLchar *configKey,
146975e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        SLuint32* pValueSize, void *pConfigValue) {
147075e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
1471c2a325746469c4c7625ec78a169b65a11dbe1e30Glenn Kasten    SLresult result;
147275e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
1473c2a325746469c4c7625ec78a169b65a11dbe1e30Glenn Kasten    assert(NULL != ap && NULL != configKey && NULL != pValueSize);
1474ca426f63e9c900ecbd28f8e3037aaf47ef739dd4Glenn Kasten    if (strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_STREAM_TYPE) == 0) {
147575e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
147675e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        // stream type
1477c2a325746469c4c7625ec78a169b65a11dbe1e30Glenn Kasten        if (NULL == pConfigValue) {
1478c2a325746469c4c7625ec78a169b65a11dbe1e30Glenn Kasten            result = SL_RESULT_SUCCESS;
1479c2a325746469c4c7625ec78a169b65a11dbe1e30Glenn Kasten        } else if (KEY_STREAM_TYPE_PARAMSIZE > *pValueSize) {
148075e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi            SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW);
1481c2a325746469c4c7625ec78a169b65a11dbe1e30Glenn Kasten            result = SL_RESULT_BUFFER_INSUFFICIENT;
148275e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        } else {
1483c2a325746469c4c7625ec78a169b65a11dbe1e30Glenn Kasten            result = audioPlayer_getStreamType(ap, (SLint32*)pConfigValue);
148475e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        }
1485c2a325746469c4c7625ec78a169b65a11dbe1e30Glenn Kasten        *pValueSize = KEY_STREAM_TYPE_PARAMSIZE;
148675e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
14878c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    } else if (strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_PERFORMANCE_MODE) == 0) {
14888c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent
14898c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        // performance mode
14908c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        if (NULL == pConfigValue) {
14918c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            result = SL_RESULT_SUCCESS;
14928c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        } else if (KEY_PERFORMANCE_MODE_PARAMSIZE > *pValueSize) {
14938c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW);
14948c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            result = SL_RESULT_BUFFER_INSUFFICIENT;
14958c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        } else {
14968c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            result = audioPlayer_getPerformanceMode(ap, (SLuint32*)pConfigValue);
14978c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        }
14988c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        *pValueSize = KEY_PERFORMANCE_MODE_PARAMSIZE;
14998c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent
150075e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    } else {
150175e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        SL_LOGE(ERROR_CONFIG_UNKNOWN_KEY);
150275e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi        result = SL_RESULT_PARAMETER_INVALID;
150375e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    }
150475e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
150575e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi    return result;
150675e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi}
150775e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
150875e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi
15098c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent// Called from android_audioPlayer_realize for a PCM buffer queue player before creating the
15108c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent// AudioTrack to determine which performance modes are allowed based on effect interfaces present
15118c9071f491393fadf767b6164a17b0795eba3fdaEric Laurentstatic void checkAndSetPerformanceModePre(CAudioPlayer *pAudioPlayer)
15127880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten{
15138c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    SLuint32 allowedModes = ANDROID_PERFORMANCE_MODE_ALL;
15147880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    assert(pAudioPlayer->mAndroidObjType == AUDIOPLAYER_FROM_PCM_BUFFERQUEUE);
151592e53bc98cd938e9917fb02d3e5a9be88423791dGlenn Kasten
151692e53bc98cd938e9917fb02d3e5a9be88423791dGlenn Kasten    // no need to check the buffer queue size, application side
151792e53bc98cd938e9917fb02d3e5a9be88423791dGlenn Kasten    // double-buffering (and more) is not a requirement for using fast tracks
15187880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten
15197880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    // Check a blacklist of interfaces that are incompatible with fast tracks.
15207880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    // The alternative, to check a whitelist of compatible interfaces, is
15217880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    // more maintainable but is too slow.  As a compromise, in a debug build
15227880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    // we use both methods and warn if they produce different results.
15237880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    // In release builds, we only use the blacklist method.
15247880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    // If a blacklisted interface is added after realization using
15257880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    // DynamicInterfaceManagement::AddInterface,
15267880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    // then this won't be detected but the interface will be ineffective.
15277880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    static const unsigned blacklist[] = {
15287880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        MPH_BASSBOOST,
15297880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        MPH_EFFECTSEND,
15307880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        MPH_ENVIRONMENTALREVERB,
15317880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        MPH_EQUALIZER,
15327880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        MPH_PLAYBACKRATE,
15337880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        MPH_PRESETREVERB,
15347880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        MPH_VIRTUALIZER,
15357880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        MPH_ANDROIDEFFECT,
15367880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        MPH_ANDROIDEFFECTSEND,
15377880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        // FIXME The problem with a blacklist is remembering to add new interfaces here
15387880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    };
15397880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    for (unsigned i = 0; i < sizeof(blacklist)/sizeof(blacklist[0]); ++i) {
15407880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        if (IsInterfaceInitialized(&pAudioPlayer->mObject, blacklist[i])) {
15418c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            //TODO: query effect for EFFECT_FLAG_HW_ACC_xx flag to refine mode
15428c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            allowedModes &=
15438c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent                    ~(ANDROID_PERFORMANCE_MODE_LATENCY|ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS);
15447880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten            break;
15457880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        }
15467880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    }
15477880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten#if LOG_NDEBUG == 0
15488c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    bool blacklistResult = (
15498c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            (allowedModes &
15508c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent                (ANDROID_PERFORMANCE_MODE_LATENCY|ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS)) != 0);
15517880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    bool whitelistResult = true;
15527880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    static const unsigned whitelist[] = {
15537880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        MPH_BUFFERQUEUE,
15547880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        MPH_DYNAMICINTERFACEMANAGEMENT,
15557880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        MPH_METADATAEXTRACTION,
155678e61e01307d62bd04283ada99ce5df1c647810dGlenn Kasten        MPH_MUTESOLO,
155778e61e01307d62bd04283ada99ce5df1c647810dGlenn Kasten        MPH_OBJECT,
15587880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        MPH_PLAY,
15597880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        MPH_PREFETCHSTATUS,
156078e61e01307d62bd04283ada99ce5df1c647810dGlenn Kasten        MPH_VOLUME,
15617880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        MPH_ANDROIDCONFIGURATION,
15627880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        MPH_ANDROIDSIMPLEBUFFERQUEUE,
15637880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        MPH_ANDROIDBUFFERQUEUESOURCE,
15647880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    };
15657880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    for (unsigned mph = MPH_MIN; mph < MPH_MAX; ++mph) {
15667880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        for (unsigned i = 0; i < sizeof(whitelist)/sizeof(whitelist[0]); ++i) {
15677880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten            if (mph == whitelist[i]) {
15687880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten                goto compatible;
15697880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten            }
15707880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        }
15717880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        if (IsInterfaceInitialized(&pAudioPlayer->mObject, mph)) {
15727880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten            whitelistResult = false;
15737880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten            break;
15747880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        }
15757880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kastencompatible: ;
15767880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    }
15777880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    if (whitelistResult != blacklistResult) {
15784e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean        SL_LOGW("whitelistResult != blacklistResult");
15797880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten    }
15807880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten#endif
15818c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    if (pAudioPlayer->mPerformanceMode == ANDROID_PERFORMANCE_MODE_LATENCY) {
15828c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        if ((allowedModes & ANDROID_PERFORMANCE_MODE_LATENCY) == 0) {
15838c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            pAudioPlayer->mPerformanceMode = ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS;
15848c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        }
15858c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    }
15868c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    if (pAudioPlayer->mPerformanceMode == ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS) {
15878c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        if ((allowedModes & ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS) == 0) {
15888c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            pAudioPlayer->mPerformanceMode = ANDROID_PERFORMANCE_MODE_NONE;
15898c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        }
15908c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    }
15917880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten}
15927880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten
15938c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent// Called from android_audioPlayer_realize for a PCM buffer queue player after creating the
15948c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent// AudioTrack to adjust performance mode based on actual output flags
15958c9071f491393fadf767b6164a17b0795eba3fdaEric Laurentstatic void checkAndSetPerformanceModePost(CAudioPlayer *pAudioPlayer)
15968c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent{
15978c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    audio_output_flags_t flags = pAudioPlayer->mAudioTrack->getFlags();
15988c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    switch (pAudioPlayer->mPerformanceMode) {
15998c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    case ANDROID_PERFORMANCE_MODE_LATENCY:
16008c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        if ((flags & (AUDIO_OUTPUT_FLAG_FAST | AUDIO_OUTPUT_FLAG_RAW)) ==
16018c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent                (AUDIO_OUTPUT_FLAG_FAST | AUDIO_OUTPUT_FLAG_RAW)) {
16028c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            break;
16038c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        }
16048c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        pAudioPlayer->mPerformanceMode = ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS;
16058c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        /* FALL THROUGH */
16068c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    case ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS:
16078c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        if ((flags & AUDIO_OUTPUT_FLAG_FAST) == 0) {
16088c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            pAudioPlayer->mPerformanceMode = ANDROID_PERFORMANCE_MODE_NONE;
16098c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        }
16108c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        break;
16118c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    case ANDROID_PERFORMANCE_MODE_POWER_SAVING:
16128c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        if ((flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) == 0) {
16138c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            pAudioPlayer->mPerformanceMode = ANDROID_PERFORMANCE_MODE_NONE;
16148c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        }
16158c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        break;
16168c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    case ANDROID_PERFORMANCE_MODE_NONE:
16178c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    default:
16188c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        break;
16198c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent    }
16208c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent}
162175e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi//-----------------------------------------------------------------------------
16227133228a478e16458b659946f2180ecddd13fda7Glenn Kasten// FIXME abstract out the diff between CMediaPlayer and CAudioPlayer
1623d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel TriviSLresult android_audioPlayer_realize(CAudioPlayer *pAudioPlayer, SLboolean async) {
1624a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
1625a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
1626a7b79e766ec6d95e9236168c27461c2ebaef4659Glenn Kasten    SL_LOGV("Realize pAudioPlayer=%p", pAudioPlayer);
1627b78fe5f783209fbe1fed42634ca9889052ffcd0bJean-Michel Trivi
1628167a2af67dcc0d20e6e3e995a23a0567715e0ee1Glenn Kasten    AudioPlayback_Parameters app;
1629167a2af67dcc0d20e6e3e995a23a0567715e0ee1Glenn Kasten    app.sessionId = pAudioPlayer->mSessionId;
1630167a2af67dcc0d20e6e3e995a23a0567715e0ee1Glenn Kasten    app.streamType = pAudioPlayer->mStreamType;
1631167a2af67dcc0d20e6e3e995a23a0567715e0ee1Glenn Kasten
1632a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    switch (pAudioPlayer->mAndroidObjType) {
1633167a2af67dcc0d20e6e3e995a23a0567715e0ee1Glenn Kasten
1634a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    //-----------------------------------
1635a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    // AudioTrack
16364e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean    case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE: {
16371fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        // initialize platform-specific CAudioPlayer fields
16381fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi
1639a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        SLDataFormat_PCM *df_pcm = (SLDataFormat_PCM *)
1640a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi                pAudioPlayer->mDynamicSource.mDataSource->pFormat;
1641a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
1642a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        uint32_t sampleRate = sles_to_android_sampleRate(df_pcm->samplesPerSec);
1643a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
16444e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean        audio_channel_mask_t channelMask;
16454e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean        channelMask = sles_to_audio_output_channel_mask(df_pcm->channelMask);
164628340d1d9199b789f0db015680b008c98084f0b7ilewis
164728340d1d9199b789f0db015680b008c98084f0b7ilewis        // To maintain backward compatibility with previous releases, ignore
164828340d1d9199b789f0db015680b008c98084f0b7ilewis        // channel masks that are not indexed.
164928340d1d9199b789f0db015680b008c98084f0b7ilewis        if (channelMask == AUDIO_CHANNEL_INVALID
165028340d1d9199b789f0db015680b008c98084f0b7ilewis                || audio_channel_mask_get_representation(channelMask)
165128340d1d9199b789f0db015680b008c98084f0b7ilewis                        == AUDIO_CHANNEL_REPRESENTATION_POSITION) {
16524e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean            channelMask = audio_channel_out_mask_from_count(df_pcm->numChannels);
165328340d1d9199b789f0db015680b008c98084f0b7ilewis            SL_LOGI("Emulating old channel mask behavior "
165428340d1d9199b789f0db015680b008c98084f0b7ilewis                    "(ignoring positional mask %#x, using default mask %#x based on "
165528340d1d9199b789f0db015680b008c98084f0b7ilewis                    "channel count of %d)", df_pcm->channelMask, channelMask,
165628340d1d9199b789f0db015680b008c98084f0b7ilewis                    df_pcm->numChannels);
16574e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean        }
16584e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean        SL_LOGV("AudioPlayer: mapped SLES channel mask %#x to android channel mask %#x",
16594e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean            df_pcm->channelMask,
16604e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean            channelMask);
16614e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean
16628c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        checkAndSetPerformanceModePre(pAudioPlayer);
16638c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent
16648daa09a2af477dbe495839ccf806919a02aa53cdEric Laurent        audio_output_flags_t policy;
16658c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        switch (pAudioPlayer->mPerformanceMode) {
16668c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        case ANDROID_PERFORMANCE_MODE_POWER_SAVING:
16678c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            policy = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
16688c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            break;
16698c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        case ANDROID_PERFORMANCE_MODE_NONE:
16708c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            policy = AUDIO_OUTPUT_FLAG_NONE;
16718c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            break;
16728c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        case ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS:
16738c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            policy = AUDIO_OUTPUT_FLAG_FAST;
16748c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            break;
16758c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        case ANDROID_PERFORMANCE_MODE_LATENCY:
16768c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        default:
1677b4e379dd5a7dc764260ace7b73a782077ff10232Glenn Kasten            policy = (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_FAST | AUDIO_OUTPUT_FLAG_RAW);
16788c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent            break;
16798c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        }
16808c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent
16818c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        int32_t notificationFrames;
16828c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        if ((policy & AUDIO_OUTPUT_FLAG_FAST) != 0) {
16832ab5ad96f9ddbf44378546d132dd98a9265a349fGlenn Kasten            // negative notificationFrames is the number of notifications (sub-buffers) per track buffer
16842ab5ad96f9ddbf44378546d132dd98a9265a349fGlenn Kasten            // for details see the explanation at frameworks/av/include/media/AudioTrack.h
16852ab5ad96f9ddbf44378546d132dd98a9265a349fGlenn Kasten            notificationFrames = -pAudioPlayer->mBufferQueue.mNumBuffers;
16867880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        } else {
16872ab5ad96f9ddbf44378546d132dd98a9265a349fGlenn Kasten            notificationFrames = 0;
16887880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten        }
16897880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten
1690ae1a5c8dc1fccf7c121eda830f8d23bd094c0f16Glenn Kasten        pAudioPlayer->mAudioTrack = new android::AudioTrack(
169175e22870e41386cdc597bd29c76744d74d4c22adJean-Michel Trivi                pAudioPlayer->mStreamType,                           // streamType
1692a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi                sampleRate,                                          // sampleRate
1693e57c13397185f9ad0f162855e9a8ebeb0c94bfc4Andy Hung                sles_to_android_sampleFormat(df_pcm),                // format
16944e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean                channelMask,                                         // channel mask
169578e61e01307d62bd04283ada99ce5df1c647810dGlenn Kasten                0,                                                   // frameCount
16967880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten                policy,                                              // flags
1697a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi                audioTrack_callBack_pullFromBuffQueue,               // callback
1698a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi                (void *) pAudioPlayer,                               // user
1699f930011635e970346ca31d0509a173a695023f27Glenn Kasten                notificationFrames,                                  // see comment above
17007880f29c5ae58e0dd5ac67753049acc8888cb5f5Glenn Kasten                pAudioPlayer->mSessionId);
1701337aff43154e6f8e2f94e569d33a5b135de70f2bGlenn Kasten        android::status_t status = pAudioPlayer->mAudioTrack->initCheck();
1702337aff43154e6f8e2f94e569d33a5b135de70f2bGlenn Kasten        if (status != android::NO_ERROR) {
1703337aff43154e6f8e2f94e569d33a5b135de70f2bGlenn Kasten            SL_LOGE("AudioTrack::initCheck status %u", status);
17042dc0674aba6242c677365b675795773738397ab9Glenn Kasten            // FIXME should return a more specific result depending on status
17056a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            result = SL_RESULT_CONTENT_UNSUPPORTED;
170647550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten            pAudioPlayer->mAudioTrack.clear();
170747550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten            return result;
1708a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi        }
17091fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi
1710143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        if (pAudioPlayer->mObject.mEngine->mAudioManager == 0) {
1711143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi            SL_LOGE("AudioPlayer realize: no audio service, player will not be registered");
1712143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi            pAudioPlayer->mPIId = 0;
1713143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        } else {
1714143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi            pAudioPlayer->mPIId = pAudioPlayer->mObject.mEngine->mAudioManager->trackPlayer(
1715143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi                    android::PLAYER_TYPE_SLES_AUDIOPLAYER_BUFFERQUEUE,
1716143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi                    usageForStreamType(pAudioPlayer->mStreamType), 0/*CONTENT_TYPE_UNKNOWN*/);
1717143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        }
1718143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi
17198c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        // update performance mode according to actual flags granted to AudioTrack
17208c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent        checkAndSetPerformanceModePost(pAudioPlayer);
17218c9071f491393fadf767b6164a17b0795eba3fdaEric Laurent
17221fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        // initialize platform-independent CAudioPlayer fields
17231fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi
17241fec6cc920db52e63c67eafd2034e52b8eb5780dJean-Michel Trivi        pAudioPlayer->mNumChannels = df_pcm->numChannels;
1725a50f5208eb9022a9d1a51288e25553cfe6828b3aJean-Michel Trivi        pAudioPlayer->mSampleRateMilliHz = df_pcm->samplesPerSec; // Note: bad field name in SL ES
17263ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi
1727f66b430471d691de4bf7b6bbc1a6527897f61cbdGlenn Kasten        // This use case does not have a separate "prepare" step
17283ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi        pAudioPlayer->mAndroidObjState = ANDROID_READY;
172915f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean
173015f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean        // If there is a JavaAudioRoutingProxy associated with this player, hook it up...
173115f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean        JNIEnv* j_env = NULL;
173215f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean        jclass clsAudioTrack = NULL;
173315f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean        jmethodID midRoutingProxy_connect = NULL;
173415f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean        if (pAudioPlayer->mAndroidConfiguration.mRoutingProxy != NULL &&
173515f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean                (j_env = android::AndroidRuntime::getJNIEnv()) != NULL &&
173615f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean                (clsAudioTrack = j_env->FindClass("android/media/AudioTrack")) != NULL &&
173715f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean                (midRoutingProxy_connect =
173815f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean                    j_env->GetMethodID(clsAudioTrack, "deferred_connect", "(J)V")) != NULL) {
173915f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean            j_env->ExceptionClear();
174015f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean            j_env->CallVoidMethod(pAudioPlayer->mAndroidConfiguration.mRoutingProxy,
174115f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean                                  midRoutingProxy_connect,
174215f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean                                  pAudioPlayer->mAudioTrack.get());
174315f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean            if (j_env->ExceptionCheck()) {
1744143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi                SL_LOGE("Java exception releasing player routing object.");
174515f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean                result = SL_RESULT_INTERNAL_ERROR;
1746677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent                pAudioPlayer->mAudioTrack.clear();
1747143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi                audioManagerReleasePlayer(pAudioPlayer);
1748677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent                return result;
174915f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean            }
175013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        }
175115f1e492e8fe7e2b6665009b5facd2b42913ab0fPaul McLean    }
175213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        break;
1753167a2af67dcc0d20e6e3e995a23a0567715e0ee1Glenn Kasten
1754a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    //-----------------------------------
1755a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    // MediaPlayer
17564ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    case AUDIOPLAYER_FROM_URIFD: {
17574ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        pAudioPlayer->mAPlayer = new android::LocAVPlayer(&app, false /*hasVideo*/);
17584ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        pAudioPlayer->mAPlayer->init(sfplayer_handlePrefetchEvent,
1759ca98a6831e18865542985b7cc97da25708b54b9cJean-Michel Trivi                        (void*)pAudioPlayer /*notifUSer*/);
17608a1b7f28c1c3de212a302182022310ab7b227788Jean-Michel Trivi
1761989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        switch (pAudioPlayer->mDataSource.mLocator.mLocatorType) {
1762833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten            case SL_DATALOCATOR_URI: {
1763833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                // The legacy implementation ran Stagefright within the application process, and
1764833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                // so allowed local pathnames specified by URI that were openable by
1765833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                // the application but were not openable by mediaserver.
1766833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                // The current implementation runs Stagefright (mostly) within mediaserver,
1767833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                // which runs as a different UID and likely a different current working directory.
1768833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                // For backwards compatibility with any applications which may have relied on the
1769833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                // previous behavior, we convert an openable file URI into an FD.
1770833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                // Note that unlike SL_DATALOCATOR_ANDROIDFD, this FD is owned by us
1771833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                // and so we close it as soon as we've passed it (via Binder dup) to mediaserver.
1772833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                const char *uri = (const char *)pAudioPlayer->mDataSource.mLocator.mURI.URI;
1773833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                if (!isDistantProtocol(uri)) {
1774833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                    // don't touch the original uri, we may need it later
1775833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                    const char *pathname = uri;
1776833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                    // skip over an optional leading file:// prefix
1777833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                    if (!strncasecmp(pathname, "file://", 7)) {
1778833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                        pathname += 7;
1779833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                    }
1780833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                    // attempt to open it as a file using the application's credentials
1781833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                    int fd = ::open(pathname, O_RDONLY);
1782833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                    if (fd >= 0) {
1783833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                        // if open is successful, then check to see if it's a regular file
1784833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                        struct stat statbuf;
1785833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                        if (!::fstat(fd, &statbuf) && S_ISREG(statbuf.st_mode)) {
1786833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                            // treat similarly to an FD data locator, but
1787833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                            // let setDataSource take responsibility for closing fd
1788833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                            pAudioPlayer->mAPlayer->setDataSource(fd, 0, statbuf.st_size, true);
1789833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                            break;
1790833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                        }
1791833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                        // we were able to open it, but it's not a file, so let mediaserver try
1792833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                        (void) ::close(fd);
1793833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                    }
1794833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                }
1795833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                // if either the URI didn't look like a file, or open failed, or not a file
1796833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                pAudioPlayer->mAPlayer->setDataSource(uri);
1797833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten                } break;
1798989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi            case SL_DATALOCATOR_ANDROIDFD: {
1799989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi                int64_t offset = (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.offset;
18004ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                pAudioPlayer->mAPlayer->setDataSource(
1801989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi                        (int)pAudioPlayer->mDataSource.mLocator.mFD.fd,
1802989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi                        offset == SL_DATALOCATOR_ANDROIDFD_USE_FILE_SIZE ?
180397876858aa17c7f24c6a1d60be09a57bc1824ba3Jean-Michel Trivi                                (int64_t)PLAYER_FD_FIND_FILE_SIZE : offset,
1804989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi                        (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.length);
180513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                }
180613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                break;
1807989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi            default:
18083ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi                SL_LOGE(ERROR_PLAYERREALIZE_UNKNOWN_DATASOURCE_LOCATOR);
1809989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi                break;
1810989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi        }
1811f8acf4b469cdc9d2fe08fb7f6ca007365efc8bc1Jean-Michel Trivi
1812143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        if (pAudioPlayer->mObject.mEngine->mAudioManager == 0) {
1813143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi            SL_LOGE("AudioPlayer realize: no audio service, player will not be registered");
1814143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi            pAudioPlayer->mPIId = 0;
1815143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        } else {
1816143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi            pAudioPlayer->mPIId = pAudioPlayer->mObject.mEngine->mAudioManager->trackPlayer(
1817143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi                    android::PLAYER_TYPE_SLES_AUDIOPLAYER_URI_FD,
1818143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi                    usageForStreamType(pAudioPlayer->mStreamType), 0/*CONTENT_TYPE_UNKNOWN*/);
1819143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        }
182013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        }
182113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        break;
1822167a2af67dcc0d20e6e3e995a23a0567715e0ee1Glenn Kasten
182313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    //-----------------------------------
182413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    // StreamPlayer
18254ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE: {
1826167a2af67dcc0d20e6e3e995a23a0567715e0ee1Glenn Kasten        android::StreamPlayer* splr = new android::StreamPlayer(&app, false /*hasVideo*/,
18277133228a478e16458b659946f2180ecddd13fda7Glenn Kasten                &pAudioPlayer->mAndroidBufferQueue, pAudioPlayer->mCallbackProtector);
18287133228a478e16458b659946f2180ecddd13fda7Glenn Kasten        pAudioPlayer->mAPlayer = splr;
18297133228a478e16458b659946f2180ecddd13fda7Glenn Kasten        splr->init(sfplayer_handlePrefetchEvent, (void*)pAudioPlayer);
183013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        }
183113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        break;
1832167a2af67dcc0d20e6e3e995a23a0567715e0ee1Glenn Kasten
183313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    //-----------------------------------
183413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    // AudioToCbRenderer
18354ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE: {
183613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        android::AudioToCbRenderer* decoder = new android::AudioToCbRenderer(&app);
183713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        pAudioPlayer->mAPlayer = decoder;
1838bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi        // configures the callback for the sink buffer queue
1839f4b45a37248899ae2d27bb172f8387fbf1edff8eGlenn Kasten        decoder->setDataPushListener(adecoder_writeToBufferQueue, pAudioPlayer);
1840bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi        // configures the callback for the notifications coming from the SF code
184113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        decoder->init(sfplayer_handlePrefetchEvent, (void*)pAudioPlayer);
184213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
184313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        switch (pAudioPlayer->mDataSource.mLocator.mLocatorType) {
184413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        case SL_DATALOCATOR_URI:
184513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            decoder->setDataSource(
184613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                    (const char*)pAudioPlayer->mDataSource.mLocator.mURI.URI);
184713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            break;
184813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        case SL_DATALOCATOR_ANDROIDFD: {
184913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            int64_t offset = (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.offset;
185013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            decoder->setDataSource(
185113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                    (int)pAudioPlayer->mDataSource.mLocator.mFD.fd,
185213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                    offset == SL_DATALOCATOR_ANDROIDFD_USE_FILE_SIZE ?
185313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                            (int64_t)PLAYER_FD_FIND_FILE_SIZE : offset,
185413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                            (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.length);
185513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            }
185613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            break;
185713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        default:
185813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            SL_LOGE(ERROR_PLAYERREALIZE_UNKNOWN_DATASOURCE_LOCATOR);
185913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi            break;
186013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        }
186113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
186213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        }
186313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        break;
1864167a2af67dcc0d20e6e3e995a23a0567715e0ee1Glenn Kasten
1865fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    //-----------------------------------
1866bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi    // AacBqToPcmCbRenderer
1867bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi    case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE: {
186870e6a0238597223221a8bf5e506c92acf28aa35fGlenn Kasten        android::AacBqToPcmCbRenderer* bqtobq = new android::AacBqToPcmCbRenderer(&app,
186970e6a0238597223221a8bf5e506c92acf28aa35fGlenn Kasten                &pAudioPlayer->mAndroidBufferQueue);
1870bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi        // configures the callback for the sink buffer queue
1871f4b45a37248899ae2d27bb172f8387fbf1edff8eGlenn Kasten        bqtobq->setDataPushListener(adecoder_writeToBufferQueue, pAudioPlayer);
1872bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi        pAudioPlayer->mAPlayer = bqtobq;
1873bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi        // configures the callback for the notifications coming from the SF code,
1874bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi        // but also implicitly configures the AndroidBufferQueue from which ADTS data is read
1875bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi        pAudioPlayer->mAPlayer->init(sfplayer_handlePrefetchEvent, (void*)pAudioPlayer);
1876bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi        }
1877bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi        break;
1878167a2af67dcc0d20e6e3e995a23a0567715e0ee1Glenn Kasten
1879bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi    //-----------------------------------
1880a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    default:
188113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        SL_LOGE(ERROR_PLAYERREALIZE_UNEXPECTED_OBJECT_TYPE_D, pAudioPlayer->mAndroidObjType);
1882337aff43154e6f8e2f94e569d33a5b135de70f2bGlenn Kasten        result = SL_RESULT_INTERNAL_ERROR;
1883337aff43154e6f8e2f94e569d33a5b135de70f2bGlenn Kasten        break;
1884a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    }
1885a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
1886677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent    if (result == SL_RESULT_SUCCESS) {
1887677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent        // proceed with effect initialization
1888677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent        // initialize EQ
1889677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent        // FIXME use a table of effect descriptors when adding support for more effects
1890677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent
1891677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent        // No session effects allowed even in latency with effects performance mode because HW
1892677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent        // accelerated effects are only tolerated as post processing in this mode
1893677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent        if ((pAudioPlayer->mAndroidObjType != AUDIOPLAYER_FROM_PCM_BUFFERQUEUE) ||
1894677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent                ((pAudioPlayer->mPerformanceMode != ANDROID_PERFORMANCE_MODE_LATENCY) &&
1895677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent                 (pAudioPlayer->mPerformanceMode != ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS))) {
1896677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent            if (memcmp(SL_IID_EQUALIZER, &pAudioPlayer->mEqualizer.mEqDescriptor.type,
1897677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent                    sizeof(effect_uuid_t)) == 0) {
1898677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent                SL_LOGV("Need to initialize EQ for AudioPlayer=%p", pAudioPlayer);
1899677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent                android_eq_init(pAudioPlayer->mSessionId, &pAudioPlayer->mEqualizer);
1900677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent            }
1901677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent            // initialize BassBoost
1902677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent            if (memcmp(SL_IID_BASSBOOST, &pAudioPlayer->mBassBoost.mBassBoostDescriptor.type,
1903677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent                    sizeof(effect_uuid_t)) == 0) {
1904677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent                SL_LOGV("Need to initialize BassBoost for AudioPlayer=%p", pAudioPlayer);
1905677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent                android_bb_init(pAudioPlayer->mSessionId, &pAudioPlayer->mBassBoost);
1906677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent            }
1907677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent            // initialize Virtualizer
1908677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent            if (memcmp(SL_IID_VIRTUALIZER, &pAudioPlayer->mVirtualizer.mVirtualizerDescriptor.type,
1909677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent                       sizeof(effect_uuid_t)) == 0) {
1910677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent                SL_LOGV("Need to initialize Virtualizer for AudioPlayer=%p", pAudioPlayer);
1911677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent                android_virt_init(pAudioPlayer->mSessionId, &pAudioPlayer->mVirtualizer);
1912677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent            }
1913677c796097b542e9ee6cf43a59e754f43c2370dcEric Laurent        }
1914f4aebfe499998c11b31319afb1c7738d4801f7b1Jean-Michel Trivi    }
19157e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi
19167e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi    // initialize EffectSend
19177e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi    // FIXME initialize EffectSend
19184be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi
1919a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi    return result;
1920a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi}
1921a852e9eca77c64fcba11eb590bec7a11aca5fe16Jean-Michel Trivi
192248913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi
192348913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi//-----------------------------------------------------------------------------
192483ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi/**
19254260ff7b8f65fdfe8d0176cdce66faf0a10c4b10Glenn Kasten * Called with a lock on AudioPlayer, and blocks until safe to destroy
192683ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi */
192783ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel TriviSLresult android_audioPlayer_preDestroy(CAudioPlayer *pAudioPlayer) {
1928e6ded5c61944a87fa9e472dec3a6929855d42aebJean-Michel Trivi    SL_LOGD("android_audioPlayer_preDestroy(%p)", pAudioPlayer);
192983ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
193083ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi
193122ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten    bool disableCallbacksBeforePreDestroy;
193222ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten    switch (pAudioPlayer->mAndroidObjType) {
193322ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten    // Not yet clear why this order is important, but it reduces detected deadlocks
193422ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten    case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
193522ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten        disableCallbacksBeforePreDestroy = true;
193622ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten        break;
193722ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten    // Use the old behavior for all other use cases until proven
193822ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten    // case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
193922ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten    default:
194022ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten        disableCallbacksBeforePreDestroy = false;
194122ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten        break;
194222ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten    }
1943f4b45a37248899ae2d27bb172f8387fbf1edff8eGlenn Kasten
194422ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten    if (disableCallbacksBeforePreDestroy) {
194522ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten        object_unlock_exclusive(&pAudioPlayer->mObject);
194622ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten        if (pAudioPlayer->mCallbackProtector != 0) {
194722ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten            pAudioPlayer->mCallbackProtector->requestCbExitAndWait();
194822ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten        }
194922ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten        object_lock_exclusive(&pAudioPlayer->mObject);
1950f4b45a37248899ae2d27bb172f8387fbf1edff8eGlenn Kasten    }
1951f4b45a37248899ae2d27bb172f8387fbf1edff8eGlenn Kasten
1952e6ded5c61944a87fa9e472dec3a6929855d42aebJean-Michel Trivi    if (pAudioPlayer->mAPlayer != 0) {
1953e6ded5c61944a87fa9e472dec3a6929855d42aebJean-Michel Trivi        pAudioPlayer->mAPlayer->preDestroy();
1954e6ded5c61944a87fa9e472dec3a6929855d42aebJean-Michel Trivi    }
1955e6ded5c61944a87fa9e472dec3a6929855d42aebJean-Michel Trivi    SL_LOGD("android_audioPlayer_preDestroy(%p) after mAPlayer->preDestroy()", pAudioPlayer);
1956e6ded5c61944a87fa9e472dec3a6929855d42aebJean-Michel Trivi
195722ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten    if (!disableCallbacksBeforePreDestroy) {
195822ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten        object_unlock_exclusive(&pAudioPlayer->mObject);
195922ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten        if (pAudioPlayer->mCallbackProtector != 0) {
196022ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten            pAudioPlayer->mCallbackProtector->requestCbExitAndWait();
196122ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten        }
196222ced1dc023dc000118e3a26517b14e9babd7c5aGlenn Kasten        object_lock_exclusive(&pAudioPlayer->mObject);
196383ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi    }
196483ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi
196583ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi    return result;
196683ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi}
196783ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi
196883ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi
196983ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi//-----------------------------------------------------------------------------
1970d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel TriviSLresult android_audioPlayer_destroy(CAudioPlayer *pAudioPlayer) {
19716a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
19729ab6dd04be11483a9e8b58de91228b17b821eca4Jean-Michel Trivi    SL_LOGV("android_audioPlayer_destroy(%p)", pAudioPlayer);
19736a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    switch (pAudioPlayer->mAndroidObjType) {
19744ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
19754ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
197696ad4989121d0119d47e4ff14f5c3341eafd64bdGlenn Kasten        // We own the audio track for PCM buffer queue players
197747550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten        if (pAudioPlayer->mAudioTrack != 0) {
197896ad4989121d0119d47e4ff14f5c3341eafd64bdGlenn Kasten            pAudioPlayer->mAudioTrack->stop();
197947550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten            // Note that there may still be another reference in post-unlock phase of SetPlayState
198047550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten            pAudioPlayer->mAudioTrack.clear();
198196ad4989121d0119d47e4ff14f5c3341eafd64bdGlenn Kasten        }
1982143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        audioManagerReleasePlayer(pAudioPlayer);
19836a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
19844ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
1985143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi    case AUDIOPLAYER_FROM_URIFD:
1986143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        audioManagerReleasePlayer(pAudioPlayer);
1987143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        // intended fall-through
19884ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE:    // intended fall-through
1989bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi    case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE: // intended fall-through
1990bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi    case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
199113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        pAudioPlayer->mAPlayer.clear();
199213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        break;
199313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    //-----------------------------------
19946a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    default:
199513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        SL_LOGE(ERROR_PLAYERDESTROY_UNEXPECTED_OBJECT_TYPE_D, pAudioPlayer->mAndroidObjType);
1996337aff43154e6f8e2f94e569d33a5b135de70f2bGlenn Kasten        result = SL_RESULT_INTERNAL_ERROR;
1997337aff43154e6f8e2f94e569d33a5b135de70f2bGlenn Kasten        break;
19986a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
19996a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
200072042d4448cee63528c619537321ba73944c6382Glenn Kasten    // placeholder: not necessary yet as session ID lifetime doesn't extend beyond player
200172042d4448cee63528c619537321ba73944c6382Glenn Kasten    // android::AudioSystem::releaseAudioSessionId(pAudioPlayer->mSessionId);
200283ac345e264c1e22b7a2f1a110b2fe92473394ecJean-Michel Trivi
200372042d4448cee63528c619537321ba73944c6382Glenn Kasten    pAudioPlayer->mCallbackProtector.clear();
2004989ab369777ef514ac3ba6cdb893de9ae0c976bcJean-Michel Trivi
2005a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten    // explicit destructor
200647550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten    pAudioPlayer->mAudioTrack.~sp();
200747550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten    // note that SetPlayState(PLAYING) may still hold a reference
20086cce136651f6fd2c7aecd45bc553270152d75462Jean-Michel Trivi    pAudioPlayer->mCallbackProtector.~sp();
2009f7b852d914faa49d3e4b7d02bb5d9d254762c0b7Jean-Michel Trivi    pAudioPlayer->mAuxEffect.~sp();
201013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    pAudioPlayer->mAPlayer.~sp();
20114be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi
20126a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    return result;
20136a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi}
20146a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
20156a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
20166a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi//-----------------------------------------------------------------------------
20176d78c9bfb68f8a0db1855bc28c087c39a7eb6f2cGlenn KastenSLresult android_audioPlayer_setPlaybackRateAndConstraints(CAudioPlayer *ap, SLpermille rate,
20186d78c9bfb68f8a0db1855bc28c087c39a7eb6f2cGlenn Kasten        SLuint32 constraints) {
2019497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
2020ac28eca1df49f581d952ffbda5d3019f7e3b7be6Glenn Kasten    switch (ap->mAndroidObjType) {
20216d78c9bfb68f8a0db1855bc28c087c39a7eb6f2cGlenn Kasten    case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE: {
20226d78c9bfb68f8a0db1855bc28c087c39a7eb6f2cGlenn Kasten        // these asserts were already checked by the platform-independent layer
20236d78c9bfb68f8a0db1855bc28c087c39a7eb6f2cGlenn Kasten        assert((AUDIOTRACK_MIN_PLAYBACKRATE_PERMILLE <= rate) &&
20246d78c9bfb68f8a0db1855bc28c087c39a7eb6f2cGlenn Kasten                (rate <= AUDIOTRACK_MAX_PLAYBACKRATE_PERMILLE));
20256d78c9bfb68f8a0db1855bc28c087c39a7eb6f2cGlenn Kasten        assert(constraints & SL_RATEPROP_NOPITCHCORAUDIO);
2026497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        // get the content sample rate
202724430c9070298f12e68b84c921add38da6ad0490Jean-Michel Trivi        uint32_t contentRate = sles_to_android_sampleRate(ap->mSampleRateMilliHz);
2028497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        // apply the SL ES playback rate on the AudioTrack as a factor of its content sample rate
202947550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten        if (ap->mAudioTrack != 0) {
20304614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi            ap->mAudioTrack->setSampleRate(contentRate * (rate/1000.0f));
2031497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        }
2032497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        }
2033497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        break;
203491145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi    case AUDIOPLAYER_FROM_URIFD: {
203591145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi        assert((MEDIAPLAYER_MIN_PLAYBACKRATE_PERMILLE <= rate) &&
203691145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi                        (rate <= MEDIAPLAYER_MAX_PLAYBACKRATE_PERMILLE));
20376d78c9bfb68f8a0db1855bc28c087c39a7eb6f2cGlenn Kasten        assert(constraints & SL_RATEPROP_NOPITCHCORAUDIO);
203891145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi        // apply the SL ES playback rate on the GenericPlayer
203991145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi        if (ap->mAPlayer != 0) {
204091145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi            ap->mAPlayer->setPlaybackRate((int16_t)rate);
204191145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi        }
204291145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi        }
2043497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        break;
20446d78c9bfb68f8a0db1855bc28c087c39a7eb6f2cGlenn Kasten
2045497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    default:
2046337aff43154e6f8e2f94e569d33a5b135de70f2bGlenn Kasten        SL_LOGE("Unexpected object type %d", ap->mAndroidObjType);
20476d78c9bfb68f8a0db1855bc28c087c39a7eb6f2cGlenn Kasten        result = SL_RESULT_FEATURE_UNSUPPORTED;
2048497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi        break;
2049497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    }
2050497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi    return result;
2051497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi}
2052497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi
2053497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi
2054497c71251661f9096f77d0a9bc08fe7a5eb49079Jean-Michel Trivi//-----------------------------------------------------------------------------
20557f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi// precondition
20567f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//  called with no lock held
20577f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//  ap != NULL
20587f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//  pItemCount != NULL
20597f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel TriviSLresult android_audioPlayer_metadata_getItemCount(CAudioPlayer *ap, SLuint32 *pItemCount) {
20607f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    if (ap->mAPlayer == 0) {
20617f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        return SL_RESULT_PARAMETER_INVALID;
20627f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    }
2063ac28eca1df49f581d952ffbda5d3019f7e3b7be6Glenn Kasten    switch (ap->mAndroidObjType) {
20647f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
206591540f92d7f1bcda423859af6bd82df083c2afabGlenn Kasten      case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
20667f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        {
20677f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            android::AudioSfDecoder* decoder =
20687f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                    static_cast<android::AudioSfDecoder*>(ap->mAPlayer.get());
20697f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            *pItemCount = decoder->getPcmFormatKeyCount();
20707f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        }
20717f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        break;
20727f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi      default:
20737f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        *pItemCount = 0;
20747f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        break;
20757f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    }
20767f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    return SL_RESULT_SUCCESS;
20777f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi}
20787f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi
20797f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi
20807f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//-----------------------------------------------------------------------------
20817f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi// precondition
20827f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//  called with no lock held
20837f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//  ap != NULL
20847f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//  pKeySize != NULL
20857f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel TriviSLresult android_audioPlayer_metadata_getKeySize(CAudioPlayer *ap,
20867f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        SLuint32 index, SLuint32 *pKeySize) {
20877f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    if (ap->mAPlayer == 0) {
20887f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        return SL_RESULT_PARAMETER_INVALID;
20897f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    }
20907f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    SLresult res = SL_RESULT_SUCCESS;
2091ac28eca1df49f581d952ffbda5d3019f7e3b7be6Glenn Kasten    switch (ap->mAndroidObjType) {
20927f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
209391540f92d7f1bcda423859af6bd82df083c2afabGlenn Kasten      case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
20947f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        {
20957f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            android::AudioSfDecoder* decoder =
20967f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                    static_cast<android::AudioSfDecoder*>(ap->mAPlayer.get());
20977f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            SLuint32 keyNameSize = 0;
20987f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            if (!decoder->getPcmFormatKeySize(index, &keyNameSize)) {
20997f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                res = SL_RESULT_PARAMETER_INVALID;
21007f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            } else {
21017f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                // *pKeySize is the size of the region used to store the key name AND
21027f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                //   the information about the key (size, lang, encoding)
21037f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                *pKeySize = keyNameSize + sizeof(SLMetadataInfo);
21047f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            }
21057f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        }
21067f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        break;
21077f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi      default:
21087f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        *pKeySize = 0;
21097f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        res = SL_RESULT_PARAMETER_INVALID;
21107f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        break;
21117f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    }
21127f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    return res;
21137f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi}
21147f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi
21157f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi
21167f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//-----------------------------------------------------------------------------
21177f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi// precondition
21187f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//  called with no lock held
21197f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//  ap != NULL
21207f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//  pKey != NULL
21217f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel TriviSLresult android_audioPlayer_metadata_getKey(CAudioPlayer *ap,
21227f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        SLuint32 index, SLuint32 size, SLMetadataInfo *pKey) {
21237f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    if (ap->mAPlayer == 0) {
21247f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        return SL_RESULT_PARAMETER_INVALID;
21257f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    }
21267f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    SLresult res = SL_RESULT_SUCCESS;
2127ac28eca1df49f581d952ffbda5d3019f7e3b7be6Glenn Kasten    switch (ap->mAndroidObjType) {
21287f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
212991540f92d7f1bcda423859af6bd82df083c2afabGlenn Kasten      case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
21307f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        {
21317f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            android::AudioSfDecoder* decoder =
21327f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                    static_cast<android::AudioSfDecoder*>(ap->mAPlayer.get());
21337f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            if ((size < sizeof(SLMetadataInfo) ||
21347f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                    (!decoder->getPcmFormatKeyName(index, size - sizeof(SLMetadataInfo),
21357f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                            (char*)pKey->data)))) {
21367f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                res = SL_RESULT_PARAMETER_INVALID;
21377f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            } else {
21387f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                // successfully retrieved the key value, update the other fields
21397f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                pKey->encoding = SL_CHARACTERENCODING_UTF8;
21407f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                memcpy((char *) pKey->langCountry, "en", 3);
21417f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                pKey->size = strlen((char*)pKey->data) + 1;
21427f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            }
21437f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        }
21447f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        break;
21457f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi      default:
21467f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        res = SL_RESULT_PARAMETER_INVALID;
21477f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        break;
21487f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    }
21497f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    return res;
21507f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi}
21517f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi
21527f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi
21537f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//-----------------------------------------------------------------------------
21547f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi// precondition
21557f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//  called with no lock held
21567f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//  ap != NULL
21577f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//  pValueSize != NULL
21587f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel TriviSLresult android_audioPlayer_metadata_getValueSize(CAudioPlayer *ap,
21597f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        SLuint32 index, SLuint32 *pValueSize) {
21607f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    if (ap->mAPlayer == 0) {
21617f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        return SL_RESULT_PARAMETER_INVALID;
21627f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    }
21637f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    SLresult res = SL_RESULT_SUCCESS;
2164ac28eca1df49f581d952ffbda5d3019f7e3b7be6Glenn Kasten    switch (ap->mAndroidObjType) {
21657f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
216691540f92d7f1bcda423859af6bd82df083c2afabGlenn Kasten      case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
21677f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        {
21687f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            android::AudioSfDecoder* decoder =
21697f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                    static_cast<android::AudioSfDecoder*>(ap->mAPlayer.get());
21707f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            SLuint32 valueSize = 0;
21717f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            if (!decoder->getPcmFormatValueSize(index, &valueSize)) {
21727f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                res = SL_RESULT_PARAMETER_INVALID;
21737f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            } else {
21747f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                // *pValueSize is the size of the region used to store the key value AND
21757f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                //   the information about the value (size, lang, encoding)
21767f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                *pValueSize = valueSize + sizeof(SLMetadataInfo);
21777f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            }
21787f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        }
21797f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        break;
21807f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi      default:
21817f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi          *pValueSize = 0;
21827f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi          res = SL_RESULT_PARAMETER_INVALID;
21837f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi          break;
21847f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    }
21857f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    return res;
21867f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi}
21877f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi
21887f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi
21897f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//-----------------------------------------------------------------------------
21907f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi// precondition
21917f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//  called with no lock held
21927f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//  ap != NULL
21937f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//  pValue != NULL
21947f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel TriviSLresult android_audioPlayer_metadata_getValue(CAudioPlayer *ap,
21957f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        SLuint32 index, SLuint32 size, SLMetadataInfo *pValue) {
21967f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    if (ap->mAPlayer == 0) {
21977f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        return SL_RESULT_PARAMETER_INVALID;
21987f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    }
21997f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    SLresult res = SL_RESULT_SUCCESS;
2200ac28eca1df49f581d952ffbda5d3019f7e3b7be6Glenn Kasten    switch (ap->mAndroidObjType) {
22017f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
220291540f92d7f1bcda423859af6bd82df083c2afabGlenn Kasten      case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
22037f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        {
22047f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            android::AudioSfDecoder* decoder =
22057f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                    static_cast<android::AudioSfDecoder*>(ap->mAPlayer.get());
22067f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            pValue->encoding = SL_CHARACTERENCODING_BINARY;
22077f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            memcpy((char *) pValue->langCountry, "en", 3); // applicable here?
22087f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            SLuint32 valueSize = 0;
22097f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            if ((size < sizeof(SLMetadataInfo)
22107f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                    || (!decoder->getPcmFormatValueSize(index, &valueSize))
22117f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                    || (!decoder->getPcmFormatKeyValue(index, size - sizeof(SLMetadataInfo),
22127f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                            (SLuint32*)pValue->data)))) {
22137f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                res = SL_RESULT_PARAMETER_INVALID;
22147f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            } else {
22157f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                pValue->size = valueSize;
22167f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi            }
22177f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        }
22187f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        break;
22197f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi      default:
22207f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        res = SL_RESULT_PARAMETER_INVALID;
22217f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi        break;
22227f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    }
22237f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    return res;
22247f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi}
22257f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi
22267f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi//-----------------------------------------------------------------------------
2227f4647bf85968ab30eb07f9a80b99177d91068f94Glenn Kasten// preconditions
2228f4647bf85968ab30eb07f9a80b99177d91068f94Glenn Kasten//  ap != NULL
2229f4647bf85968ab30eb07f9a80b99177d91068f94Glenn Kasten//  mutex is locked
2230f4647bf85968ab30eb07f9a80b99177d91068f94Glenn Kasten//  play state has changed
2231f4647bf85968ab30eb07f9a80b99177d91068f94Glenn Kastenvoid android_audioPlayer_setPlayState(CAudioPlayer *ap) {
22328a1b7f28c1c3de212a302182022310ab7b227788Jean-Michel Trivi
22338a1b7f28c1c3de212a302182022310ab7b227788Jean-Michel Trivi    SLuint32 playState = ap->mPlay.mState;
22348a1b7f28c1c3de212a302182022310ab7b227788Jean-Michel Trivi
2235ac28eca1df49f581d952ffbda5d3019f7e3b7be6Glenn Kasten    switch (ap->mAndroidObjType) {
22364ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
22378a1b7f28c1c3de212a302182022310ab7b227788Jean-Michel Trivi        switch (playState) {
223848913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        case SL_PLAYSTATE_STOPPED:
22393ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi            SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_STOPPED");
224047550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten            if (ap->mAudioTrack != 0) {
22413ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi                ap->mAudioTrack->stop();
22423ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi            }
2243143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi            audioManagerPlayerEvent(ap, android::PLAYER_STATE_STOPPED);
224448913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi            break;
224548913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        case SL_PLAYSTATE_PAUSED:
22463ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi            SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_PAUSED");
224747550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten            if (ap->mAudioTrack != 0) {
22483ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi                ap->mAudioTrack->pause();
22493ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi            }
2250143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi            if (ap->mObject.mEngine->mAudioManager != 0) {
2251143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi                ap->mObject.mEngine->mAudioManager->playerEvent(ap->mPIId,
2252143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi                        android::PLAYER_STATE_PAUSED);
2253143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi            }
225448913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi            break;
225548913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        case SL_PLAYSTATE_PLAYING:
22563ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi            SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_PLAYING");
2257143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi            audioManagerPlayerEvent(ap, android::PLAYER_STATE_STARTED);
225847550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten            if (ap->mAudioTrack != 0) {
225947550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten                // instead of ap->mAudioTrack->start();
2260143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi                if (!ap->mDeferredStart) {
2261143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi                    // state change
2262143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi                    audioManagerPlayerEvent(ap, android::PLAYER_STATE_STARTED);
2263143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi                }
226447550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten                ap->mDeferredStart = true;
22653ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi            }
226648913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi            break;
226748913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        default:
2268e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten            // checked by caller, should not happen
2269e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten            break;
227048913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        }
227148913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        break;
227226043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi
2273143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi    case AUDIOPLAYER_FROM_URIFD:
2274143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        switch (playState) {
2275143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        case SL_PLAYSTATE_STOPPED:
2276143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi            aplayer_setPlayState(ap->mAPlayer, playState, &ap->mAndroidObjState);
2277143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi            audioManagerPlayerEvent(ap, android::PLAYER_STATE_STOPPED);
2278143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi            break;
2279143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        case SL_PLAYSTATE_PAUSED:
2280143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi            aplayer_setPlayState(ap->mAPlayer, playState, &ap->mAndroidObjState);
2281143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi            audioManagerPlayerEvent(ap, android::PLAYER_STATE_PAUSED);
2282143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi            break;
2283143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        case SL_PLAYSTATE_PLAYING:
2284143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi            audioManagerPlayerEvent(ap, android::PLAYER_STATE_STARTED);
2285143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi            aplayer_setPlayState(ap->mAPlayer, playState, &ap->mAndroidObjState);
2286143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi            break;
2287143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        }
2288143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        break;
2289143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi
22904ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE:     // intended fall-through
2291bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi    case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:  // intended fall-through
2292bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi    case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
229313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        // FIXME report and use the return code to the lock mechanism, which is where play state
229413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        //   changes are updated (see object_unlock_exclusive_attributes())
2295b8fe327b1505778e82db76de930dd3f62ec99158Glenn Kasten        aplayer_setPlayState(ap->mAPlayer, playState, &ap->mAndroidObjState);
229613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        break;
229748913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi    default:
229813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        SL_LOGE(ERROR_PLAYERSETPLAYSTATE_UNEXPECTED_OBJECT_TYPE_D, ap->mAndroidObjType);
229948913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi        break;
230048913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi    }
230148913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi}
230248913d4519d5112319c4277d4966435fec2f551cJean-Michel Trivi
23036a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
23046a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi//-----------------------------------------------------------------------------
23055933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten// call when either player event flags, marker position, or position update period changes
2306bcfe680db1e392f3bb29382c2e15e89c3af783edGlenn Kastenvoid android_audioPlayer_usePlayEventMask(CAudioPlayer *ap) {
2307e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    IPlay *pPlayItf = &ap->mPlay;
2308e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    SLuint32 eventFlags = pPlayItf->mEventFlags;
2309ac28eca1df49f581d952ffbda5d3019f7e3b7be6Glenn Kasten    /*switch (ap->mAndroidObjType) {
23104ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:*/
23114614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
23125933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten    if (ap->mAPlayer != 0) {
23135933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten        assert(ap->mAudioTrack == 0);
23145933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten        ap->mAPlayer->setPlayEvents((int32_t) eventFlags, (int32_t) pPlayItf->mMarkerPosition,
23155933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten                (int32_t) pPlayItf->mPositionUpdatePeriod);
23165933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten        return;
23175933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten    }
23185933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten
231947550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten    if (ap->mAudioTrack == 0) {
2320e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten        return;
23214614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
23224614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
23234614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (eventFlags & SL_PLAYEVENT_HEADATMARKER) {
2324a50f5208eb9022a9d1a51288e25553cfe6828b3aJean-Michel Trivi        ap->mAudioTrack->setMarkerPosition((uint32_t)((((int64_t)pPlayItf->mMarkerPosition
2325a50f5208eb9022a9d1a51288e25553cfe6828b3aJean-Michel Trivi                * sles_to_android_sampleRate(ap->mSampleRateMilliHz)))/1000));
23264614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    } else {
23274614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        // clear marker
23284614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        ap->mAudioTrack->setMarkerPosition(0);
23294614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
23304614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
23314614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (eventFlags & SL_PLAYEVENT_HEADATNEWPOS) {
233249e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten         ap->mAudioTrack->setPositionUpdatePeriod(
233349e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten                (uint32_t)((((int64_t)pPlayItf->mPositionUpdatePeriod
233449e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten                * sles_to_android_sampleRate(ap->mSampleRateMilliHz)))/1000));
23354614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    } else {
23364614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        // clear periodic update
23374614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        ap->mAudioTrack->setPositionUpdatePeriod(0);
23384614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
23394614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
23404614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (eventFlags & SL_PLAYEVENT_HEADATEND) {
2341e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        // nothing to do for SL_PLAYEVENT_HEADATEND, callback event will be checked against mask
23426a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
23434614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
23444614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (eventFlags & SL_PLAYEVENT_HEADMOVING) {
23454614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi        // FIXME support SL_PLAYEVENT_HEADMOVING
2346a7b79e766ec6d95e9236168c27461c2ebaef4659Glenn Kasten        SL_LOGD("[ FIXME: IPlay_SetCallbackEventsMask(SL_PLAYEVENT_HEADMOVING) on an "
234749e4076e940559bc204d0f0aa7ab412986445bfaGlenn Kasten            "SL_OBJECTID_AUDIOPLAYER to be implemented ]");
23484614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
23494614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    if (eventFlags & SL_PLAYEVENT_HEADSTALLED) {
2350e8c5f1974de23ca3e0a2a41a8f2bda35b554290fJean-Michel Trivi        // nothing to do for SL_PLAYEVENT_HEADSTALLED, callback event will be checked against mask
23514614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi    }
23524614bf6ff570bc1593e07f796d2d8d28c6424c50Jean-Michel Trivi
23536a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi}
23546a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
23556a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
23566a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi//-----------------------------------------------------------------------------
2357d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel TriviSLresult android_audioPlayer_getDuration(IPlay *pPlayItf, SLmillisecond *pDurMsec) {
2358dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi    CAudioPlayer *ap = (CAudioPlayer *)pPlayItf->mThis;
2359ac28eca1df49f581d952ffbda5d3019f7e3b7be6Glenn Kasten    switch (ap->mAndroidObjType) {
23604ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
23614ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      case AUDIOPLAYER_FROM_URIFD:  // intended fall-through
23624ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE: {
23634ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        int32_t durationMsec = ANDROID_UNKNOWN_TIME;
23644ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        if (ap->mAPlayer != 0) {
23654ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            ap->mAPlayer->getDurationMsec(&durationMsec);
236613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        }
23674ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        *pDurMsec = durationMsec == ANDROID_UNKNOWN_TIME ? SL_TIME_UNKNOWN : durationMsec;
236813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        break;
23694ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      }
23704ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
23714ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE: // intended fall-through
2372f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten      case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
2373f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten      case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
23744ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      default: {
237570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        *pDurMsec = SL_TIME_UNKNOWN;
23764ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      }
2377dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi    }
2378dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi    return SL_RESULT_SUCCESS;
2379dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi}
2380dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi
2381dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi
2382dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi//-----------------------------------------------------------------------------
2383d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel Trivivoid android_audioPlayer_getPosition(IPlay *pPlayItf, SLmillisecond *pPosMsec) {
23846a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    CAudioPlayer *ap = (CAudioPlayer *)pPlayItf->mThis;
2385ac28eca1df49f581d952ffbda5d3019f7e3b7be6Glenn Kasten    switch (ap->mAndroidObjType) {
23864ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
23874ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
23881a9c2615d0933d183fcb1b9e34ec8f0da2a85153Glenn Kasten        if ((ap->mSampleRateMilliHz == UNKNOWN_SAMPLERATE) || (ap->mAudioTrack == 0)) {
2389a50f5208eb9022a9d1a51288e25553cfe6828b3aJean-Michel Trivi            *pPosMsec = 0;
2390a50f5208eb9022a9d1a51288e25553cfe6828b3aJean-Michel Trivi        } else {
23913ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi            uint32_t positionInFrames;
23923ddf7a34cc617e52a9b9a5593a0d1c5ef8d22bd9Jean-Michel Trivi            ap->mAudioTrack->getPosition(&positionInFrames);
2393a50f5208eb9022a9d1a51288e25553cfe6828b3aJean-Michel Trivi            *pPosMsec = ((int64_t)positionInFrames * 1000) /
2394a50f5208eb9022a9d1a51288e25553cfe6828b3aJean-Michel Trivi                    sles_to_android_sampleRate(ap->mSampleRateMilliHz);
2395a50f5208eb9022a9d1a51288e25553cfe6828b3aJean-Michel Trivi        }
23966a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
23974ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
23984ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE:    // intended fall-through
2399f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten      case AUDIOPLAYER_FROM_URIFD:
2400f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
2401f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten      case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE: {
24024ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        int32_t posMsec = ANDROID_UNKNOWN_TIME;
24034ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        if (ap->mAPlayer != 0) {
24044ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            ap->mAPlayer->getPositionMsec(&posMsec);
240543e7743b5297cc5afcb246a7e2b5d825a607f8afJean-Michel Trivi        }
24064ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        *pPosMsec = posMsec == ANDROID_UNKNOWN_TIME ? 0 : posMsec;
24076a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        break;
24084ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      }
24094ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
24104ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      default:
24114ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        *pPosMsec = 0;
24126a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
24136a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi}
24146a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
24156a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi
2416b91e32605ecf39e34ad39936b1ee193bb4e30225Glenn Kasten//-----------------------------------------------------------------------------
2417f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn KastenSLresult android_audioPlayer_seek(CAudioPlayer *ap, SLmillisecond posMsec) {
2418f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten    SLresult result = SL_RESULT_SUCCESS;
241943e7743b5297cc5afcb246a7e2b5d825a607f8afJean-Michel Trivi
2420ac28eca1df49f581d952ffbda5d3019f7e3b7be6Glenn Kasten    switch (ap->mAndroidObjType) {
24214ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
24224ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:      // intended fall-through
24234ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE:
2424f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten      case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
2425f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten        result = SL_RESULT_FEATURE_UNSUPPORTED;
24266f0c1c280141bb49828f89c7fd1bd07238a87cb5Jean-Michel Trivi        break;
24274ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
24284ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      case AUDIOPLAYER_FROM_URIFD:                   // intended fall-through
24294ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
24304ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        if (ap->mAPlayer != 0) {
24314ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            ap->mAPlayer->seek(posMsec);
243243e7743b5297cc5afcb246a7e2b5d825a607f8afJean-Michel Trivi        }
24336f0c1c280141bb49828f89c7fd1bd07238a87cb5Jean-Michel Trivi        break;
24344ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
24354ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      default:
24366f0c1c280141bb49828f89c7fd1bd07238a87cb5Jean-Michel Trivi        break;
24376f0c1c280141bb49828f89c7fd1bd07238a87cb5Jean-Michel Trivi    }
2438f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten    return result;
24393c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi}
24403c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi
24413c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi
24423c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi//-----------------------------------------------------------------------------
2443f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn KastenSLresult android_audioPlayer_loop(CAudioPlayer *ap, SLboolean loopEnable) {
2444f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten    SLresult result = SL_RESULT_SUCCESS;
2445d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi
2446f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten    switch (ap->mAndroidObjType) {
2447f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten    case AUDIOPLAYER_FROM_URIFD:
2448f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten    // case AUDIOPLAY_FROM_URIFD_TO_PCM_BUFFERQUEUE:
2449f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten    //      would actually work, but what's the point?
2450f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten      if (ap->mAPlayer != 0) {
24514ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        ap->mAPlayer->loop((bool)loopEnable);
2452f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten      }
2453f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten      break;
2454f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten    default:
2455f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten      result = SL_RESULT_FEATURE_UNSUPPORTED;
2456f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten      break;
2457d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi    }
2458f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten    return result;
2459d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi}
2460d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi
2461d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi
2462d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi//-----------------------------------------------------------------------------
24634ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel TriviSLresult android_audioPlayer_setBufferingUpdateThresholdPerMille(CAudioPlayer *ap,
24644ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        SLpermille threshold) {
24654ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
24664ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
24674ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    switch (ap->mAndroidObjType) {
24684ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      case AUDIOPLAYER_FROM_URIFD:
24694ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        if (ap->mAPlayer != 0) {
24704ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            ap->mAPlayer->setBufferingUpdateThreshold(threshold / 10);
24714ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        }
24724ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        break;
24734ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
24744ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      default: {}
24754ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    }
24764ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
24774ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    return result;
24784ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi}
24794ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
24804ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
24814ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi//-----------------------------------------------------------------------------
248270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivivoid android_audioPlayer_bufferQueue_onRefilled_l(CAudioPlayer *ap) {
2483a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi    // the AudioTrack associated with the AudioPlayer receiving audio from a PCM buffer
2484a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi    // queue was stopped when the queue become empty, we restart as soon as a new buffer
2485a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi    // has been enqueued since we're in playing state
248647550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten    if (ap->mAudioTrack != 0) {
2487143c8939640425ce28aaac46732fb604fba1f5c8Jean-Michel Trivi        audioManagerPlayerEvent(ap, android::PLAYER_STATE_STARTED);
248847550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten        // instead of ap->mAudioTrack->start();
248947550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten        ap->mDeferredStart = true;
2490b44084fdb096a2662085af0199b69ccb0dce5c30Jean-Michel Trivi    }
2491a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi
2492a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi    // when the queue became empty, an underflow on the prefetch status itf was sent. Now the queue
2493a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi    // has received new data, signal it has sufficient data
2494b8fe327b1505778e82db76de930dd3f62ec99158Glenn Kasten    if (IsInterfaceInitialized(&ap->mObject, MPH_PREFETCHSTATUS)) {
2495a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten        // we wouldn't have been called unless we were previously in the underflow state
2496a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten        assert(SL_PREFETCHSTATUS_UNDERFLOW == ap->mPrefetchStatus.mStatus);
2497a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten        assert(0 == ap->mPrefetchStatus.mLevel);
2498a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten        ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_SUFFICIENTDATA;
2499a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten        ap->mPrefetchStatus.mLevel = 1000;
2500a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten        // callback or no callback?
2501a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten        SLuint32 prefetchEvents = ap->mPrefetchStatus.mCallbackEventsMask &
2502a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten                (SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE);
2503a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten        if (SL_PREFETCHEVENT_NONE != prefetchEvents) {
2504a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten            ap->mPrefetchStatus.mDeferredPrefetchCallback = ap->mPrefetchStatus.mCallback;
2505a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten            ap->mPrefetchStatus.mDeferredPrefetchContext  = ap->mPrefetchStatus.mContext;
2506a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten            ap->mPrefetchStatus.mDeferredPrefetchEvents   = prefetchEvents;
2507a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten        }
2508a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi    }
2509b44084fdb096a2662085af0199b69ccb0dce5c30Jean-Michel Trivi}
2510b44084fdb096a2662085af0199b69ccb0dce5c30Jean-Michel Trivi
2511b44084fdb096a2662085af0199b69ccb0dce5c30Jean-Michel Trivi
2512b44084fdb096a2662085af0199b69ccb0dce5c30Jean-Michel Trivi//-----------------------------------------------------------------------------
25134b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten/*
25144b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten * BufferQueue::Clear
25154b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten */
25160ac71cb5890738ea93c26a9f567be2b523235c64Jean-Michel TriviSLresult android_audioPlayer_bufferQueue_onClear(CAudioPlayer *ap) {
25174b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    SLresult result = SL_RESULT_SUCCESS;
25184b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten
25190ac71cb5890738ea93c26a9f567be2b523235c64Jean-Michel Trivi    switch (ap->mAndroidObjType) {
25204b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    //-----------------------------------
25214b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    // AudioTrack
25224ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
252347550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten        if (ap->mAudioTrack != 0) {
25240ac71cb5890738ea93c26a9f567be2b523235c64Jean-Michel Trivi            ap->mAudioTrack->flush();
25250ac71cb5890738ea93c26a9f567be2b523235c64Jean-Michel Trivi        }
25264b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten        break;
25274b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    default:
25284b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten        result = SL_RESULT_INTERNAL_ERROR;
25294b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten        break;
25304b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    }
25314b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten
25324b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    return result;
25334b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten}
2534b44084fdb096a2662085af0199b69ccb0dce5c30Jean-Michel Trivi
253526043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi
2536fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi//-----------------------------------------------------------------------------
2537be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivivoid android_audioPlayer_androidBufferQueue_clear_l(CAudioPlayer *ap) {
2538f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten    switch (ap->mAndroidObjType) {
2539f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten    case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE:
2540f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten      if (ap->mAPlayer != 0) {
2541e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi        android::StreamPlayer* splr = static_cast<android::StreamPlayer*>(ap->mAPlayer.get());
2542e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi        splr->appClear_l();
2543f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten      } break;
2544f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten    case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
2545f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten      // nothing to do here, fall through
2546f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten    default:
2547f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten      break;
2548be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi    }
2549be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi}
2550be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi
255170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivivoid android_audioPlayer_androidBufferQueue_onRefilled_l(CAudioPlayer *ap) {
2552f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten    switch (ap->mAndroidObjType) {
2553f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten    case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE:
2554f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten      if (ap->mAPlayer != 0) {
255570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        android::StreamPlayer* splr = static_cast<android::StreamPlayer*>(ap->mAPlayer.get());
2556bc0e642e6c1a51b3ae3a02d490d94b03e718e6b5Jean-Michel Trivi        splr->queueRefilled();
2557f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten      } break;
2558f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten    case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
2559f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten      // FIXME this may require waking up the decoder if it is currently starved and isn't polling
2560f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten    default:
2561f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten      break;
2562be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi    }
2563be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi}
2564